[ruby-core:104933] [Ruby master Bug#17052] Ruby with LTO enabled has issues with SIGSEGV handler
From:
"vo.x (Vit Ondruch)" <noreply@...>
Date:
2021-08-16 22:00:59 UTC
List:
ruby-core #104933
Issue #17052 has been updated by vo.x (Vit Ondruch).
This is the GDB output:
~~~
(gdb) r
Starting program: /builddir/build/BUILD/ruby-3.0.2/miniruby -e Process.kill\ :SEGV,\ \$\$
Download failed: No route to host. Continuing without debug info for /lib64/libz.so.1.
Download failed: No route to host. Continuing without debug info for /lib64/libgmp.so.10.
Download failed: No route to host. Continuing without debug info for /lib64/libcrypt.so.2.
Download failed: No route to host. Continuing without debug info for /lib64/libm.so.6.
Download failed: No route to host. Continuing without debug info for /lib64/libc.so.6.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7aa8810 in kill () from /lib64/libc.so.6
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.34-1.fc35.ppc64le gmp-6.2.0-7.fc35.ppc64le libxcrypt-4.4.25-1.fc35.ppc64le zlib-1.2.11-30.fc35.ppc64le
(gdb) c
Continuing.
-e:1: [BUG] Segmentation fault at 0x590fb15c0000001f
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [powerpc64le-linux]
-- Control frame information -----------------------------------------------
c:0003 p:---- s:0012 e:000011 CFUNC :kill
c:0002 p:0015 s:0006 e:000005 EVAL -e:1 [FINISH]
c:0001 p:0000 s:0003 E:0013f0 (none) [FINISH]
-- Ruby level backtrace information ----------------------------------------
-e:1:in `<main>'
-e:1:in `kill'
-- C level backtrace information -------------------------------------------
Program received signal SIGSEGV, Segmentation fault.
0x000000010031fb00 in uleb128 (p=0x1005986c0) at addr2line.c:200
200 unsigned char b = *(unsigned char *)(*p)++;
(gdb) bt
#0 0x000000010031fb00 in uleb128 (p=0x1005986c0) at addr2line.c:200
#1 di_read_die (reader=0x100598668, die=0x100598578) at addr2line.c:1343
#2 0x00000001003379a8 in debug_info_read (traces=<optimized out>, offset=<optimized out>, lines=<optimized out>, num_traces=<optimized out>, reader=<optimized out>) at addr2line.c:1650
#3 fill_lines (num_traces=num_traces@entry=19, check_debuglink=check_debuglink@entry=1, objp=0x100599010, objp@entry=0x1005990a0, lines=lines@entry=0x1005e2c20, offset=0, offset@entry=-1,
traces=<optimized out>) at addr2line.c:1907
#4 0x0000000100338cfc in rb_dump_backtrace_with_lines.constprop.0 (num_traces=<optimized out>, traces=<optimized out>) at addr2line.c:2306
#5 0x000000010031df2c in rb_print_backtrace () at vm_dump.c:760
#6 0x0000000100335668 in rb_vm_bugreport.constprop.0 (ctx=<optimized out>) at vm_dump.c:998
#7 0x00000001000cd8a4 in rb_bug_for_fatal_signal (default_sighandler=0x0, sig=<optimized out>, ctx=<optimized out>, fmt=0x100383a78 "Segmentation fault at %p") at error.c:786
#8 0x00000001002562e8 in sigsegv (sig=<optimized out>, info=0x10059a330, ctx=0x1005995b0) at signal.c:960
#9 <signal handler called>
#10 0x00007ffff7aa8810 in kill () from /lib64/libc.so.6
#11 0x000000010025acd0 in rb_f_kill (argc=<optimized out>, argv=0x7ffff78e0050) at signal.c:439
#12 0x00000001001fb3a8 in proc_rb_f_kill (c=<optimized out>, v=<optimized out>, _=<optimized out>) at process.c:8605
#13 0x00000001002e9238 in ractor_safe_call_cfunc_m1 (recv=<optimized out>, argc=<optimized out>, argv=<optimized out>, func=<optimized out>) at vm_insnhelper.c:2739
#14 0x00000001002f2080 in vm_call_cfunc_with_frame (ec=0x100491ac0, reg_cfp=0x7fffffffe170, calling=<optimized out>) at vm_insnhelper.c:2929
#15 0x00000001002f4e94 in vm_sendish (ec=0x100491ac0, reg_cfp=0x7ffff79dffa0, cd=0x1005c2e80, block_handler=<optimized out>, method_explorer=<optimized out>) at vm_insnhelper.c:4530
#16 0x00000001002fa20c in vm_exec_core (ec=0x100491ac0, initial=<optimized out>) at insns.def:789
#17 0x0000000100315140 in rb_vm_exec (ec=0x100491ac0, mjit_enable_p=<optimized out>) at vm.c:2172
#18 0x0000000100316f80 in rb_iseq_eval_main (iseq=0x1004a9fd8) at vm.c:2420
#19 0x00000001000d7c6c in rb_ec_exec_node (ec=ec@entry=0x100491ac0, n=n@entry=0x1004a9fd8) at eval.c:317
#20 0x00000001000d7dd4 in ruby_run_node (n=0x1004a9fd8) at eval.c:375
#21 0x000000010002afb8 in main (argc=<optimized out>, argv=<optimized out>) at ./main.c:50
(gdb) l uleb128
file: "addr2line.c", line number: 195, symbol: "uleb128"
190
191 /* Avoid consuming stack as this module may be used from signal handler */
192 static char binary_filename[PATH_MAX + 1];
193
194 static unsigned long
195 uleb128(char **p)
196 {
197 unsigned long r = 0;
198 int s = 0;
199 for (;;) {
file: "addr2line.c", line number: 197, symbol: "uleb128"
192 static char binary_filename[PATH_MAX + 1];
193
194 static unsigned long
195 uleb128(char **p)
196 {
197 unsigned long r = 0;
198 int s = 0;
199 for (;;) {
200 unsigned char b = *(unsigned char *)(*p)++;
201 if (b < 0x80) {
file: "addr2line.c", line number: 200, symbol: "uleb128"
195 uleb128(char **p)
196 {
197 unsigned long r = 0;
198 int s = 0;
199 for (;;) {
200 unsigned char b = *(unsigned char *)(*p)++;
201 if (b < 0x80) {
202 r += (unsigned long)b << s;
203 break;
204 }
file: "addr2line.c", line number: 201, symbol: "uleb128"
196 {
197 unsigned long r = 0;
198 int s = 0;
199 for (;;) {
200 unsigned char b = *(unsigned char *)(*p)++;
201 if (b < 0x80) {
202 r += (unsigned long)b << s;
203 break;
204 }
205 r += (b & 0x7f) << s;
(gdb)
206 s += 7;
207 }
208 return r;
209 }
210
211 static long
212 sleb128(char **p)
213 {
214 long r = 0;
215 int s = 0;
(gdb) l di_read_die
1328 }
1329 #endif
1330
1331 static DIE *
1332 di_read_die(DebugInfoReader *reader, DIE *die)
1333 {
1334 uint64_t abbrev_number = uleb128(&reader->p);
1335 if (abbrev_number == 0) {
1336 reader->level--;
1337 return NULL;
(gdb)
1338 }
1339
1340 reader->q = di_find_abbrev(reader, abbrev_number);
1341
1342 die->pos = reader->p - reader->obj->debug_info.ptr - 1;
1343 die->tag = (int)uleb128(&reader->q); /* tag */
1344 die->has_children = *reader->q++; /* has_children */
1345 if (die->has_children) {
1346 reader->level++;
1347 }
(gdb)
1348 return die;
1349 }
1350
1351 static DebugInfoValue *
1352 di_read_record(DebugInfoReader *reader, DebugInfoValue *vp)
1353 {
1354 uint64_t at = uleb128(&reader->q);
1355 uint64_t form = uleb128(&reader->q);
1356 if (!at || !form) return NULL;
1357 vp->at = at;
(gdb) l debug_info_read
1643 debug_info_read(DebugInfoReader *reader, int num_traces, void **traces,
1644 line_info_t *lines, int offset) {
1645 while (reader->p < reader->cu_end) {
1646 DIE die;
1647 ranges_t ranges = {};
1648 line_info_t line = {};
1649
1650 if (!di_read_die(reader, &die)) continue;
1651 /* fprintf(stderr,"%d:%tx: <%d>\n",__LINE__,die.pos,reader->level,die.tag); */
1652
(gdb)
1653 if (die.tag != DW_TAG_subprogram && die.tag != DW_TAG_inlined_subroutine) {
1654 skip_die:
1655 di_skip_records(reader);
1656 continue;
1657 }
1658
1659 /* enumerate abbrev */
1660 for (;;) {
1661 DebugInfoValue v = {{}};
1662 /* ptrdiff_t pos = reader->p - reader->p0; */
(gdb)
1663 if (!di_read_record(reader, &v)) break;
1664 /* fprintf(stderr,"\n%d:%tx: AT:%lx FORM:%lx\n",__LINE__,pos,v.at,v.form); */
1665 /* div_inspect(&v); */
1666 switch (v.at) {
1667 case DW_AT_name:
1668 line.sname = get_cstr_value(&v);
1669 break;
1670 case DW_AT_call_file:
1671 fill_filename((int)v.as.uint64, reader->debug_line_directories, reader->debug_line_files, &line, reader->obj);
1672 break;
(gdb)
1673 case DW_AT_call_line:
1674 line.line = (int)v.as.uint64;
1675 break;
1676 case DW_AT_low_pc:
1677 case DW_AT_high_pc:
1678 case DW_AT_ranges:
1679 ranges_set(&ranges, &v);
1680 break;
1681 case DW_AT_declaration:
1682 goto skip_die;
(gdb)
1683 case DW_AT_inline:
1684 /* 1 or 3 */
1685 break; /* goto skip_die; */
1686 case DW_AT_abstract_origin:
1687 read_abstract_origin(reader, v.form, v.as.uint64, &line);
1688 break; /* goto skip_die; */
1689 }
1690 }
1691 /* ranges_inspect(reader, &ranges); */
1692 /* fprintf(stderr,"%d:%tx: %x ",__LINE__,diepos,die.tag); */
(gdb)
1693 for (int i=offset; i < num_traces; i++) {
1694 uintptr_t addr = (uintptr_t)traces[i];
1695 uintptr_t offset = addr - reader->obj->base_addr + reader->obj->vmaddr;
1696 uintptr_t saddr = ranges_include(reader, &ranges, offset);
1697 if (saddr) {
1698 /* fprintf(stderr, "%d:%tx: %d %lx->%lx %x %s: %s/%s %d %s %s %s\n",__LINE__,die.pos, i,addr,offset, die.tag,line.sname,line.dirname,line.filename,line.line,reader->obj->path,line.sname,lines[i].sname); */
1699 if (lines[i].sname) {
1700 line_info_t *lp = malloc(sizeof(line_info_t));
1701 memcpy(lp, &lines[i], sizeof(line_info_t));
1702 lines[i].next = lp;
(gdb)
1703 lp->dirname = line.dirname;
1704 lp->filename = line.filename;
1705 lp->line = line.line;
1706 lp->saddr = 0;
1707 }
1708 lines[i].path = reader->obj->path;
1709 lines[i].base_addr = line.base_addr;
1710 lines[i].sname = line.sname;
1711 lines[i].saddr = saddr + reader->obj->base_addr - reader->obj->vmaddr;
1712 }
(gdb)
1713 }
1714 }
1715 }
1716
1717 #ifdef USE_ELF
1718 static unsigned long
1719 uncompress_debug_section(ElfW(Shdr) *shdr, char *file, char **ptr)
1720 {
1721 #ifdef SUPPORT_COMPRESSED_DEBUG_LINE
1722 ElfW(Chdr) *chdr = (ElfW(Chdr) *)(file + shdr->sh_offset);
(gdb)
~~~
----------------------------------------
Bug #17052: Ruby with LTO enabled has issues with SIGSEGV handler
https://bugs.ruby-lang.org/issues/17052#change-93298
* Author: vo.x (Vit Ondruch)
* Status: Open
* Priority: Normal
* ruby -v: ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [powerpc64le-linux]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN
----------------------------------------
Fedora aims to enable link time optimization (LTO) of packages in next release. The specific changes in configuration options are available here [1]. Since that time, I observe following errors [2] at least on {aarch64,ppc64le} (and possibly also other architectures):
~~~
1) Failure:
TestBugReporter#test_bug_reporter_add [/builddir/build/BUILD/ruby-2.7.1/test/-ext-/bug_reporter/test_bug_reporter.rb:22]:
pid 32395 killed by SIGSEGV (signal 11) (core dumped)
| -:1: [BUG] Segmentation fault at 0x000003e800007e8b
| ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [powerpc64le-linux]
|
| -- Control frame information -----------------------------------------------
| c:0003 p:---- s:0012 e:000011 CFUNC :kill
| c:0002 p:0021 s:0006 e:000005 EVAL -:1 [FINISH]
| c:0001 p:0000 s:0003 E:000f80 (none) [FINISH]
|
| -- Ruby level backtrace information ----------------------------------------
| -:1:in `<main>'
| -:1:in `kill'
|
| -- C level backtrace information -------------------------------------------
..
1. [2/2] Assertion for "stderr"
| Expected /Sample bug reporter: 12345/
| to match
| "-- Control frame information -----------------------------------------------\n"+
| "c:0003 p:---- s:0012 e:000011 CFUNC :kill\n"+
| "c:0002 p:0021 s:0006 e:000005 EVAL -:1 [FINISH]\n"+
| "c:0001 p:0000 s:0003 E:000f80 (none) [FINISH]\n\n"+
| "-- Ruby level backtrace information ----------------------------------------\n"+
| "-:1:in `<main>'\n"+
| "-:1:in `kill'\n\n"+
| "-- C level backtrace information -------------------------------------------\n"
| after 4 patterns with 120 characters.
2) Failure:
TestRubyOptions#test_segv_loaded_features [/builddir/build/BUILD/ruby-2.7.1/test/ruby/test_rubyoptions.rb:735]:
pid 38444 killed by SIGSEGV (signal 11) (core dumped)
| -e:1: [BUG] Segmentation fault at 0x000003e80000962c
| ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [powerpc64le-linux]
|
| -- Control frame information -----------------------------------------------
| c:0003 p:---- s:0012 e:000011 CFUNC :kill
| c:0002 p:0016 s:0006 e:000005 BLOCK -e:1 [FINISH]
| c:0001 p:0000 s:0003 E:002460 (none) [FINISH]
|
| -- Ruby level backtrace information ----------------------------------------
| -e:1:in `block in <main>'
| -e:1:in `kill'
|
| -- C level backtrace information -------------------------------------------
..
1. [2/2] Assertion for "stderr"
| <""> expected but was
| <"-- C level backtrace information -------------------------------------------\n">.
3) Failure:
TestRubyOptions#test_segv_setproctitle [/builddir/build/BUILD/ruby-2.7.1/test/ruby/test_rubyoptions.rb:749]:
pid 38451 killed by SIGSEGV (signal 11) (core dumped)
| -e:1: [BUG] Segmentation fault at 0x000003e800009633
| ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [powerpc64le-linux]
|
| -- Control frame information -----------------------------------------------
| c:0003 p:---- s:0012 e:000011 CFUNC :kill
| c:0002 p:0029 s:0006 e:000005 EVAL -e:1 [FINISH]
| c:0001 p:0000 s:0003 E:000480 (none) [FINISH]
|
| -- Ruby level backtrace information ----------------------------------------
| -e:1:in `<main>'
| -e:1:in `kill'
|
| -- C level backtrace information -------------------------------------------
..
1. [2/2] Assertion for "stderr"
| <""> expected but was
| <"-- C level backtrace information -------------------------------------------\n">.
4) Failure:
TestRubyOptions#test_segv_test [/builddir/build/BUILD/ruby-2.7.1/test/ruby/test_rubyoptions.rb:729]:
pid 38460 killed by SIGSEGV (signal 11) (core dumped)
| -e:1: [BUG] Segmentation fault at 0x000003e80000963c
| ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [powerpc64le-linux]
|
| -- Control frame information -----------------------------------------------
| c:0003 p:---- s:0012 e:000011 CFUNC :kill
| c:0002 p:0015 s:0006 e:000005 EVAL -e:1 [FINISH]
| c:0001 p:0000 s:0003 E:0006a0 (none) [FINISH]
|
| -- Ruby level backtrace information ----------------------------------------
| -e:1:in `<main>'
| -e:1:in `kill'
|
| -- C level backtrace information -------------------------------------------
..
1. [2/2] Assertion for "stderr"
| <""> expected but was
| <"-- C level backtrace information -------------------------------------------\n">.
Finished tests in 840.600443s, 25.0047 tests/s, 3238.9681 assertions/s.
21019 tests, 2722678 assertions, 4 failures, 0 errors, 70 skips
ruby -v: ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [powerpc64le-linux]
~~~
When I raised the issue on fedora-devel ML [3], there was suggestion that it might happen when signal handler modifies any global variable. Now I am not sure if that is the case. Can somebody confirm? Or investigate/fix this, please?
[1]: https://src.fedoraproject.org/rpms/redhat-rpm-config/c/5baaf4a99cc77572d3496a7000674098bef7ed68?branch=master
[2]: https://koschei.fedoraproject.org/package/ruby
[3]: https://lists.fedoraproject.org/archives/list/[email protected]/message/D6YUXPU5C2RWIQMNHLT4HBYXUGVKKPOW/
---Files--------------------------------
ruby-addr2line-DW_FORM_ref_addr.patch (651 Bytes)
ruby-addr2line-read_abstract_origin.patch (1.37 KB)
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:[email protected]?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>