C++ 引发异常时获取堆栈跟踪

C++ 引发异常时获取堆栈跟踪,c++,visual-studio-2008,debugging,C++,Visual Studio 2008,Debugging,我现在正在调试一个利用许多不同线程的程序 有时会抛出一个异常。问题是没有办法知道是什么线程导致了问题 有人知道在抛出异常后获取堆栈跟踪的简单方法吗?我想简单地写一条调试消息,但这将是一个巨大的:-)我想有比这更好的技术 我使用VisualStudio 2008——本地C++项目…< /p> < p>异常本身具有属性STATTROW…所以您只需要返回ToString() 但我相信你的问题更像是如何捕捉随机异常。如果是这样,我要做的就是把所有的主代码放在一个try/catch中。我真的不太确定,如果

我现在正在调试一个利用许多不同线程的程序

有时会抛出一个异常。问题是没有办法知道是什么线程导致了问题

有人知道在抛出异常后获取堆栈跟踪的简单方法吗?我想简单地写一条调试消息,但这将是一个巨大的:-)我想有比这更好的技术


我使用VisualStudio 2008——本地C++项目…< /p> < p>异常本身具有属性STATTROW…所以您只需要返回ToString()

但我相信你的问题更像是如何捕捉随机异常。如果是这样,我要做的就是把所有的主代码放在一个try/catch中。我真的不太确定,如果异常被抛出到其他线程中,那么这种技术是否有效


您还应该捕获一个ApplicationExeption,它不是从异常派生的。

除非我大错特错,否则您需要知道哪个线程触发了异常,以便使用Visual Studio调试器的调用堆栈视图,这显然是您目前所处的catch-22情况

我想尝试的一件事是,看看在抛出异常时是否可以让调试器中断(使用Debug>Exceptions)。您必须显式地启用它,但是如果您知道抛出的异常类型,这可能会让您知道它是在哪里抛出的

除此之外,在异常的构造函数中放置一个断点(如果它是您自己的)也应该允许您确定它是从哪里触发的


如果这些方法不适合您,我会按照您的建议查看调试消息。

您可以使用异常对话框(
debug
|
异常…
菜单项,或
Ctrl+Alt+E
Ctrl+de
,具体取决于您的键盘绑定)要在抛出特定异常时将正在运行的代码分解为调试?

此库看起来很合适:


Jochen Kalmbach在包装低级dbghelp.dll接口的复杂性方面似乎做得非常彻底。

如果无法使用调试器来捕获正在发生的事情。。。你不能打印堆栈跟踪和线程

我的猜测是,你将不得不投入一些良好的润滑油和艰苦的工作。从了解系统开始。了解系统后,请尝试将系统分成两部分。起作用的部分和不起作用的部分。然后继续尝试,直到你深入到问题


当你深入到足够远的地方时,试着用try/catch来包围可疑代码。。。希望您可以使用调试器停止执行并查看发生了什么

您可以在exceptions构造函数(即您将要抛出的对象)中放置断点


当然,这假设您有一个通用的异常层次结构。

这对于Microsoft来说非常简单,它是免费的。如果尚未安装符号,您还需要为您的版本安装符号

只需将WinDBG设置为崩溃转储工具。我使用此注册表设置:(您可能希望编辑路径)

示例:
CrashDumpSettings.reg

您会得到一个很好的日志文件和一些转储文件,可以用来查看WinDBG发生异常时进程的状态。日志文件将分析发生的错误,包括导致错误的代码行。它还将列出每个线程的调用堆栈。在调用堆栈列表中,编号旁边带有
#
的线程是导致异常的线程。这些文件中有大量信息。我推荐约翰·罗宾斯来接。这是一本关于调试的好书,即使它是几年前写的。你可以从Amazon获得大约20美元。

奥弗提到他的项目是一个本地C++项目。我可能错了,但你的建议是针对.NET的,对吗?是的。。。我的错误。。。我还以为你在.NET里呢
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug]
"Auto"="1"
"Debugger"="C:\\progra~1\\debugg~1\\cdb.exe -p %ld -e %ld -g -y SRV*c:\\mss*http://msdl.microsoft.com/download/symbols -c \"$<c:\\Dumps\\CrashDump.cdbscript\""
.sympath+ c:\windows\symbols;c:\some\path\to\symbols\for\your\project

as /c CrashFirstModule .printf "%mu", @@c++((*(ntdll!_LDR_DATA_TABLE_ENTRY**)&@$peb->Ldr->InLoadOrderModuleList.Flink)->BaseDllName.Buffer) 

.logopen /t c:\dumps\${CrashFirstModule}_process.log
.kframes 100
!analyze -v
~*kv
lmv
.logclose

.dump /mhi /u /b c:\dumps\${CrashFirstModule}_mini.cab
.dump /mhia /u /b c:\dumps\${CrashFirstModule}_full.cab

q