调试发布版本客户端崩溃:获取调用堆栈的可能方法有哪些? 我有一个本地C++应用程序,在办公室里工作很好(当然我们也要测试),但是客户体验了很多不同的崩溃。我知道可以使用windbg(它是一款跨平台的应用程序,适用于Win、Linux和Mac,但在所有平台上都会发生崩溃,因此调试其中任何一个都是有用的),但操作客户端机器(例如安装和注册windbg)不是一个选项。我想知道是否还有其他方法来获取调用堆栈。是否有任何工具可以对二进制文件进行检测以提供此类信息

调试发布版本客户端崩溃:获取调用堆栈的可能方法有哪些? 我有一个本地C++应用程序,在办公室里工作很好(当然我们也要测试),但是客户体验了很多不同的崩溃。我知道可以使用windbg(它是一款跨平台的应用程序,适用于Win、Linux和Mac,但在所有平台上都会发生崩溃,因此调试其中任何一个都是有用的),但操作客户端机器(例如安装和注册windbg)不是一个选项。我想知道是否还有其他方法来获取调用堆栈。是否有任何工具可以对二进制文件进行检测以提供此类信息,c++,debugging,crash,C++,Debugging,Crash,另外,我想我可以将.pdb文件与二进制文件一起发送,但我不希望这样。在Windows上,您可以在客户端计算机上进行配置,这样,如果应用程序崩溃,它将创建所谓的“迷你转储文件”,然后调试器可以使用适当的pdb打开该文件 您还可以向应用程序添加未经处理的异常筛选器,并在出现无法恢复的错误时自行生成迷你转储 编辑: 如果您想在(未处理的)异常上生成转储文件,请不要在C++ >代码> catch(…)/Cux>块中执行此操作,因为它被调用 > 发生了,原始调用栈不可用。 为了捕获和转储调用堆栈,您应该在

另外,我想我可以将.pdb文件与二进制文件一起发送,但我不希望这样。

在Windows上,您可以在客户端计算机上进行配置,这样,如果应用程序崩溃,它将创建所谓的“迷你转储文件”,然后调试器可以使用适当的pdb打开该文件

您还可以向应用程序添加未经处理的异常筛选器,并在出现无法恢复的错误时自行生成迷你转储

编辑:

如果您想在(未处理的)异常上生成转储文件,请不要在C++ >代码> catch(…)/Cux>块中执行此操作,因为它被调用<强> > <强>发生了,原始调用栈不可用。 为了捕获和转储调用堆栈,您应该在堆栈展开之前转储它。像这样:

int HandleMyException(EXCEPTION_POINTERS* pExc)
{
    // dump it
    MiniDumpWrite(...);

    // Unless you decide to terminate your process, return EXCEPTION_EXECUTE_HANDLER, so that the execution
    // continues normally after the __except block.
    return EXCEPTION_EXECUTE_HANDLER;
}

__try
{
    // Do something...
}
__except (/* stack still not unwound */ HandleMyException(GetExceptionInformation()))
{
    // unwind already took place here, nothing to dump
}

在Windows上,您可以在客户端计算机上进行配置,这样,如果应用程序崩溃,它将创建所谓的“迷你转储文件”,然后调试器可以使用适当的PDB打开该文件

您还可以向应用程序添加未经处理的异常筛选器,并在出现无法恢复的错误时自行生成迷你转储

编辑:

如果您想在(未处理的)异常上生成转储文件,请不要在C++ >代码> catch(…)/Cux>块中执行此操作,因为它被调用<强> > <强>发生了,原始调用栈不可用。 为了捕获和转储调用堆栈,您应该在堆栈展开之前转储它。像这样:

int HandleMyException(EXCEPTION_POINTERS* pExc)
{
    // dump it
    MiniDumpWrite(...);

    // Unless you decide to terminate your process, return EXCEPTION_EXECUTE_HANDLER, so that the execution
    // continues normally after the __except block.
    return EXCEPTION_EXECUTE_HANDLER;
}

__try
{
    // Do something...
}
__except (/* stack still not unwound */ HandleMyException(GetExceptionInformation()))
{
    // unwind already took place here, nothing to dump
}
对于Windows,您可以使用。windows api允许您在程序崩溃时生成堆栈跟踪。将生成一个
dmp
文件。您可以检索该文件并在调试环境中进行调试。无需提供调试二进制文件或
pdb
文件

对于跨平台,您可以使用。该工具生成跟踪,并可自动发送跟踪,或随后发送用户生成的报告。

对于Windows,您可以使用。windows api允许您在程序崩溃时生成堆栈跟踪。将生成一个
dmp
文件。您可以检索该文件并在调试环境中进行调试。无需提供调试二进制文件或
pdb
文件


对于跨平台,您可以使用。该工具生成跟踪,可以自动发送跟踪,也可以随后发送用户生成的报告。

第一步是在应用程序崩溃时询问客户端详细信息,即场景、输入和内容。客户机会使应用程序崩溃,而您曾认为(这是一个很大的错误)应用程序无法崩溃。我从未认为它无法崩溃,我只是无法重现崩溃。第一步是在应用程序崩溃时询问客户机详细信息,即场景、输入和其他信息。客户端会使应用程序崩溃,而您认为(这是一个很大的错误)是不可崩溃的。我从来没有认为它是不可崩溃的,我只是无法重现崩溃。非常好的建议(我是指SEH),谢谢!但有一个问题:我尝试在异常处理程序中使用
MiniDumpWriteDump
,了解到导致错误的函数调用链在堆栈中不存在,我的主要愿望是获得调用堆栈。@VioletGiraffe它可能仍然存在,但在不同的线程上。你试过检查每个线程的调用堆栈吗?@VioletGiraffe你怎么知道的?您实际上是在监视线程还是您的程序只有一个线程。仅仅因为你只启动了一个线程,并不意味着SEH或其他东西不能产生新的线程。这是有道理的。我的意思是说只有一个线程可以崩溃。我已经检查了所有其他线程。据我所知,当执行流到达异常处理程序时,调用堆栈根本不可用(解开?我不太了解异常)。@VioletGiraffe您在开发机器上尝试过这个吗?在您实际调试转储文件的机器上,您需要有pdb以便实际查看任何内容。dmp文件显示加载了哪些模块?你的模块在吗?他们是否已加载pdb?在这里发布所有线程的所有调用堆栈或上载dmp文件会很有帮助。我可以看看,也许会有帮助。很好的建议(我是说SEH),谢谢!但有一个问题:我尝试在异常处理程序中使用
MiniDumpWriteDump
,了解到导致错误的函数调用链在堆栈中不存在,我的主要愿望是获得调用堆栈。@VioletGiraffe它可能仍然存在,但在不同的线程上。你试过检查每个线程的调用堆栈吗?@VioletGiraffe你怎么知道的?您实际上是在监视线程还是您的程序只有一个线程。仅仅因为你只启动了一个线程,并不意味着SEH或其他东西不能产生新的线程。这是有道理的。我的意思是说只有一个线程可以崩溃。我已经检查了所有其他线程。据我所知,当执行流到达异常处理程序时,调用堆栈根本不可用(解开?我不太了解异常)。@VioletGiraffe您在开发机器上尝试过这个吗?在您实际调试转储文件的机器上,您需要有pdb以便实际查看任何内容。什么模块没有