Bug #19606
closedaddr2line.c broken on Fedora 38
Description
I'm running the Fedora 38 beta on my machine, and the Ruby crash reporter is itself crashing while trying to print C-level backtraces, with an error like this:
-- C level backtrace information -------------------------------------------
1344: Abbrev Number 27547 not found
This seems to happen because the debuginfo provided by Fedora 38 (for e.g. the libc frames) is compressed with dwz. Some debginfo is shared between multiple files, and a reference to the shared file is put in the .gnu_debugaltlink
attribute of the debug object. Then, the main debug object contains forms of type DW_FORM_GNU_ref_alt
and DW_FORM_GNU_strp_alt
, whose values will refer to offsets inside the debugaltlink file.
For example, libc symbols contain a .gnu_debugaltlink
section
% readelf -x .gnu_debugaltlink /usr/lib/debug/lib64/libc.so.6-2.37-1.fc38.x86_64.debug
Hex dump of section '.gnu_debugaltlink':
0x00000000 2e2e2f2e 64777a2f 676c6962 632d322e ../.dwz/glibc-2.
0x00000010 33372d31 2e666333 382e7838 365f3634 37-1.fc38.x86_64
0x00000020 002a30a8 c71ff2fd aa58a637 226c0f56 .*0......X.7"l.V
0x00000030 3ffd674a de ?.gJ.
Some DWARF abbrev's contain references to this shared data:
% readelf --debug-dump /usr/lib/debug/lib64/libc.so.6-2.37-1.fc38.x86_64.debug
...
Contents of the .debug_abbrev section (loaded from /usr/lib/debug/lib64/libc.so.6-2.37-1.fc38.x86_64.debug):
...
50 DW_TAG_typedef [no children]
DW_AT_name DW_FORM_GNU_strp_alt
DW_AT_decl_file DW_FORM_data1
DW_AT_decl_line DW_FORM_data1
DW_AT_decl_column DW_FORM_data1
DW_AT_type DW_FORM_GNU_ref_alt
DW_AT value: 0 DW_FORM value: 0
...
Because addr2line.c doesn't know how to read these DW_FORM_GNU_*
forms in debug_info_reader_read_value
, it doesn't advance the reader at all and so the DWARF parsing becomes confused. This can lead to a garbage abbrev number being read, or even to just straight up segfaults.
I have a patch which simply skips over the right number of bytes for these forms, without actually reading any of the data: https://github.com/ruby/ruby/pull/7731. This was sufficient to make the crash reporter work again properly on my machine.
Technically speaking, perhaps we should actually open the .gnu_debugaltlink
file and dig out the referenced attribute value - this would be required if filename strings were put into the shared dwz info with DW_FORM_GNU_strp_apt
. If you think this is necessary I can try and put together a follow up patch to do this. However I've not actually seen a debuginfo file that does this, yet.