pkgsrc-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

pkg/59017: ruby32 crashes in asciidoctor



>Number:         59017
>Category:       pkg
>Synopsis:       ruby32 crashes in asciidoctor
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Jan 21 10:10:00 +0000 2025
>Originator:     Taylor R Campbell
>Release:        netbsd-9 userland on netbsd-10 kernel, pkgsrc-current, ruby32-base-3.2.5
>Organization:
The NetBSigaltstackD Gemdation
>Environment:
>Description:
While trying to build a package that uses asciidoctor, ruby crashes with SIGSEGV:

asciidoctor  --require=./doc/man.rb --backend=manpage doc/manpage-newsboat.asciidoc
/home/riastradh/pkgsrc/git/cross/pkg/lib/ruby/3.2.0/x86_64-netbsd/rbconfig.rb: [BUG] Segmentation fault
ruby 3.2.6 (2024-10-30 revision 63aeb018eb) [x86_64-netbsd]

-- Control frame information -----------------------------------------------
c:0006 p:---- s:0027 e:000026 DUMMY  [FINISH]
c:0005 p:---- s:0024 e:000023 CFUNC  :require
c:0004 p:0005 s:0019 e:000018 TOP    /home/riastradh/pkgsrc/git/cross/pkg/lib/ruby/3.2.0/rubygems.rb:9 [FINISH]
c:0003 p:---- s:0012 e:000011 CFUNC  :require
c:0002 p:0012 s:0007 e:000006 TOP    <internal:gem_prelude>:2 [FINISH]
c:0001 p:0000 s:0003 E:000a40 DUMMY  [FINISH]

-- Ruby level backtrace information ----------------------------------------
<internal:gem_prelude>:2:in `<internal:gem_prelude>'
<internal:gem_prelude>:2:in `require'
/home/riastradh/pkgsrc/git/cross/pkg/lib/ruby/3.2.0/rubygems.rb:9:in `<top (required)>'
/home/riastradh/pkgsrc/git/cross/pkg/lib/ruby/3.2.0/rubygems.rb:9:in `require'

The crash happened with and without the ruby-yjit option.  I've seen this several times over the past few years (with earlier versions of ruby) so I went digging this time now that I have debug data.

The stack trace from gdb is not helpful -- it looks like the error-reporting logic in the SIGSEGV handler itself crashed with SIGSEGV:

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007e845f041dd1 in uleb128 (p=0x7f7fff8b5ac0) at addr2line.c:206
206             unsigned char b = (unsigned char)*(*p)++;
(gdb) bt
#0  0x00007e845f041dd1 in uleb128 (p=0x7f7fff8b5ac0) at addr2line.c:206
#1  di_read_debug_abbrev_cu (reader=0x7f7fff8b5b00) at addr2line.c:1048
#2  di_read_cu (reader=0x7f7fff8b5b00) at addr2line.c:1737
#3  fill_lines (num_traces=num_traces@entry=5,
    traces=traces@entry=0x7e845f394780 <trace>,
    check_debuglink=check_debuglink@entry=1, objp=objp@entry=0x7f7fff8b6478,
    lines=lines@entry=0x7e845f504f80, offset=offset@entry=0)
    at addr2line.c:2167
#4  0x00007e845f043bc1 in rb_dump_backtrace_with_lines (
    num_traces=<optimized out>, traces=traces@entry=0x7e845f394780 <trace>)
    at addr2line.c:2611
#5  0x00007e845f039670 in rb_print_backtrace () at vm_dump.c:787
#6  0x00007e845f03976c in rb_vm_bugreport (ctx=ctx@entry=0x0) at vm_dump.c:1080
#7  0x00007e845eeb2598 in rb_bug_for_fatal_signal (default_sighandler=0x0,
    sig=sig@entry=11, ctx=ctx@entry=0x0,
    fmt=fmt@entry=0x7e845f08a6ea "Segmentation fault") at error.c:813
#8  0x00007e845efb83b0 in sigsegv (sig=11) at signal.c:964
#9  0x00007e845d0a1da0 in _opendir (name=<optimized out>)
    at /usr/src/9/lib/libc/gen/opendir.c:72
#10 0x000000010000000b in ?? ()
#11 0x0000000000000000 in ?? ()

Digging into ruby32-base, I discovered that on NetBSD, and only on NetBSD, Ruby avoids sigaltstack for the SIGSEGV handler, and also avoids getting at the siginfo_t.  The ChangeLog suggests sigaltstack was disabled on NetBSD back in 2010, probably for the benefit of the ancient netbsd<=5 ABI where the pthread id was based on the stack pointer rather than stored in a thread-local storage register as it has been for a long time:

Mon Feb 15 17:42:20 2010  NARUSE, Yui  <naruse%ruby-lang.org@localhost>

        * signal.c (USE_SIGALTSTACK): NetBSD can't use sigaltstack(2)
          with pthread.
          http://netbsd.gw.com/cgi-bin/man-cgi?sigaltstack++NetBSD-current

The note about incompatibility of sigaltstack(2) with pthread was taken out of NetBSD's man page in 2012, some time after it became irrelevant with the introduction of thread-local storage support in netbsd-6.

I tried patching vm_core.h in ruby32-base to re-enable sigaltstack in order to get better diagnostics with the following patch:


$NetBSD$

Enable sigaltstack(2) again on NetBSD.  This has not been relevant for
a very long time, probably since NetBSD 6.

--- vm_core.h.orig	2024-10-30 09:47:11.000000000 +0000
+++ vm_core.h
@@ -148,7 +148,7 @@ extern int ruby_assert_critical_section_
 /* define to 0 to test old code path */
 #define WAITPID_USE_SIGCHLD (RUBY_SIGCHLD || SIGCHLD_LOSSY)
 
-#if defined(SIGSEGV) && defined(HAVE_SIGALTSTACK) && defined(SA_SIGINFO) && !defined(__NetBSD__)
+#if defined(SIGSEGV) && defined(HAVE_SIGALTSTACK) && defined(SA_SIGINFO)
 #  define USE_SIGALTSTACK
 void *rb_allocate_sigaltstack(void);
 void *rb_register_sigaltstack(void *);


When I did this, I was not able to get better diagnostics out of gdb...because asciidoctor just worked and didn't crash any more!  Tried both with and without ruby-yjit, worked either way.

I still don't know what provoked the original SIGSEGV.  But we should maybe just allow Ruby to use sigaltstack on NetBSD like it does on all the other platforms.
>How-To-Repeat:
try to use textproc/ruby-asciidoctor on netbsd-9, probably
>Fix:
1. patch away the `&& !defined(__NetBSD__)' condition on the use of sigaltstack in lang/ruby32-base
2. maybe do the same for lang/ruby31-base, lang/ruby33, lang/ruby34, and anything in wip
3. submit the patch upstream (maybe conditionalized on __NetBSD_Version__ being at least netbsd-6 if they care about really old NetBSD)



Home | Main Index | Thread Index | Old Index