转储调用堆栈出错?

时间:2013-03-19 13:04:52

标签: c windows winapi

我正在调试用纯C(无C ++,MFC,.NET等)编写的程序到WIN32API。它必须在VS2005(在Win 2K / XP下运行)和VS2010(在Win7下运行)中编译。我一直无法复制我的客户似乎能够相当可靠地复制的错误,所以我正在寻找方法让我的程序“调试自己”原来。它正在监视所有正在改变的关键值,但我真正希望看到的是当值发生变化时的堆栈转储。哦,我不能运行“真正的”调试版本(使用调试库)而不在客户的机器上安装编译器,这不是一个选项,所以这必须内置到我的发布版本中。

除了将我自己的函数入口/出口调用添加到我自己的堆栈监视器之外,还有什么方法可以做到这一点吗?我特别希望能够在特定内存地址意外更改时设置硬件断点(因此我需要能够在几个EXPECTED更改位置周围禁用/启用它。)这可能吗?在Windows程序中?

如果可能的话,我更喜欢不需要更改几千行代码的内容。是的,当涉及到开发工​​具时,我非常处于弱势阶段 - 我认为自己很幸运能拥有专业版的Visual Studio IDE。

- edit-- 除了下面提供的优秀答案之外,我还在http://www.codereversing.com/blog/?p=76的代码中找到了有关使用硬件断点的一些信息。我认为它是用黑客攻击其他程序的想法编写的,但看起来它可以找到我的需求,允许我在意外的位置写入变量时创建一个迷你转储。这将是很酷的,非常有用,特别是如果我可以概括它。感谢您的回答,现在我想看看我能用所有这些新信息创建的东西!

3 个答案:

答案 0 :(得分:3)

您可以使用创建转储的MiniDumpWriteDump函数,该函数可用于事后调试。在应用程序崩溃的情况下,您可以从MiniDumpWriteDump设置的未处理异常处理程序中调用SetUnhandledExceptionFilter。如果您所讨论的错误没有崩溃,则可以在检测到某些意外情况时从程序的任何位置调用MiniDumpWriteDump。有关崩溃转储和事后调试的更多信息,请访问:http://www.codeproject.com/Articles/1934/Post-Mortem-Debugging-Your-Application-with-Minidu

这种技术的主要思想是将客户端站点上生成的小型转储文件发送给开发人员,可以调试它们 - 线程,堆栈和变量信息可用(由代码优化引起的明显限制)。

答案 1 :(得分:2)

dbghelp32.dll中有许多Win32函数可用于为给定线程生成堆栈跟踪:有关此示例,请参阅this code

您还可以在MSDN上查找StackWalk64()及相关功能。

要获取有用的信息,您应该在编译器中为您的发布版本打开PDB文件生成:如果您设置安装程序,以便在客户的计算机上PDB文件与DLL位于同一位置,那么您可以使用函数名称等获得可理解的堆栈跟踪。如果没有它,您将只获取函数的DLL名称和十六进制地址。

我不确定设置硬件断点有多实用:你可以编写一些使用Win32调试API的调试器,但这可能比它的价值更麻烦。

答案 2 :(得分:1)

如果您可以添加有限的检测以在症状再次出现时引发可识别的异常,则可以使用Process Dumper在该异常的任何实例上生成完整的进程转储。

我发现我非常频繁地引用这个工具,这对于难以调试的生产问题来说是一个真正的天赐之物,但似乎鲜为人知。