8000 Initialize interrupt queue before signal handlers by k0kubun · Pull Request #9196 · ruby/ruby · GitHub
[go: up one dir, main page]

Skip to content

Initialize interrupt queue before signal handlers #9196

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 12, 2023

Conversation

k0kubun
Copy link
Member
@k0kubun k0kubun commented Dec 12, 2023

As of a57186b, we got a few crashes in production like this:

(gdb) bt
#0  0x00005d25c885d6ab in rbimpl_rstring_getmem (str=0) at ./include/ruby/internal/core/rstring.h:393
#1  RSTRING_PTR (str=0) at ./include/ruby/internal/core/rstring.h:418
#2  oldbt_bugreport (arg=0x7b9f68534060, file=0, line=0, method=135924594111400) at vm_backtrace.c:1005
#3  0x00005d25c885da9a in oldbt_iter_cfunc (mid=<optimized out>, cfp=0x7b9f68f813d0, ptr=0x7b9f68534070) at vm_backtrace.c:963
#4  backtrace_each (ec=<optimized out>, arg=arg@entry=0x7b9f68534070, iter_cfunc=0x5d25c885d580 <oldbt_iter_cfunc>, iter_iseq=<optimized out>, init=0x5d25c885d370 <oldbt_init>) at vm_backtrace.c:922
#5  0x00005d25c885f16d in rb_backtrace_print_as_bugreport (fp=fp@entry=0x7b9f68539200) at vm_backtrace.c:1028
#6  0x00005d25c88617df in rb_vm_bugreport (ctx=ctx@entry=0x7b9f68534340, errout=errout@entry=0x7b9f68539200) at vm_dump.c:1134
#7  0x00005d25c8a1793c in rb_bug_for_fatal_signal (default_sighandler=0x0, sig=sig@entry=11, ctx=ctx@entry=0x7b9f68534340, fmt=fmt@entry=0x5d25c8a718bb "Segmentation fault at %p") at error.c:1065
#8  0x00005d25c87ae71d in sigsegv (sig=11, info=0x7b9f68534470, ctx=0x7b9f68534340) at signal.c:920
#9  <signal handler called>
#10 0x00005d25c8968474 in RB_FL_TEST_RAW (flags=8192, obj=0) at ./include/ruby/internal/fl_type.h:472
#11 RB_FL_ANY_RAW (flags=8192, obj=0) at ./include/ruby/internal/fl_type.h:520
#12 rb_array_len (a=0) at ./include/ruby/internal/core/rarray.h:259
#13 rb_ary_push (ary=0, item=135924155977880) at array.c:1337
#14 0x00005d25c87f9d6d in rb_threadptr_pending_interrupt_enque (v=<optimized out>, th=0x7b9f68e3b1c0) at thread.c:1874
#15 rb_threadptr_raise (argv=0x7fffd924f070, argc=2, target_th=0x7b9f68e3b1c0) at thread.c:2478
#16 rb_threadptr_signal_raise (th=<optimized out>, sig=<optimized out>) at thread.c:2490
#17 0x00005d25c87af925 in rb_signal_exec (th=th@entry=0x7b9f68e3b1c0, sig=<optimized out>) at signal.c:1079
#18 0x00005d25c87f0910 in rb_threadptr_execute_interrupts (th=<optimized out>, blocking_timing=0) at thread.c:2385
#19 0x00005d25c8848677 in rb_vm_check_ints (ec=0x7b9f68e7c2d0) at /tmp/ruby-build/ruby-3.3.0-a57186b9d1b0db3a88e5e9082347903b109f7d0e/vm_core.h:1899
#20 rb_vm_check_ints (ec=0x7b9f68e7c2d0) at /tmp/ruby-build/ruby-3.3.0-a57186b9d1b0db3a88e5e9082347903b109f7d0e/vm_core.h:2074
#21 vm_pop_frame (ep=<optimized out>, cfp=<optimized out>, ec=0x7b9f68e7c2d0) at /tmp/ruby-build/ruby-3.3.0-a57186b9d1b0db3a88e5e9082347903b109f7d0e/vm_insnhelper.c:419
#22 rb_vm_pop_frame (ec=0x7b9f68e7c2d0) at /tmp/ruby-build/ruby-3.3.0-a57186b9d1b0db3a88e5e9082347903b109f7d0e/vm_insnhelper.c:428
#23 vm_call0_cfunc_with_frame (argv=<optimized out>, calling=<optimized out>, ec=0x7b9f68e7c2d0) at /tmp/ruby-build/ruby-3.3.0-a57186b9d1b0db3a88e5e9082347903b109f7d0e/vm_eval.c:176
#24 vm_call0_cfunc (argv=<optimized out>, calling=<optimized out>, ec=0x7b9f68e7c2d0) at /tmp/ruby-build/ruby-3.3.0-a57186b9d1b0db3a88e5e9082347903b109f7d0e/vm_eval.c:187
#25 vm_call0_body (ec=0x7b9f68e7c2d0, calling=<optimized out>, argv=<optimized out>) at /tmp/ruby-build/ruby-3.3.0-a57186b9d1b0db3a88e5e9082347903b109f7d0e/vm_eval.c:233
#26 0x00005d25c8848918 in vm_call0_cc (ec=0x7b9f68e7c2d0, recv=135924155977960, id=<optimized out>, argc=<optimized out>, argv=<optimized out>, cc=<optimized out>, kw_splat=0) at /tmp/ruby-build/ruby-3.3.0-a57186b9d1b0db3a88e5e9082347903b109f7d0e/vm_eval.c:110
#27 0x00005d25c884aace in rb_call (scope=CALL_FCALL_KW, argv=0x1, argc=1, mid=3137, recv=135924155977960) at /tmp/ruby-build/ruby-3.3.0-a57186b9d1b0db3a88e5e9082347903b109f7d0e/vm_eval.c:895
#28 rb_funcallv_kw (recv=recv@entry=135924155977960, mid=mid@entry=3137, argc=argc@entry=1, argv=argv@entry=0x7fffd924f3a8, kw_splat=kw_splat@entry=0) at /tmp/ruby-build/ruby-3.3.0-a57186b9d1b0db3a88e5e9082347903b109f7d0e/vm_eval.c:1088
#29 0x00005d25c865807f in rb_obj_call_init_kw (obj=obj@entry=135924155977960, argc=argc@entry=1, argv=argv@entry=0x7fffd924f3a8, kw_splat=kw_splat@entry=0) at eval.c:1700
#30 0x00005d25c86fcb9e in rb_class_new_instance_kw (kw_splat=0, klass=135924593851680, argv=0x7fffd924f3a8, argc=1) at object.c:2142
#31 rb_class_new_instance (argc=argc@entry=1, argv=argv@entry=0x7fffd924f3a8, klass=klass@entry=135924593851680) at object.c:2150
#32 0x00005d25c8a17e70 in rb_exc_new_str (etype=etype@entry=135924593851680, str=<optimized out>) at error.c:1397
#33 0x00005d25c885b677 in rb_vm_register_special_exception_str (sp=sp@entry=ruby_error_stream_closed, cls=135924593851680, mesg=<optimized out>) at vm.c:2954
#34 0x00005d25c87fcd85 in Init_Thread () at thread.c:5380
#35 0x00005d25c8696224 in rb_call_inits () at inits.c:66
#36 0x00005d25c865682c in ruby_setup () at eval.c:89
#37 0x00005d25c86568ed in ruby_init () at eval.c:101
#38 0x00005d25c8651695 in rb_main (argv=0x7fffd924f658, argc=6) at ./main.c:38
#39 main (argc=<optimized out>, argv=<optimized out>) at ./main.c:58
(gdb) frame 14
#14 0x00005d25c87f9d6d in rb_threadptr_pending_interrupt_enque (v=<optimized out>, th=0x7b9f68e3b1c0) at thread.c:1874
warning: Source file is more recent than executable.
1874        rb_ary_push(th->pending_interrupt_queue, v);
(gdb) p th->pending_interrupt_queue
$1 = 0

Once signal handlers are installed, if the process is signaled and then reaches rb_vm_check_ints, it needs to use th->pending_interrupt_queue on rb_threadptr_pending_interrupt_enque. If that happens before Init_Thread, this becomes 0 and crashes.

So th->pending_interrupt_queue should be initialized before installing signal handlers.

@k0kubun k0kubun merged commit 9f0065a into ruby:master Dec 12, 2023
@k0kubun k0kubun deleted the interrupt-queue branch December 12, 2023 05:12
@nurse nurse mentioned this pull request Feb 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant
0