简体   繁体   English

在运行时调用堆栈

[英]Call Stack at Runtime

I want to access the call stack at runtime in a Native C++ application. 我想在本机C ++应用程序中在运行时访问调用堆栈。 I am not using the IDE. 我没有使用IDE。 How do I display the call stack? 如何显示调用堆栈?

Update: I have a function which is called from many points all over the application. 更新:我有一个从应用程序的许多方面调用的函数。 It crashes on rare occasions. 它在极少数情况下崩溃。 I was looking for a way to get name of the caller and log it. 我正在寻找一种方法来获取呼叫者的姓名并进行记录。

Have a look at StackWalk64 . 看看StackWalk64

If you're used to doing this on .NET, then you're in for a nasty surprise. 如果您习惯在.NET上执行此操作,那么您将感到非常讨厌。

I believe that this page has the answer you are looking for. 我相信页面可以为您提供所需的答案。 You said Visual C so I assume you mean windows. 您说的是Visual C,所以我认为您的意思是Windows。

You should consider setting your unhandled exception filter and writing a minidump file from within it. 您应该考虑设置未处理的异常过滤器,并从其中写入一个小型转储文件。 It is not all that complicated and is well documented . 它并不那么复杂,并且有据可查 Just stick to the minimum of things you do once in your unhandled exception filter (read what can all go wrong if you get creative). 只需在未处理的异常过滤器中坚持做一次就可以了(如果有创意, 一切都会出错 )。

But to be on the safe side (your unhandled exception filter might get inadvertently overwritten), you could put your code inside __try/__except block and write the minidump from within the filter function (note, you cannot have objects that require automatic unwinding in a function with __try/__except block, if you do have them, consider putting them into a separate function): 但是为了安全起见(您未处理的异常过滤器可能会无意中被覆盖),您可以将代码放入__try / __ except块中,并从过滤器函数中写入minidump(请注意,您不能将需要自动展开的对象放在带有__try / __ except块的函数,如果确实有它们,请考虑将其放入单独的函数中):

long __stdcall myfilter(EXCEPTION_POINTERS *pexcept_info) 长__stdcall myfilter(EXCEPTION_POINTERS * pexcept_info)
{ {
mycreateminidump(pexcept_info); mycreateminidump(pexcept_info);
return EXCEPTION_EXECUTE_HANDLER; 返回EXCEPTION_EXECUTE_HANDLER;
} }
void myfunc() 无效myfunc()
{ {
__try{ __尝试{
//your logic here //这里的逻辑
} __except(myfilter(GetExceptionInformation())) { } __except(myfilter(GetExceptionInformation())){
// exception handled //处理异常
} }
} }

You can then inspect the dump file with a debugger of your choice. 然后,您可以使用所选的调试器检查转储文件。 Both Visual Studio and debuggers from Windows Debugging Tools package can handle minidumps. Visual Studio和Windows调试工具包中的调试器都可以处理小型转储。

If you want to get a callstack of the crash, what you really want to do is post mortem debugging . 如果您想获取崩溃的调用堆栈,那么您真正想做的就是事后调试 If you want to check a callstack of application while it is running, this is one of many functions SysInternals Process Explorer can offer. 如果要在应用程序运行时检查其调用堆栈,这是SysInternals Process Explorer可以提供的众多功能之一。

If you're not actively debugging, you can "crash" the app to produce a minidump (this can be done non-invasively and lets the app continue running). 如果您未在积极调试,则可以“崩溃”该应用程序以产生一个小型转储(这可以以非侵入方式完成,并允许该应用程序继续运行)。 IIRC DrWatson will let you do this, if not userdump from MS support will. IIRC DrWatson将允许您执行此操作,如果没有MS支持的用户转储。

You can then load the dump into windbg and see the callstack + variables etc there. 然后,您可以将转储加载到windbg中,并在那里查看callstack +变量等。 You will need your app's symbols to make sense of the trace. 您将需要应用程序的符号来理解轨迹。

If you're looking for a simpler run-time code style traces, I recommend a simple class that you instantiate on every method, the constructor writes the method name using OutputDebugString. 如果您正在寻找更简单的运行时代码样式跟踪,我建议您在每个方法上实例化一个简单的类,构造函数使用OutputDebugString编写方法名称。 Use WinDebug to view the trace as the program runs. 使用WinDebug在程序运行时查看跟踪。 (put some form of control in your class, even if its just a global variable or registry value, or global Atom so you can turn the tracing on or off at will). (即使只是一个全局变量或注册表值或全局Atom,也可以在类中添加某种形式的控件,以便您可以随意打开或关闭跟踪)。

It crashes on rare occasions. 它在极少数情况下崩溃。 I was looking for a way to get name of the caller and log it. 我正在寻找一种方法来获取呼叫者的姓名并进行记录。

What do you mean by it crashes? 您崩溃是什么意思? Access Violation? 违反访问权限? Divide by zero? 除以零? what exactly? 到底是什么 Does it interact with kernel mode components? 它是否与内核模式组件交互?

Turn on appverifier. 打开验证器。 that should eliminate a lot of things. 那应该消除很多东西。

create this: 创建这个:

HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\FileName.exe HKEY_LOCAL_MACHINE \\ SOFTWARE \\ Microsoft \\ Windows NT \\ CurrentVersion \\ Image文件执行选项\\ FileName.exe

under that key, create a new string name : debugger value: c:\\pathtowindbg\\windbg.exe -gG -xe av 在该键下,创建一个新的字符串名称:调试器值:c:\\ pathtowindbg \\ windbg.exe -gG -xe av

If you're running 32bit code with WOW, you need to do this under the wow3264node. 如果使用WOW运行32位代码,则需要在wow3264node下执行此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM