我想在本机C++应用程序中的运行时访问调用堆栈。我没有使用IDE。如何显示调用堆栈?更新:我有一个函数,它在应用程序中的许多点都被调用。它在极少数情况下崩溃。我正在寻找一种方法来获取调用者的名称并记录它。
jk9hmnmh1#
看看StackWalk64。如果你习惯于在.NET上这样做,那么你会有一个讨厌的惊喜。
w51jfk4q2#
我相信这个页面有你正在寻找的答案。你说Visual C,所以我假设你的意思是Windows。
nuypyhwy3#
你应该考虑设置你的unhandled exception filter并从里面写一个minidump文件。它并不那么复杂,是well documented。只要坚持在你的未处理异常过滤器中做一次最少的事情(如果你有创意的话,可以阅读all go wrong)。但是为了安全起见(你的未处理异常过滤器可能会被无意中覆盖),你可以把你的代码放在__try/__except块中,并从过滤器函数中编写minidump(注意,你不能在一个带有__try/__except块的函数中拥有需要自动展开的对象,如果你有它们,考虑把它们放在一个单独的函数中):long __stdcall myfilter(EXCEPTION_POINTERS *pexcept_info){mysql(mysql);return EXCEPTION_EXECUTE_HANDLER;}void myfunc(){__try{//你的逻辑在这里} __except(myfilter(GetExceptionInformation(){//异常处理}}然后,您可以使用所选的调试器检查转储文件。Visual Studio和Windows Tools包中的调试器都可以处理小型转储。
ilmyapht4#
如果你想获取崩溃的调用堆栈,你真正想做的是post mortem debugging。如果你想在应用程序运行时检查它的调用堆栈,这是SysInternals Process Explorer可以提供的众多函数之一。
zpf6vheq5#
如果你没有积极调试,你可以“崩溃”应用程序以产生一个minidump(这可以非侵入性地完成,并让应用程序继续运行)。IIRC DrWatson将允许你这样做,如果不是来自MS支持的用户转储将允许。然后你可以将转储文件加载到windbg中,并在那里看到callstack +变量等。你需要你的应用的符号来理解跟踪。如果你正在寻找一个更简单的运行时代码风格的跟踪,我推荐一个简单的类,你在每个方法上示例化,构造函数用OutputString写方法名。使用Wincloud在程序运行时查看跟踪。(在你的类中放置某种形式的控件,即使它只是一个全局变量或注册表值,或全局Atom,这样你就可以随意打开或关闭跟踪)。
hgc7kmma6#
它在极少数情况下崩溃。我正在寻找一种方法来获得调用者的名称并记录它。你说它崩溃是什么意思?访问冲突?除以零?到底是什么?它与内核模式组件交互吗?打开appverifier。这应该会消除很多东西。创建这个:HKEY_NAME_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\FileName.exe在该键下,创建一个新的字符串name:debugger value:c:\pathtowindbg\windbg.exe-gG -xe av如果你正在使用WOW运行32位代码,你需要在wow 3264节点下这样做。
6条答案
按热度按时间jk9hmnmh1#
看看StackWalk64。
如果你习惯于在.NET上这样做,那么你会有一个讨厌的惊喜。
w51jfk4q2#
我相信这个页面有你正在寻找的答案。你说Visual C,所以我假设你的意思是Windows。
nuypyhwy3#
你应该考虑设置你的unhandled exception filter并从里面写一个minidump文件。它并不那么复杂,是well documented。只要坚持在你的未处理异常过滤器中做一次最少的事情(如果你有创意的话,可以阅读all go wrong)。
但是为了安全起见(你的未处理异常过滤器可能会被无意中覆盖),你可以把你的代码放在__try/__except块中,并从过滤器函数中编写minidump(注意,你不能在一个带有__try/__except块的函数中拥有需要自动展开的对象,如果你有它们,考虑把它们放在一个单独的函数中):
long __stdcall myfilter(EXCEPTION_POINTERS *pexcept_info)
{
mysql(mysql);
return EXCEPTION_EXECUTE_HANDLER;
}
void myfunc()
{
__try{
//你的逻辑在这里
} __except(myfilter(GetExceptionInformation(){
//异常处理
}
}
然后,您可以使用所选的调试器检查转储文件。Visual Studio和Windows Tools包中的调试器都可以处理小型转储。
ilmyapht4#
如果你想获取崩溃的调用堆栈,你真正想做的是post mortem debugging。如果你想在应用程序运行时检查它的调用堆栈,这是SysInternals Process Explorer可以提供的众多函数之一。
zpf6vheq5#
如果你没有积极调试,你可以“崩溃”应用程序以产生一个minidump(这可以非侵入性地完成,并让应用程序继续运行)。IIRC DrWatson将允许你这样做,如果不是来自MS支持的用户转储将允许。
然后你可以将转储文件加载到windbg中,并在那里看到callstack +变量等。你需要你的应用的符号来理解跟踪。
如果你正在寻找一个更简单的运行时代码风格的跟踪,我推荐一个简单的类,你在每个方法上示例化,构造函数用OutputString写方法名。使用Wincloud在程序运行时查看跟踪。(在你的类中放置某种形式的控件,即使它只是一个全局变量或注册表值,或全局Atom,这样你就可以随意打开或关闭跟踪)。
hgc7kmma6#
它在极少数情况下崩溃。我正在寻找一种方法来获得调用者的名称并记录它。
你说它崩溃是什么意思?访问冲突?除以零?到底是什么?它与内核模式组件交互吗?
打开appverifier。这应该会消除很多东西。
创建这个:
HKEY_NAME_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\FileName.exe
在该键下,创建一个新的字符串name:debugger value:c:\pathtowindbg\windbg.exe-gG -xe av
如果你正在使用WOW运行32位代码,你需要在wow 3264节点下这样做。