是否可以在不存在 PDB 文件的情况下在 Windows 上获取堆栈跟踪?如果是的话,怎么办?

问题描述 投票:0回答:3

我知道

StackWalk64()
API可以用来在Windows中打印调用堆栈。 关于这如何在 SO 上工作已经有很多讨论。

C++ 中的函数调用堆栈

Windows 上的 StackWalk64 - 获取符号名称

StackWalker - 遍历调用堆栈

我观察到

StackWalk64()
需要符号文件(PDB文件)来呈现才能找出函数名称。如果 pdb 文件不存在,则不会打印符号信息。

我的问题是 -

  1. 我的理解正确吗?我没有找到这个记录。
  2. 此 API 是否出于测试/调试目的而公开?如何让它发挥作用
    不存在 pdb 文件的生产系统?
  3. 在 Linux 上,如果符号文件不存在,则会像打印的调用堆栈一样被破坏。至少在windows上可以实现吗?
c++ visual-studio winapi window debug-symbols
3个回答
2
投票

如果只是堆栈跟踪,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]);

0
投票

回答您的问题 -

1。我的理解正确吗?我没有找到这个记录。

是的。您需要符号来打印函数名称。不需要私有符号,公共符号也可以工作(如果你想发送 pdb)。

2。此 API 是否出于测试/调试目的而公开?如何让它发挥作用 生产系统中不存在 pdb 文件?

此 API 主要用于调试器,但它可以在许多工具中使用,例如显示线程堆栈的高级任务管理器(ProcessExplorer)。 如果您想要函数名称,则需要符号(至少是公共符号)。

3.在 Linux 上,如果符号文件不存在,则像打印的调用堆栈一样被破坏。至少在windows上可以实现吗

无需符号即可实现的是 - 调用堆栈将使用偏移量(从模块开头开始)的模块名称,例如xyz.dll+0x62


0
投票

是的。 PE 文件可以嵌入调试符号,但 msvc 似乎不支持此功能(如何指示 MSVC 在可执行文件中嵌入符号?)。分开 .exe 文件和 .pdb 文件的原因是为了更快的链接。

Windows 上的 Mingw 确实将调试符号直接嵌入到 .exe 文件中,而不是 msvc 在 pdb 文件中输出。

在 Linux 和 Macos 上,通过 elf/mach-o 文件的符号表可能可以获取一些最少的信息用于堆栈跟踪。

© www.soinside.com 2019 - 2024. All rights reserved.