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/devel / lists.fedoraproject.org/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:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>