Skip to content

Commit 455d76a

Browse files
committed
Check that VM is running in sigaction
1 parent 52d1df6 commit 455d76a

File tree

1 file changed

+16
-0
lines changed

1 file changed

+16
-0
lines changed

ext/stackprof/stackprof.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <ruby/st.h>
1313
#include <ruby/io.h>
1414
#include <ruby/intern.h>
15+
#include <ruby/vm.h>
1516
#include <signal.h>
1617
#include <sys/time.h>
1718
#include <time.h>
@@ -32,6 +33,7 @@ static const char *fake_frame_cstrs[] = {
3233
};
3334

3435
static int stackprof_use_postponed_job = 1;
36+
static int ruby_vm_running = 0;
3537

3638
#define TOTAL_FAKE_FRAMES (sizeof(fake_frame_cstrs) / sizeof(char *))
3739

@@ -725,6 +727,11 @@ stackprof_signal_handler(int sig, siginfo_t *sinfo, void *ucontext)
725727

726728
if (!_stackprof.running) return;
727729

730+
// There's a possibility that the signal handler is invoked *after* the Ruby
731+
// VM has been shut down (e.g. after ruby_cleanup(0)). In this case, things
732+
// that rely on global VM state (e.g. rb_during_gc) will segfault.
733+
if (!ruby_vm_running) return;
734+
728735
if (_stackprof.mode == sym_wall) {
729736
// In "wall" mode, the SIGALRM signal will arrive at an arbitrary thread.
730737
// In order to provide more useful results, especially under threaded web
@@ -845,6 +852,12 @@ stackprof_use_postponed_job_l(VALUE self)
845852
return Qnil;
846853
}
847854

855+
static void
856+
stackprof_at_exit(ruby_vm_t* vm)
857+
{
858+
ruby_vm_running = 0;
859+
}
860+
848861
void
849862
Init_stackprof(void)
850863
{
@@ -855,6 +868,9 @@ Init_stackprof(void)
855868
*/
856869
stackprof_use_postponed_job = RUBY_API_VERSION_MAJOR < 3;
857870

871+
ruby_vm_running = 1;
872+
ruby_vm_at_exit(stackprof_at_exit);
873+
858874
#define S(name) sym_##name = ID2SYM(rb_intern(#name));
859875
S(object);
860876
S(custom);

0 commit comments

Comments
 (0)