简体   繁体   English

转储调用堆栈出错?

[英]Dump call stack on error?

I'm debugging a program written in plain C (no C++, MFC, .NET, etc.) to the WIN32API. 我正在调试用纯C语言编写的程序(没有C ++,MFC,.NET等)到WIN32API。 It must compile in both VS2005 (to run under Win 2K/XP) and VS2010 (to run under Win7.) I've been unable to duplicate a bug that my customer seems able to duplicate fairly reliably, so I'm looking for ways to have my program "debug itself" as-it-were. 它必须在VS2005(在Win 2K / XP下运行)和VS2010(在Win7下运行)中都可以编译。我一直无法复制客户似乎能够可靠地复制的错误,因此我正在寻找方法让我的程序“自我调试”。 It is monitoring all of the key values that are changing, but what I'd really like to see is a stack dump when a value changes. 它正在监视所有正在更改的键值,但是我真正想看到的是值更改时的堆栈转储。 Oh, I cannot run a "true" debug build (using the debug libraries) without installing the compiler on the customer's machine and that is not an option, so this must be built into my release build. 哦,如果不在客户计算机上安装编译器,则无法运行“真正的”调试版本(使用调试库),这不是一个选择,因此必须将其构建到我的发行版本中。

Is there any way to do this other than just adding my own function entry/exit calls to my own stack monitor? 除了将我自己的函数进入/退出调用添加到我自己的堆栈监视器之外,还有什么方法可以做到这一点? I'd especially like to be able to set a hardware breakpoint when a specific memory address changes unexpectedly (so I'd need to be able to disable/enable it around the few EXPECTED change locations.) Is this possible? 我特别希望能够在特定内存地址意外更改时设置硬件断点(因此,我需要能够在一些EXPECTED更改位置附近禁用/启用它)。这可能吗? In a Windows program? 在Windows程序中?

I'd prefer something that doesn't require changing several thousand lines of code, if possible. 如果可能的话,我希望不需要更改几千行代码的操作。 And yes, I'm very underprivileged when it comes to development tools -- I consider myself lucky to have a pro version of the Visual Studio IDEs. 是的,在开发工具方面我非常无能为力-我认为自己很幸运拥有Visual Studio IDE的专业版。

--edit-- In addition to the excellent answers provided below, I've found some info about using hardware breakpoints in your own code at http://www.codereversing.com/blog/?p=76 . --edit--除了下面提供的出色答案外,我还在http://www.codereversing.com/blog/?p=76上找到了一些有关在自己的代码中使用硬件断点的信息。 I think it was written with the idea of hacking other programs, but it looks like it might work find for my needs, allowing me to create a mini dump when an unexpected location writes to a variable. 我认为它是用黑客其他程序的想法编写的,但是看起来它可以满足我的需求,当意外位置写入变量时,允许我创建一个小型转储。 That would be cool and really useful, especially if I can generalize it. 那将很酷,而且非常有用,特别是如果我可以将其概括的话。 Thanks for the answers, now I'm off to see what I can create using all this new information! 感谢您的回答,现在我来看看使用所有这些新信息可以创建什么!

You can use MiniDumpWriteDump function which creates a dump, which can be used for post-mortem debugging. 您可以使用MiniDumpWriteDump函数创建转储,该转储可用于事后调试。 In the case application crashes, you can call MiniDumpWriteDump from unhandled exception handler set by SetUnhandledExceptionFilter . 如果应用程序崩溃,则可以从SetUnhandledExceptionFilter设置的未处理异常处理程序中调用MiniDumpWriteDump If the bug you are talking about is not crash, you can call MiniDumpWriteDump from any place of the program, when some unexpected situation is detected. 如果您所讨论的错误没有崩溃,则在检测到某些意外情况时,可以从程序的任何位置调用MiniDumpWriteDump More about crash dumps and post-mortem debugging here: http://www.codeproject.com/Articles/1934/Post-Mortem-Debugging-Your-Application-with-Minidu 有关崩溃转储和事后调试的更多信息,请访问: http : //www.codeproject.com/Articles/1934/Post-Mortem-Debugging-Your-Application-with-Minidu

The main idea in this technique is that mini dump files produced on a client site are sent to developer, they can be debugged - threads, stack and variables information is available (with obvious restrictions caused by code optimizations). 该技术的主要思想是将客户端站点上生成的小型转储文件发送给开发人员,并且可以对其进行调试-线程,堆栈和变量信息可用(明显受到代码优化的限制)。

There are a bunch of Win32 functions in dbghelp32.dll that can be used to produce a stack trace for a given thread: for an example of this see this code . dbghelp32.dll中有一堆Win32函数,可用于为给定线程生成堆栈跟踪:有关此示例,请参见此代码

You can also look up the StackWalk64() and related functions on MSDN. 您还可以在MSDN上查找StackWalk64()和相关功能。

To get useful information out, you should turn on PDB file generation in the compiler for your release build: if you set up your installer so that on the customer's computer the PDB files are in the same place as the DLL, then you can get an intelligible stack trace out with function names, etc. Without that, you'll just get DLL names and hex addresses for functions. 为了获得有用的信息,您应该在发行版的编译器中打开PDB文件生成:如果您设置安装程序,以便在客户计算机上PDB文件与DLL位于同一位置,那么您可以获取可理解的堆栈会使用函数名称等进行跟踪。否则,您将仅获得函数的DLL名称和十六进制地址。

I'm not sure how practical it would be to set up hardware breakpoints: you could write some sort of debugger that uses the Win32 debugging API, but that's probably more trouble than its worth. 我不确定设置硬件断点的实用性:您可以编写某种使用Win32调试API的调试器,但这可能比其价值更大。

If you can add limited instrumentation to raise an identifiable exception when the symptom recurs, you can use Process Dumper to generate a full process dump on any instance of that exception. 如果在症状再次出现时可以添加有限的工具以引发可识别的异常,则可以使用Process Dumper在该异常的任何实例上生成完整的进程转储。

I find I cite this tool very frequently, it's a real godsend for hard-to-debug production problems but seems little-known. 我发现我经常引用此工具,它确实是难以调试的生产问题的天赐之物,但鲜为人知。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM