3

I took this code and modified it to look like this:

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;
}

This is supposed to print a stack trace of my current program to identify where things went awry without having to turn on gdb every time my program crashes.

When I run this code (in a state guaranteed to trigger an issue) I get the following stack trace:

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

My goal is to try to print as much relevant information as possible. (file, function, line). Now, I thought that the instruction: (char *)callstack[i] - (char *)info.dli_saddr) which I copied from the original script, would get me the line where the code was called, but for example the file where Display::UpdateFrame() is defined doesn;t even have 1000 lines, so trivially that number isn't the number of the calling code in the original file.

Is there a way to obtain this information with stack trace similarly to how GDB does it?

i.e if the function was called in the source code at

File: Display.hpp

Function: Display::UpdateFrame()

Line: 227

Can I retrieve that information at runtime using stacktrace?

5
  • Shot in the dark: does the line number shown include the pre-processor expanded header files above it? Commented Aug 31, 2019 at 22:56
  • Maybe, but I don't have a simple way to test it. Although if it is including the headers, i would expect a much larger number Commented Aug 31, 2019 at 23:01
  • 1
    You might be able to get more help with your inquiry by directing it to the gdb mailing list. Can't think of a better place to ask how to do something that gdb does, perhaps via an API interface of some sort, then from directly asking the folks who wrote gdb. I don't see any API of this available on Fedora, as far as I can tell, but maybe you can get lucky. Commented Sep 1, 2019 at 0:03
  • Are those line numbers or byte offsets of the machine instruction that crashed? Commented Sep 1, 2019 at 5:26
  • I am not sure, they are definitely not line numbers. So by elimination, byte offsets? Commented Sep 1, 2019 at 17:29

1 Answer 1

2

The backtrace() returns offsets in bytes relative to the start of some ELF section. In order to get line numbers and function names you need to use a library that can read the debug info of your program and then figure out which source file / line number / function the given offset corresponds to.

Here is an example of how to do this (written by me), using libbfd (assuming you're on linux):

https://github.com/CarloWood/libmemleak/blob/master/src/addr2line.c

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.