Search code examples
cdebuggingmemory-addressaddr2line

Get source location for address at runtime using debug information


In my C program, I have an instruction pointer that points to some address in virtual memory, e.g., a function pointer. I would like to map this address to the corresponding source location (file path, line number) using the debug information in the executed binary at runtime. I know that GDB implements something like this, but am unsure how to approach this for my project.

I'm aware of addr2line and llvm-symbolizer, but both of those tools analyze addresses in ELF files, not binaries that are already loaded into virtual memory. Similarly, this is not a duplicate of How do I access the addr2line functionality within my C++ program?


Solution

  • Thanks to Yakov Galka's comment, I found a solution for what I want to do:

    #define __USE_GNU
    #include <dlfcn.h>
    
    // instruction address for which I want the source location
    const void* code_addr = 0xabcdef;
    
    // call dladdr to figure out base address in virtual memory
    Dl_info info;
    dladdr(code_addr, &info);
    
    size_t base_address = (size_t) info.dli_fbase;
    size_t relative_address = ((size_t) code_addr) - base_address;
    // in my case: relative_address == 0x126c
    

    Then, I can call addr2line to determine the source location. In my case, everything is liked into a.out, so I can just call

    addr2line --basenames -i -e tasks.out 0x126c
    

    which then prints something like:

    filename.c:42