【发布时间】:2019-08-31 22:35:57
【问题描述】:
我将this code 修改为如下所示:
std::string Backtrace(int skip = 1)
{
void *callstack[128];
const int nMaxFrames = sizeof(callstack) / sizeof(callstack[0]);
char buf[1024];
int nFrames = backtrace(callstack, nMaxFrames);
char **symbols = backtrace_symbols(callstack, nFrames);
string message = "";
for (int i = skip; i < nFrames; i++) {
Dl_info info;
if (dladdr(callstack[i], &info)) {
char *demangled = nullptr;
int status;
demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status);
if(demangled != nullptr)
message += string(demangled) + ": " +
to_string((char *)callstack[i] - (char *)info.dli_saddr) + "\n";
free(demangled);
}
}
free(symbols);
if (nFrames == nMaxFrames)
message += "[truncated]\n";
return message;
}
这应该打印我当前程序的堆栈跟踪,以确定出现问题的地方,而不必在每次我的程序崩溃时打开 gdb。
当我运行此代码时(在保证会触发问题的状态下),我得到以下堆栈跟踪:
DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT, unsigned int, VkDebugUtilsMessengerCallbackDataEXT const*, void*): 146
vk::DispatchLoaderStatic::vkQueueSubmit(VkQueue_T*, unsigned int, VkSubmitInfo const*, VkFence_T*) const: 50
Display::UpdateFrame(): 1088
RenderingPipeline::RenderFrame(vk::Buffer&, vk::Buffer&, Image&, unsigned int): 63
RenderHandler::RenderHandler(Window*, HardwareInterface*, Display*, Memory*): 784
我的目标是尽可能多地打印相关信息。 (文件、函数、行)。现在,我认为指令:
我从原始脚本中复制的(char *)callstack[i] - (char *)info.dli_saddr) 会得到调用代码的行,但例如定义Display::UpdateFrame() 的文件甚至没有 1000 行,所以这个数字不是数字原文件中的调用代码。
有没有一种方法可以像 GDB 一样通过堆栈跟踪来获取这些信息?
即如果函数在源代码中被调用
File: Display.hpp
Function: Display::UpdateFrame()
Line: 227
我可以在运行时使用堆栈跟踪检索该信息吗?
【问题讨论】:
-
在黑暗中拍摄:显示的行号是否包括其上方的预处理器扩展头文件?
-
也许吧,但我没有简单的方法来测试它。虽然如果它包括标题,我会期望一个更大的数字
-
您可以通过将其发送到 gdb 邮件列表来获得更多帮助。想不出更好的地方来询问如何做 gdb 所做的事情,也许是通过某种 API 接口,然后直接询问编写 gdb 的人。据我所知,我在 Fedora 上没有看到任何可用的 API,但也许你会走运。
-
是崩溃的机器指令的行号还是字节偏移?
-
我不确定,它们绝对不是行号。那么通过消除,字节偏移量?
标签: c++ debugging stack-trace backtrace