发布代码的逐步执行/事后调试(VS/C++)
单步执行发布代码有任何意义吗?我注意到省略了一些代码行,即一些方法调用。此外,变量预览不显示某些变量,并显示其他一些变量的无效(非真实)值,因此这完全具有误导性。
我问这个问题是因为将 WinDbg 故障转储文件加载到 Visual Studio 中会带来与单步执行相同的堆栈和变量部分视图。除了在没有优化的情况下重新编译应用程序之外,还有什么方法可以改善故障转储分析体验?
Windows、Visual Studio 2005、非托管 C++
Is there any sense to step-execute release code? I noticed that some lines of code are omitted, i.e. some method calls. Also variable preview doesn't show some variables and shows invalid (not real) values for some others, so it's all quite misleading.
I'm asking this question, because loading WinDbg crashdump file into Visual Studio brings the same stack and variables partial view as step-execution. Are there any way to improve crashdump analyze experience, except recompiling application without optimalizations?
Windows, Visual Studio 2005, unmanaged C++
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的 - 如果您有用于构建的 .pdb 以及崩溃时的 .dmp 文件,那么您可以在确切的故障点打开调试器,并检查该点应用程序的状态。
正如一些人所指出的 - 某些变量将被优化掉,但如果您有一点创造力/好奇心,您会找到获得这些值的方法。
您可以为您的代码构建一个根崩溃处理程序,以自动生成一个 .dmp 文件,该文件适用于所有 Windows 风格(假设您正在创建一个 Windows 应用程序),使用如下所示的内容:
上面的内容需要我在下面编写的 MiniDumper 类:
及其实现:
对于这不是一个即插即用的解决方案,我深表歉意。我的 Toolbox 库的其他部分存在依赖关系。但我认为这将有助于让您正确了解如何从代码中自动构建“捕获崩溃小型转储”,然后您可以将其与 .dsp 文件结合起来,制作一个开发周期的正常部分 - 这样当 .dmp 进入时 - 您可以使用发布版本(您不分发!)中保存的 .pdb 启动调试器,并且您可以相当调试崩溃情况容易地。
上面的代码是许多不同来源的混合体——来自调试书籍、MSDN 文档等的代码片段。如果我省略了归属,我的意思是没有坏处。但是,我不相信上述任何代码是由除我之外的任何人显着创建的。
Yes - if you have the .pdb for the build, and the .dmp file from the crash, then you can open the debugger on the exact point of failure, and examine the state of your app at that point.
As several have noted - some variables will be optimized away, but if you're mildly creative / inquisitive, you'll find ways to obtain those values.
You can build in a root crash handler for your code to generate a .dmp file automatically which works on all Windows flavors (assuming you are creating a Windows app) using something like the following:
The above would require the MiniDumper class I wrote, below:
And its implementation:
I apologize for the fact that this is not a drop-in solution. There are dependencies on other parts of my Toolbox library. But I think it would go a long way towards giving you the right idea as to how to build-in "capture a crash mini-dump" automatically from your code, which you can then combine with your .dsp files that you can make a normal part of your development cycle - so that when a .dmp comes in - you can fire up the debugger on it with your saved .pdb from your release build (which you don't distribute!) and you can debug the crash conditions quite easily.
The above code is an amalgam of many different sources - code snippets from debugging books, from MSDN documentation, etc., etc. If I have left out attribution I mean no harm. However, I do no believe that any of the above code is significantly created by anyone but myself.
仅重新编译感兴趣的文件而不进行优化:)
一般情况下:
Recompile just the file of interest without optimisations :)
In general:
至少不是 IA64 转储...
除了完整转储和私有符号之外,您实际上无能为力。现代编译器对您的代码很感兴趣,并且几乎无法识别,特别是如果您添加类似
我发现有两件事很有用:
沿着堆栈向上走,直到你对“this”真正指向的内容有了一个很好的定位。大多数时候,当您处于对象方法框架中时,由于注册表优化,“this”是不可靠的。通常,多次调用堆栈,您会得到一个具有正确地址的对象,您可以逐个成员引用进行导航,直到崩溃点并为“this”提供正确的值
uf(Windbg 的反汇编函数命令)提供正确的值。这个小助手可以以比普通反汇编视图更易于管理的形式列出反汇编函数。因为它遵循跳转和代码重新排列,所以更容易遵循uf输出的逻辑。
At least is not a IA64 dump...
There really isn't much you can do beyond having full dump and private symbols. Modern compilers have a field day with your code and is barely recognisable, specially if you add something like LTCG.
There are two things I found usefull:
Walk up the stack until you get a good anchor on what 'this' really points to. Most times when you are in an object method frame 'this' is unreliable because of registry optmizations. Usually several calls up the stack you get an object that has the correct address and you can navigate, member reference by member reference, until your crash point and have a correct value for 'this'
uf (Windbg's unassembly function command). This little helper can list a function dissasembly in a more manageable form than the normal dissasembly view. Because it follows jumps and code re-arranges, is easier to follow the logic of uf output.
最重要的是要有符号文件(*.pdb)。您可以为发布版本生成它们,默认情况下它们不处于活动状态。
然后您必须知道,由于优化,代码可能会重新排序,因此调试可能看起来有点不稳定。此外,一些中间变量可能已被优化掉。一般来说,数据的行为和可见性可能有一些限制。
使用 Visual Studio C++ 2008,您可以自动调试 *.dmp 文件。我相信它也适用于 VS 2005。对于较旧的编译器,恐怕您必须使用 WinDbg...(当然还要指定 WinDbg 的 *.pdb 文件,否则信息将非常有限)
The most important thing is to have the symbol files (*.pdb). You can generate them for release builds, by default they are not active.
Then you have to know that because of optimizations, code might get re-ordered, so debugging could look a bit jerky. Also some intermediate variables might have got optimized away. Generally speaking the behaviour and visibility of data might have some restrictions.
With Visual Studio C++ 2008 you can automatically debug the *.dmp files. I believe it also works for VS 2005. For older compilers I am afraid you´ll have to use WinDbg... (Also specify of course the *.pdb files for WinDbg, otherwise the info will be quite limited)