1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Show C backtrace appropriately at core dump for GCC 8 or later

When ruby is compiled by GCC 8 or later, some frames of C level
backtrace information lacks.

```
$ ./miniruby -e '1.times { Process.kill(:SEGV, $$) }'

...

-- C level backtrace information
-------------------------------------------
/home/mame/work/ruby-gcc-9/miniruby(rb_vm_bugreport+0x611) [0x558a5fdcbc21] ../ruby/vm_dump.c:758
[0x558a5fbc789a]
/home/mame/work/ruby-gcc-9/miniruby(sigsegv+0x4d) [0x558a5fd1eaed] ../ruby/signal.c:959
/lib/x86_64-linux-gnu/libpthread.so.0(__restore_rt+0x0) [0x7f687e6713c0]
/lib/x86_64-linux-gnu/libc.so.6(kill+0xb) [0x7f687e31355b] ../sysdeps/unix/syscall-template.S:78
/home/mame/work/ruby-gcc-9/miniruby(rb_f_kill+0x350) [0x558a5fd1fe60] ../ruby/signal.c:480
[0x558a5fda50d3]
[0x558a5fdb085c]
[0x558a5fdb0fe7]
[0x558a5fdbae1a]
[0x558a5fdaf484]
/home/mame/work/ruby-gcc-9/miniruby(rb_yield_1+0x29f) [0x558a5fdb2fbf] ../ruby/vm.c:1265
/home/mame/work/ruby-gcc-9/miniruby(int_dotimes+0x5c) [0x558a5fc72f2c] ../ruby/numeric.c:5198
[0x558a5fda50d3]
[0x558a5fdb085c]
[0x558a5fdb0fe7]
[0x558a5fdbaf21]
[0x558a5fdaf484]
/home/mame/work/ruby-gcc-9/miniruby(rb_ec_exec_node+0xed) [0x558a5fbcc4fd] ../ruby/eval.c:317
/home/mame/work/ruby-gcc-9/miniruby(ruby_run_node+0x4f) [0x558a5fbd110f] ../ruby/eval.c:375
/home/mame/work/ruby-gcc-9/miniruby(main+0x73) [0x558a5fb2c083] ../ruby/main.c:50
```

By this one-line change, it shows all locations.

```
$ ./miniruby -e '1.times { Process.kill(:SEGV, $$) }'

...

-- C level backtrace information -------------------------------------------
/home/mame/work/ruby-gcc-9/miniruby(rb_print_backtrace+0x11) [0x558247adec21] ../ruby/vm_dump.c:758
/home/mame/work/ruby-gcc-9/miniruby(rb_vm_bugreport) ../ruby/vm_dump.c:956
/home/mame/work/ruby-gcc-9/miniruby(rb_bug_for_fatal_signal+0x15a) [0x5582478da89a] ../ruby/error.c:773
/home/mame/work/ruby-gcc-9/miniruby(sigsegv+0x4d) [0x558247a31aed] ../ruby/signal.c:959
/lib/x86_64-linux-gnu/libpthread.so.0(__restore_rt+0x0) [0x7f82202f73c0]
/lib/x86_64-linux-gnu/libc.so.6(kill+0xb) [0x7f821ff9955b] ../sysdeps/unix/syscall-template.S:78
/home/mame/work/ruby-gcc-9/miniruby(rb_f_kill+0x350) [0x558247a32e60] ../ruby/signal.c:480
/home/mame/work/ruby-gcc-9/miniruby(vm_call_cfunc_with_frame+0x123) [0x558247ab80d3] ../ruby/vm_insnhelper.c:2821
/home/mame/work/ruby-gcc-9/miniruby(vm_call_method_each_type+0x7c) [0x558247ac385c] ../ruby/vm_insnhelper.c:3324
/home/mame/work/ruby-gcc-9/miniruby(vm_call_method+0xc7) [0x558247ac3fe7] ../ruby/vm_insnhelper.c:3428
/home/mame/work/ruby-gcc-9/miniruby(vm_sendish+0x14) [0x558247acde1a] ../ruby/vm_insnhelper.c:4412
/home/mame/work/ruby-gcc-9/miniruby(vm_exec_core) ../ruby/insns.def:789
/home/mame/work/ruby-gcc-9/miniruby(rb_vm_exec+0x1a4) [0x558247ac2484] ../ruby/vm.c:2165
/home/mame/work/ruby-gcc-9/miniruby(rb_yield_1+0x29f) [0x558247ac5fbf] ../ruby/vm.c:1265
/home/mame/work/ruby-gcc-9/miniruby(int_dotimes+0x5c) [0x558247985f2c] ../ruby/numeric.c:5198
/home/mame/work/ruby-gcc-9/miniruby(vm_call_cfunc_with_frame+0x123) [0x558247ab80d3] ../ruby/vm_insnhelper.c:2821
/home/mame/work/ruby-gcc-9/miniruby(vm_call_method_each_type+0x7c) [0x558247ac385c] ../ruby/vm_insnhelper.c:3324
/home/mame/work/ruby-gcc-9/miniruby(vm_call_method+0xc7) [0x558247ac3fe7] ../ruby/vm_insnhelper.c:3428
/home/mame/work/ruby-gcc-9/miniruby(vm_sendish+0x14) [0x558247acdf21] ../ruby/vm_insnhelper.c:4412
/home/mame/work/ruby-gcc-9/miniruby(vm_exec_core) ../ruby/insns.def:770
/home/mame/work/ruby-gcc-9/miniruby(rb_vm_exec+0x1a4) [0x558247ac2484] ../ruby/vm.c:2165
/home/mame/work/ruby-gcc-9/miniruby(rb_ec_exec_node+0xed) [0x5582478df4fd] ../ruby/eval.c:317
/home/mame/work/ruby-gcc-9/miniruby(ruby_run_node+0x4f) [0x5582478e410f] ../ruby/eval.c:375
/home/mame/work/ruby-gcc-9/miniruby(main+0x73) [0x55824783f083] ../ruby/main.c:50
```

Details:

In short, it is an uninitialized variable bug.

Until GCC 7, all function locations are represented by a pair of
DW_AT_low_pc and DW_AT_high_pc in DWARF information.
But since GCC 8, some functions are split to multiple chunks, which are
represented by DW_AT_ranges.
DW_AT_ranges are represented as offsets from a base address.
According to DWARF specification, it is the base address of the
compilation unit, but GCC seems to use zero as default.
The function "di_read_cu" in addr2line.c had a comment about the fact.
However, the base address wasn't initialized as zero.
This commit is contained in:
Yusuke Endoh 2020-12-11 00:09:09 +09:00
parent 7f4c31d6a3
commit f3c19ddfbc
Notes: git 2020-12-11 01:32:47 +09:00

View file

@ -914,6 +914,7 @@ debug_info_reader_init(DebugInfoReader *reader, obj_info_t *obj)
reader->p = obj->debug_info.ptr;
reader->pend = obj->debug_info.ptr + obj->debug_info.size;
reader->debug_line_cu_end = obj->debug_line.ptr;
reader->current_low_pc = 0;
}
static void