Я взял этот код и изменил его, чтобы он выглядел следующим образом:
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
Могу ли я получить эту информацию во время выполнения с помощью stacktrace?