ext/pf2/src/sample.rs in pf2-0.2.0 vs ext/pf2/src/sample.rs in pf2-0.3.0

- old
+ new

@@ -1,29 +1,50 @@ use std::time::Instant; use rb_sys::*; +use crate::backtrace::{Backtrace, BacktraceState}; + const MAX_STACK_DEPTH: usize = 500; +const MAX_C_STACK_DEPTH: usize = 1000; #[derive(Debug, PartialEq)] pub struct Sample { pub ruby_thread: VALUE, pub timestamp: Instant, pub line_count: i32, pub frames: [VALUE; MAX_STACK_DEPTH], pub linenos: [i32; MAX_STACK_DEPTH], + pub c_backtrace_pcs: [usize; MAX_C_STACK_DEPTH + 1], } impl Sample { // Nearly async-signal-safe // (rb_profile_thread_frames isn't defined as a-s-s) - pub fn capture(ruby_thread: VALUE) -> Self { + pub fn capture(ruby_thread: VALUE, backtrace_state: &BacktraceState) -> Self { + let mut c_backtrace_pcs = [0; MAX_C_STACK_DEPTH + 1]; + + Backtrace::backtrace_simple( + backtrace_state, + 0, + |pc: usize| -> i32 { + if c_backtrace_pcs[0] >= MAX_C_STACK_DEPTH { + return 1; + } + c_backtrace_pcs[0] += 1; + c_backtrace_pcs[c_backtrace_pcs[0]] = pc; + 0 + }, + Some(Backtrace::backtrace_error_callback), + ); + let mut sample = Sample { ruby_thread, timestamp: Instant::now(), line_count: 0, frames: [0; MAX_STACK_DEPTH], linenos: [0; MAX_STACK_DEPTH], + c_backtrace_pcs, }; unsafe { sample.line_count = rb_profile_thread_frames( ruby_thread, 0,