Fix C level backtraces for USE_ELF

After upgrading GitHub to Ruby 3.4 we noticed that we stopped getting
useful C level backtrace information in our crash reports. We traced it
back to 7dd2afbe3a.

Passing 0 instead of -1 made sense for the Mach-O version of
`fill_lines`, but there is a separate ELF version of `fill_lines` that
still has special handling for -1: 58e3aa0224/addr2line.c (L2178-L2209)

Without this special handling for the main executable, we don't have the
right `base_addr` when reading debug info, and so we fail to populate
the information for that line: 58e3aa0224/addr2line.c (L1948)
Then we get to 58e3aa0224/addr2line.c (L2649),
and potentially (depending on how things were run) get back `"ruby"` as
`info.dli_fname` instead of the absolute path for the executable. We set
that as the `binary_filename` and then try to open it inside the next
call to `fill_lines`, but that fails (unless you happen to be in the
directory where the ruby executable lives) and break out of filling
lines entirely: 58e3aa0224/addr2line.c (L2673-L2674)

This commit treats offset 0 as the main executable, rather than having
a special meaning for -1 (which gets turned into 0 anyway).

[Bug #21289]
This commit is contained in:
Daniel Colson 2025-04-28 12:54:25 -04:00 committed by John Hawthorn
parent 3176cd6993
commit 48a360baa4
Notes: git 2025-05-01 23:58:21 +00:00

View File

@ -2175,9 +2175,8 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
}
}
if (offset == -1) {
if (offset == 0) {
/* main executable */
offset = 0;
if (dynsym_shdr && dynstr_shdr) {
char *strtab = file + dynstr_shdr->sh_offset;
ElfW(Sym) *symtab = (ElfW(Sym) *)(file + dynsym_shdr->sh_offset);