jeremy-rifkin / cpptrace

Simple, portable, and self-contained stacktrace library for C++11 and newer
MIT License
621 stars 64 forks source link

Image base address mapping isn't handled correctly with _dl_find_object #104

Closed jeremy-rifkin closed 5 months ago

jeremy-rifkin commented 5 months ago

When building cpptrace with cmake .. -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=Off -GNinja -DCMAKE_INSTALL_PREFIX=foo && ninja install and then using it in a simple test program:

~/test !16569 › g++ main.cpp -I include -L foo/lib -lcpptrace -ldl -ldwarf -lz -lzstd -g
~/test !16570 › ./a.out
Stack trace (most recent call first):
#0 0x0000000000404949 at /home/rifkin/test/a.out
#1 0x00007f20dc661d8f in __libc_start_call_main at ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#2 0x00007f20dc661e3f in __libc_start_main_impl at ./csu/../csu/libc-start.c:392:3
#3 0x0000000000404864 at /home/rifkin/test/a.out

Frame 0 should be main at main.cpp line 5.

raw address:
0x0000000000404949
4213065

object address:
0x804949
8407369

readelf -l ./a.out

Elf file type is EXEC (Executable file)
Entry point 0x404840
There are 13 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
                 0x00000000000002d8 0x00000000000002d8  R      0x8
  INTERP         0x0000000000000318 0x0000000000400318 0x0000000000400318
                 0x000000000000001c 0x000000000000001c  R      0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x0000000000003da0 0x0000000000003da0  R      0x1000
  LOAD           0x0000000000004000 0x0000000000404000 0x0000000000404000
                 0x00000000001036a1 0x00000000001036a1  R E    0x1000
  LOAD           0x0000000000108000 0x0000000000508000 0x0000000000508000
                 0x0000000000054a8c 0x0000000000054a8c  R      0x1000
  LOAD           0x000000000015d1f0 0x000000000055e1f0 0x000000000055e1f0
                 0x00000000000019f0 0x0000000000002380  RW     0x1000
  DYNAMIC        0x000000000015dda0 0x000000000055eda0 0x000000000055eda0
                 0x0000000000000220 0x0000000000000220  RW     0x8
  NOTE           0x0000000000000338 0x0000000000400338 0x0000000000400338
                 0x0000000000000020 0x0000000000000020  R      0x8
  NOTE           0x0000000000000358 0x0000000000400358 0x0000000000400358
                 0x0000000000000020 0x0000000000000020  R      0x4
  GNU_PROPERTY   0x0000000000000338 0x0000000000400338 0x0000000000400338
                 0x0000000000000020 0x0000000000000020  R      0x8
  GNU_EH_FRAME   0x0000000000135c48 0x0000000000535c48 0x0000000000535c48
                 0x000000000000743c 0x000000000000743c  R      0x4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x10
  GNU_RELRO      0x000000000015d1f0 0x000000000055e1f0 0x000000000055e1f0
                 0x0000000000000e10 0x0000000000000e10  R      0x1

The base address is being resolved to 0x400000 and that offset is throwing things off. The correct offset for the dwarf lookup is 0x404949:

addr2line -e a.out 404949 -f -C
main
main.cpp:5
jeremy-rifkin commented 5 months ago

It looks like this only happens when using _dl_find_object