我知道
StackWalk64()
API可以用来在Windows中打印调用堆栈。
关于这如何在 SO 上工作已经有很多讨论。
Windows 上的 StackWalk64 - 获取符号名称
我观察到
StackWalk64()
需要符号文件(PDB文件)来呈现才能找出函数名称。如果 pdb 文件不存在,则不会打印符号信息。
我的问题是 -
如果只是堆栈跟踪,CaptureStackBackTrace() 应该足够了。
void *stack[48];
USHORT count = CaptureStackBackTrace(0, 48, stack, NULL);
for(USHORT c = 0; c < count; c++)
printf("addr %02d: %p\n", c, stack[c]);
回答您的问题 -
1。我的理解正确吗?我没有找到这个记录。
是的。您需要符号来打印函数名称。不需要私有符号,公共符号也可以工作(如果你想发送 pdb)。
2。此 API 是否出于测试/调试目的而公开?如何让它发挥作用 生产系统中不存在 pdb 文件?
此 API 主要用于调试器,但它可以在许多工具中使用,例如显示线程堆栈的高级任务管理器(ProcessExplorer)。 如果您想要函数名称,则需要符号(至少是公共符号)。
3.在 Linux 上,如果符号文件不存在,则像打印的调用堆栈一样被破坏。至少在windows上可以实现吗
无需符号即可实现的是 - 调用堆栈将使用偏移量(从模块开头开始)的模块名称,例如xyz.dll+0x62
是的。 PE 文件可以嵌入调试符号,但 msvc 似乎不支持此功能(如何指示 MSVC 在可执行文件中嵌入符号?)。分开 .exe 文件和 .pdb 文件的原因是为了更快的链接。
Windows 上的 Mingw 确实将调试符号直接嵌入到 .exe 文件中,而不是 msvc 在 pdb 文件中输出。
在 Linux 和 Macos 上,通过 elf/mach-o 文件的符号表可能可以获取一些最少的信息用于堆栈跟踪。