在运行时调用堆栈
我想在本机C ++应用程序中在运行时访问调用堆栈。我没有使用IDE。如何显示调用堆栈?
更新:我有一个从应用程序各处调用的函数。它在极少数情况下崩溃。我正在寻找一种方法来获取呼叫者的姓名并进行记录。
解决方案
看看StackWalk64.
如果我们习惯在.NET上执行此操作,那么我们将感到非常讨厌。
如果我们未在积极调试,则可以"崩溃"该应用程序以生成一个小型转储(此操作可以非侵入式完成,并允许该应用程序继续运行)。 IIRC DrWatson将允许我们执行此操作,如果不从MS支持人员转储用户的话。
然后,我们可以将转储加载到windbg中,并在那里查看callstack +变量等。我们将需要应用程序的符号来理解轨迹。
如果要查找更简单的运行时代码样式跟踪,建议我们在每个方法上实例化一个简单的类,构造函数使用OutputDebugString编写方法名称。使用WinDebug在程序运行时查看跟踪。 (即使只是一个全局变量或者注册表值或者全局Atom,也可以在类中添加某种形式的控件,以便我们可以随意打开或者关闭跟踪)。
我相信该页面可以为我们提供所需的答案。我们说的是Visual C,所以我认为意思是Windows。
我们应该考虑设置未处理的异常过滤器,并从其中写入一个小型转储文件。它并不那么复杂,并且有据可查。
只需在未处理的异常过滤器中坚持做一次就可以了(如果有创意,一切都会出错)。
但是为了安全起见(我们未处理的异常过滤器可能会无意中被覆盖),我们可以将代码放入__try / __ except块中,并从过滤器函数中写入minidump(注意,我们不能将需要自动展开的对象放在__try / __ except块的函数,如果我们确实有它们,请考虑将它们放到单独的函数中):
long __stdcall myfilter(EXCEPTION_POINTERS *pexcept_info) { mycreateminidump(pexcept_info); return EXCEPTION_EXECUTE_HANDLER; } void myfunc() { __try{ //your logic here } __except(myfilter(GetExceptionInformation())) { // exception handled } }
然后,我们可以使用所选的调试器检查转储文件。 Visual Studio和Windows调试工具包中的调试器都可以处理小型转储。
It crashes on rare occasions. I was looking for a way to get name of the caller and log it.
我们崩溃是什么意思?违反访问权限?除以零?到底是什么?它是否与内核模式组件交互?
打开验证器。那应该消除很多东西。
创建这个:
HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ Image文件执行选项\ FileName.exe
在该键下,创建一个新字符串
名称:调试器
值:c:\ pathtowindbg \ windbg.exe -gG -xe av
如果使用WOW运行32位代码,则需要在wow3264node下执行此操作。
如果我们想获取崩溃的调用栈,那么我们真正想做的就是事后调试。如果要在应用程序运行时检查其调用堆栈,这是SysInternals Process Explorer可以提供的许多功能之一。