0

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

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

如果可能的话,我更喜欢不需要更改几千行代码的东西。是的,在开发工具方面,我的地位非常低下——我认为自己很幸运拥有 Visual Studio IDE 的专业版。

--edit-- 除了下面提供的出色答案之外,我还在http://www.codereversing.com/blog/?p=76找到了一些关于在您自己的代码中使用硬件断点的信息。我认为它是为了破解其他程序的想法而编写的,但它看起来可能会满足我的需要,允许我在意外位置写入变量时创建一个小型转储。那会很酷而且非常有用,尤其是如果我可以概括它的话。感谢您的回答,现在我要去看看我可以使用所有这些新信息创建什么!

4

3 回答 3

3

您可以使用MiniDumpWriteDump创建转储的函数,该转储可用于事后调试。在应用程序崩溃的情况下,您可以MiniDumpWriteDump从设置的未处理异常处理程序中调用SetUnhandledExceptionFilter。如果你说的bug不是crash,MiniDumpWriteDump当检测到一些意外情况时,你可以从程序的任何地方调用。更多关于崩溃转储和事后调试的信息:http: //www.codeproject.com/Articles/1934/Post-Mortem-Debugging-Your-Application-with-Minidu

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

于 2013-03-19T13:20:19.790 回答
2

dbghelp32.dll 中有一堆 Win32 函数,可用于为给定线程生成堆栈跟踪:有关此示例,请参见此代码

您还可以在 MSDN 上查找 StackWalk64() 和相关函数。

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

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

于 2013-03-19T13:16:45.840 回答
1

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

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

于 2013-03-19T13:37:33.387 回答