【发布时间】:2010-09-12 16:35:03
【问题描述】:
我想在本机 C++ 应用程序中在运行时访问调用堆栈。我没有使用 IDE。如何显示调用堆栈?
更新:我有一个从整个应用程序的许多点调用的函数。它在极少数情况下崩溃。我正在寻找一种方法来获取调用者的姓名并记录它。
【问题讨论】:
标签: debugging visual-c++ callstack
我想在本机 C++ 应用程序中在运行时访问调用堆栈。我没有使用 IDE。如何显示调用堆栈?
更新:我有一个从整个应用程序的许多点调用的函数。它在极少数情况下崩溃。我正在寻找一种方法来获取调用者的姓名并记录它。
【问题讨论】:
标签: debugging visual-c++ callstack
看看StackWalk64。
如果您习惯在 .NET 上执行此操作,那么您会大吃一惊。
【讨论】:
如果您没有主动调试,您可以“崩溃”应用程序以生成一个小型转储(这可以非侵入性地完成并让应用程序继续运行)。 IIRC DrWatson 会让你这样做,如果不是来自 MS 支持的 userdump。
然后您可以将转储加载到 windbg 并在那里查看调用堆栈 + 变量等。您将需要应用的符号来理解跟踪。
如果您正在寻找更简单的运行时代码样式跟踪,我建议您在每个方法上实例化一个简单的类,构造函数使用 OutputDebugString 写入方法名称。使用 WinDebug 在程序运行时查看跟踪。 (在您的类中放置某种形式的控制,即使它只是一个全局变量或注册表值,或全局 Atom,以便您可以随意打开或关闭跟踪)。
【讨论】:
我相信this 页面有您正在寻找的答案。您说的是 Visual C,所以我假设您的意思是 windows。
【讨论】:
您应该考虑设置您的unhandled exception filter 并从其中写入一个小型转储文件。它并不是那么复杂,是well documented。 只需坚持在未处理的异常过滤器中执行的最少操作(如果您有创意,请阅读 all go wrong 可以做什么)。
但为了安全起见(您的未处理异常过滤器可能会无意中被覆盖),您可以将代码放在 __try/__except 块中并从过滤器函数中编写小型转储(注意,您不能拥有需要自动使用 __try/__except 块在函数中展开,如果有,请考虑将它们放入单独的函数中):
长 __stdcall myfilter(EXCEPTION_POINTERS *pexcept_info)
{
mycreateminidump(pexcept_info);
返回 EXCEPTION_EXECUTE_HANDLER;
}
无效 myfunc()
{
__尝试{
//你的逻辑在这里
} __except(myfilter(GetExceptionInformation())) {
// 异常处理
}
}
然后您可以使用您选择的调试器检查转储文件。 Visual Studio 和 Windows 调试工具包中的调试器都可以处理小型转储。
【讨论】:
它在极少数情况下会崩溃。我正在寻找一种方法来获取调用者的姓名并记录它。
崩溃是什么意思?访问冲突?除以零?究竟是什么?它是否与内核模式组件交互?
开启 appverifier。这应该会消除很多东西。
创建这个:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\FileName.exe
在该键下,创建一个新字符串 名称:调试器 值:c:\pathtowindbg\windbg.exe -gG -xe av
如果您使用 WOW 运行 32 位代码,则需要在 wow3264 节点下执行此操作。
【讨论】:
如果你想得到崩溃的调用堆栈,你真正想做的是post mortem debugging。如果您想在应用程序运行时检查其调用堆栈,这是SysInternals Process Explorer 可以提供的众多功能之一。
【讨论】: