summaryrefslogtreecommitdiff
path: root/addr2line.c
diff options
context:
space:
mode:
authorDaniel Colson <[email protected]>2025-04-28 12:54:25 -0400
committerJohn Hawthorn <[email protected]>2025-05-01 16:58:06 -0700
commit48a360baa4570a31d760040118d005bb656c6389 ()
tree9a0f986aef516813a934200fa5b139f5751e14e5 /addr2line.c
parent3176cd699359e5dc276f15452dc5ed828b58c628 (diff)
Fix C level backtraces for USE_ELF
After upgrading to Ruby 3.4 we noticed that we stopped getting useful C level backtrace information in our crash reports. We traced it back to https://.com//ruby/commit/7dd2afbe3a14d021e5554288517709f5778c3d58. 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: https://.com/ruby/ruby/blob/58e3aa02240a9ec1b5fe6ce60d63828c2cf0c73a/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: https://.com/ruby/ruby/blob/58e3aa02240a9ec1b5fe6ce60d63828c2cf0c73a/addr2line.c#L1948 Then we get to https://.com/ruby/ruby/blob/58e3aa02240a9ec1b5fe6ce60d63828c2cf0c73a/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: https://.com/ruby/ruby/blob/58e3aa02240a9ec1b5fe6ce60d63828c2cf0c73a/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]
Notes: Merged: https://.com/ruby/ruby/pull/13195
-rw-r--r--addr2line.c3
1 files changed, 1 insertions, 2 deletions
@@ -2175,9 +2175,8 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
}
}
- if (offset == -1) {
/* 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);