Skip to content

Commit 2a23159

Browse files
authored
Merge pull request #150 from jhawthorn/collect_frames_immediately
Collect stack frames immediately in Ruby 3.0
2 parents aa15f48 + 6c3f4d7 commit 2a23159

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

ext/stackprof/stackprof.c

+20-8
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@
2222
#define FAKE_FRAME_MARK INT2FIX(1)
2323
#define FAKE_FRAME_SWEEP INT2FIX(2)
2424

25+
/*
26+
* As of Ruby 3.0, it should be safe to read stack frames at any time
27+
* See https://github.com/ruby/ruby/commit/0e276dc458f94d9d79a0f7c7669bde84abe80f21
28+
*/
29+
#if RUBY_API_VERSION_MAJOR < 3
30+
#define USE_POSTPONED_JOB
31+
#endif
32+
2533
static const char *fake_frame_cstrs[] = {
2634
"(garbage collection)",
2735
"(marking)",
@@ -596,31 +604,30 @@ stackprof_record_gc_samples()
596604
static void
597605
stackprof_gc_job_handler(void *data)
598606
{
599-
static int in_signal_handler = 0;
600-
if (in_signal_handler) return;
601607
if (!_stackprof.running) return;
602608

603-
in_signal_handler++;
604609
stackprof_record_gc_samples();
605-
in_signal_handler--;
606610
}
607611

608612
static void
609613
stackprof_job_handler(void *data)
610614
{
611-
static int in_signal_handler = 0;
612-
if (in_signal_handler) return;
613615
if (!_stackprof.running) return;
614616

615-
in_signal_handler++;
616617
stackprof_record_sample();
617-
in_signal_handler--;
618618
}
619619

620620
static void
621621
stackprof_signal_handler(int sig, siginfo_t *sinfo, void *ucontext)
622622
{
623+
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
624+
623625
_stackprof.overall_signals++;
626+
627+
if (!_stackprof.running) return;
628+
if (!ruby_native_thread_p()) return;
629+
if (pthread_mutex_trylock(&lock)) return;
630+
624631
if (!_stackprof.ignore_gc && rb_during_gc()) {
625632
VALUE mode = rb_gc_latest_gc_info(sym_state);
626633
if (mode == sym_marking) {
@@ -631,8 +638,13 @@ stackprof_signal_handler(int sig, siginfo_t *sinfo, void *ucontext)
631638
_stackprof.unrecorded_gc_samples++;
632639
rb_postponed_job_register_one(0, stackprof_gc_job_handler, (void*)0);
633640
} else {
641+
#ifdef USE_POSTPONED_JOB
634642
rb_postponed_job_register_one(0, stackprof_job_handler, (void*)0);
643+
#else
644+
stackprof_job_handler(0);
645+
#endif
635646
}
647+
pthread_mutex_unlock(&lock);
636648
}
637649

638650
static void

0 commit comments

Comments
 (0)