Skip to content

Commit 53d7ff1

Browse files
committed
Remove need to register specific callback type, rather have specific callback registration functions
1 parent c419101 commit 53d7ff1

File tree

6 files changed

+168
-129
lines changed

6 files changed

+168
-129
lines changed

LICENSE-3rdparty.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
root_name: builder, build_common, tools, datadog-alloc, datadog-crashtracker, ddcommon, ddtelemetry, datadog-ddsketch, datadog-crashtracker-ffi, ddcommon-ffi, datadog-ffe, datadog-ipc, datadog-ipc-macros, tarpc, tarpc-plugins, tinybytes, spawn_worker, datadog-library-config, datadog-library-config-ffi, datadog-live-debugger, datadog-live-debugger-ffi, datadog-profiling, datadog-profiling-protobuf, datadog-profiling-ffi, data-pipeline-ffi, data-pipeline, datadog-trace-protobuf, datadog-trace-stats, datadog-trace-utils, datadog-trace-normalization, dogstatsd-client, datadog-log, datadog-log-ffi, ddsketch-ffi, ddtelemetry-ffi, symbolizer-ffi, datadog-profiling-replayer, datadog-remote-config, datadog-sidecar, datadog-sidecar-macros, datadog-sidecar-ffi, datadog-trace-obfuscation, datadog-tracer-flare, sidecar_mockgen, test_spawn_from_lib
1+
root_name: builder, build_common, tools, datadog-alloc, datadog-crashtracker, ddcommon, ddcommon-ffi, ddtelemetry, datadog-ddsketch, cc_utils, datadog-crashtracker-ffi, datadog-ffe, datadog-ipc, datadog-ipc-macros, tarpc, tarpc-plugins, tinybytes, spawn_worker, datadog-library-config, datadog-library-config-ffi, datadog-live-debugger, datadog-live-debugger-ffi, datadog-profiling, datadog-profiling-protobuf, datadog-profiling-ffi, data-pipeline-ffi, data-pipeline, datadog-trace-protobuf, datadog-trace-stats, datadog-trace-utils, datadog-trace-normalization, dogstatsd-client, datadog-log, datadog-log-ffi, ddsketch-ffi, ddtelemetry-ffi, symbolizer-ffi, datadog-profiling-replayer, datadog-remote-config, datadog-sidecar, datadog-sidecar-macros, datadog-sidecar-ffi, datadog-trace-obfuscation, datadog-tracer-flare, sidecar_mockgen, test_spawn_from_lib, bin_tests
22
third_party_libraries:
33
- package_name: addr2line
44
package_version: 0.24.2

bin_tests/src/modes/unix/test_010_runtime_callback_frame.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
// It registers a test callback that provides mock runtime stack frames,
66
// then crashes and verifies that the runtime frames appear in the crash report.
77
//
8-
// This test uses CallbackType::Frame to emit structured runtime stack data.
8+
// This test uses frame-by-frame callback to emit structured runtime stack data.
99

1010
use crate::modes::behavior::Behavior;
1111
use datadog_crashtracker::{
12-
clear_runtime_callback, register_runtime_stack_callback, CallbackType,
13-
CrashtrackerConfiguration, RuntimeStackFrame,
12+
clear_runtime_callback, register_runtime_frame_callback, CrashtrackerConfiguration,
13+
RuntimeStackFrame,
1414
};
1515
use ddcommon_ffi::CharSlice;
16-
use std::ffi::c_char;
1716
use std::path::Path;
1817

1918
pub struct Test;
@@ -32,7 +31,7 @@ impl Behavior for Test {
3231
unsafe {
3332
clear_runtime_callback();
3433
}
35-
register_runtime_stack_callback(test_runtime_callback_frame, CallbackType::Frame)
34+
register_runtime_frame_callback(test_runtime_callback_frame)
3635
.map_err(|e| anyhow::anyhow!("Failed to register runtime callback: {:?}", e))?;
3736
Ok(())
3837
}
@@ -45,7 +44,6 @@ impl Behavior for Test {
4544
// Signal-safe test callback that emits mock runtime stack frames
4645
unsafe extern "C" fn test_runtime_callback_frame(
4746
emit_frame: unsafe extern "C" fn(*const RuntimeStackFrame),
48-
_emit_stacktrace_string: unsafe extern "C" fn(*const c_char),
4947
) {
5048
static FUNCTION_NAME_1: &str = "test_module.TestClass.runtime_function_1";
5149
static FUNCTION_NAME_2: &str = "my_package.submodule.MyModule.runtime_function_2";
@@ -93,8 +91,7 @@ mod tests {
9391

9492
assert!(!is_runtime_callback_registered());
9593

96-
let result =
97-
register_runtime_stack_callback(test_runtime_callback_frame, CallbackType::Frame);
94+
let result = register_runtime_frame_callback(test_runtime_callback_frame);
9895
assert!(result.is_ok(), "Frame callback registration should succeed");
9996
assert!(
10097
is_runtime_callback_registered(),

bin_tests/src/modes/unix/test_011_runtime_callback_string.rs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,11 @@
55
// It registers a test callback that provides mock runtime stacktrace string,
66
// then crashes and verifies that the runtime stacktrace string appear in the crash report.
77
//
8-
// This test uses CallbackType::StacktraceString to emit structured runtime stack data.
8+
// This test uses stacktrace string callback to emit structured runtime stack data.
99

1010
use crate::modes::behavior::Behavior;
1111
use datadog_crashtracker::{
12-
clear_runtime_callback, register_runtime_stack_callback, CallbackType,
13-
CrashtrackerConfiguration, RuntimeStackFrame,
12+
clear_runtime_callback, register_runtime_stacktrace_string_callback, CrashtrackerConfiguration,
1413
};
1514
use std::ffi::c_char;
1615
use std::path::Path;
@@ -31,11 +30,8 @@ impl Behavior for Test {
3130
unsafe {
3231
clear_runtime_callback();
3332
}
34-
register_runtime_stack_callback(
35-
test_runtime_callback_string,
36-
CallbackType::StacktraceString,
37-
)
38-
.map_err(|e| anyhow::anyhow!("Failed to register runtime callback: {:?}", e))?;
33+
register_runtime_stacktrace_string_callback(test_runtime_callback_string)
34+
.map_err(|e| anyhow::anyhow!("Failed to register runtime callback: {:?}", e))?;
3935
Ok(())
4036
}
4137

@@ -46,7 +42,6 @@ impl Behavior for Test {
4642

4743
// Signal-safe test callback that emits mock runtime stacktrace string
4844
unsafe extern "C" fn test_runtime_callback_string(
49-
_emit_frame: unsafe extern "C" fn(*const RuntimeStackFrame),
5045
emit_stacktrace_string: unsafe extern "C" fn(*const c_char),
5146
) {
5247
static STACKTRACE_STRING: &[u8] = b"test_stacktrace_string\0";
@@ -66,10 +61,7 @@ mod tests {
6661

6762
assert!(!is_runtime_callback_registered());
6863

69-
let result = register_runtime_stack_callback(
70-
test_runtime_callback_string,
71-
CallbackType::StacktraceString,
72-
);
64+
let result = register_runtime_stacktrace_string_callback(test_runtime_callback_string);
7365
assert!(
7466
result.is_ok(),
7567
"String callback registration should succeed"

datadog-crashtracker-ffi/src/runtime_callback.rs

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@
55
//!
66
//! This module provides C-compatible FFI bindings for registering runtime-specific
77
//! crash callbacks that can provide stack traces for dynamic languages.
8+
#[cfg(unix)]
89
use datadog_crashtracker::{
910
get_registered_callback_type_ptr, is_runtime_callback_registered,
10-
register_runtime_stack_callback, CallbackError, CallbackType, RuntimeStackCallback,
11+
register_runtime_frame_callback, register_runtime_stacktrace_string_callback, CallbackError,
12+
RuntimeFrameCallback, RuntimeStacktraceStringCallback,
1113
};
1214

13-
// Re-export the enums for C/C++ consumers
14-
pub use datadog_crashtracker::CallbackType as ddog_CallbackType;
15-
1615
pub use datadog_crashtracker::RuntimeStackFrame as ddog_RuntimeStackFrame;
1716

1817
/// Result type for runtime callback registration
@@ -65,19 +64,43 @@ impl From<CallbackError> for CallbackResult {
6564
/// }
6665
///
6766
///
68-
/// ddog_CallbackResult result = ddog_crasht_register_runtime_stack_callback(
69-
/// my_runtime_callback,
70-
/// CallbackType::Frame,
67+
/// ddog_CallbackResult result = ddog_crasht_register_runtime_frame_callback(
68+
/// my_runtime_callback
7169
/// );
7270
/// ```
73-
/// Register a runtime stack collection callback using type-safe enums
71+
/// Register a runtime frame collection callback
72+
///
73+
/// This function allows language runtimes to register a callback that will be invoked
74+
/// during crash handling to collect runtime-specific stack frames.
75+
///
76+
/// # Arguments
77+
/// - `callback`: The callback function to invoke during crashes
78+
///
79+
/// # Returns
80+
/// - `CallbackResult::Ok` if registration succeeds (replaces any existing callback)
81+
/// - `CallbackResult::Error` if registration fails
82+
///
83+
/// # Safety
84+
/// - The callback must be signal-safe
85+
/// - Only one callback can be registered at a time (this replaces any existing one)
86+
#[cfg(unix)]
87+
#[no_mangle]
88+
pub unsafe extern "C" fn ddog_crasht_register_runtime_frame_callback(
89+
callback: RuntimeFrameCallback,
90+
) -> CallbackResult {
91+
match register_runtime_frame_callback(callback) {
92+
Ok(()) => CallbackResult::Ok,
93+
Err(e) => e.into(),
94+
}
95+
}
96+
97+
/// Register a runtime stacktrace string collection callback
7498
///
75-
/// This function provides compile-time safety by using enums instead of strings
76-
/// for runtime and callback types.
99+
/// This function allows language runtimes to register a callback that will be invoked
100+
/// during crash handling to collect runtime-specific stacktrace strings.
77101
///
78102
/// # Arguments
79103
/// - `callback`: The callback function to invoke during crashes
80-
/// - `callback_type`: Callback type enum (Frame, StacktraceString)
81104
///
82105
/// # Returns
83106
/// - `CallbackResult::Ok` if registration succeeds (replaces any existing callback)
@@ -86,12 +109,12 @@ impl From<CallbackError> for CallbackResult {
86109
/// # Safety
87110
/// - The callback must be signal-safe
88111
/// - Only one callback can be registered at a time (this replaces any existing one)
112+
#[cfg(unix)]
89113
#[no_mangle]
90-
pub unsafe extern "C" fn ddog_crasht_register_runtime_stack_callback(
91-
callback: RuntimeStackCallback,
92-
callback_type: CallbackType,
114+
pub unsafe extern "C" fn ddog_crasht_register_runtime_stacktrace_string_callback(
115+
callback: RuntimeStacktraceStringCallback,
93116
) -> CallbackResult {
94-
match register_runtime_stack_callback(callback, callback_type) {
117+
match register_runtime_stacktrace_string_callback(callback) {
95118
Ok(()) => CallbackResult::Ok,
96119
Err(e) => e.into(),
97120
}
@@ -103,6 +126,7 @@ pub unsafe extern "C" fn ddog_crasht_register_runtime_stack_callback(
103126
///
104127
/// # Safety
105128
/// This function is safe to call at any time
129+
#[cfg(unix)]
106130
#[no_mangle]
107131
pub extern "C" fn ddog_crasht_is_runtime_callback_registered() -> bool {
108132
is_runtime_callback_registered()
@@ -117,6 +141,7 @@ pub extern "C" fn ddog_crasht_is_runtime_callback_registered() -> bool {
117141
/// - The returned pointer is valid only while the callback remains registered
118142
/// - The caller should not free the returned pointer
119143
/// - The returned string should be copied if it needs to persist beyond callback lifetime
144+
#[cfg(unix)]
120145
#[no_mangle]
121146
pub unsafe extern "C" fn ddog_crasht_get_registered_callback_type() -> *const std::ffi::c_char {
122147
get_registered_callback_type_ptr()
@@ -134,9 +159,8 @@ mod tests {
134159
// with the global static variable
135160
static TEST_MUTEX: Mutex<()> = Mutex::new(());
136161

137-
unsafe extern "C" fn test_runtime_callback(
162+
unsafe extern "C" fn test_frame_callback(
138163
emit_frame: unsafe extern "C" fn(*const RuntimeStackFrame),
139-
_emit_stacktrace_string: unsafe extern "C" fn(*const c_char),
140164
) {
141165
let function_name = "TestModule.TestClass.test_function";
142166
let file_name = "test.rb";
@@ -151,6 +175,13 @@ mod tests {
151175
emit_frame(&frame);
152176
}
153177

178+
unsafe extern "C" fn test_stacktrace_string_callback(
179+
emit_stacktrace_string: unsafe extern "C" fn(*const c_char),
180+
) {
181+
let stacktrace_string = "test_stacktrace_string\0";
182+
emit_stacktrace_string(stacktrace_string.as_ptr() as *const c_char);
183+
}
184+
154185
#[test]
155186
fn test_callback_registration() {
156187
let _guard = TEST_MUTEX.lock().unwrap();
@@ -159,9 +190,8 @@ mod tests {
159190

160191
assert!(!ddog_crasht_is_runtime_callback_registered());
161192

162-
let result = ddog_crasht_register_runtime_stack_callback(
163-
test_runtime_callback,
164-
CallbackType::StacktraceString,
193+
let result = ddog_crasht_register_runtime_stacktrace_string_callback(
194+
test_stacktrace_string_callback,
165195
);
166196

167197
assert_eq!(result, CallbackResult::Ok);
@@ -174,10 +204,7 @@ mod tests {
174204
.unwrap();
175205
assert_eq!(callback_type_str, "stacktrace_string");
176206

177-
let result = ddog_crasht_register_runtime_stack_callback(
178-
test_runtime_callback,
179-
CallbackType::Frame,
180-
);
207+
let result = ddog_crasht_register_runtime_frame_callback(test_frame_callback);
181208

182209
assert_eq!(result, CallbackResult::Ok);
183210

datadog-crashtracker/src/collector/emitters.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use crate::collector::additional_tags::consume_and_emit_additional_tags;
55
use crate::collector::counters::emit_counters;
66
use crate::collector::spans::{emit_spans, emit_traces};
77
use crate::runtime_callback::{
8-
get_registered_callback_type_enum, invoke_runtime_callback_with_writer,
9-
is_runtime_callback_registered, CallbackType,
8+
get_registered_callback_type_internal, invoke_runtime_callback_with_writer,
9+
is_runtime_callback_registered,
1010
};
1111
use crate::shared::constants::*;
1212
use crate::{translate_si_code, CrashtrackerConfiguration, SignalNames, StacktraceCollection};
@@ -236,16 +236,17 @@ fn emit_ucontext(w: &mut impl Write, ucontext: *const ucontext_t) -> Result<(),
236236
/// callbacks and writing to the provided stream. The runtime callback itself
237237
/// must be signal safe.
238238
fn emit_runtime_stack(w: &mut impl Write) -> Result<(), EmitterError> {
239-
let callback_type = unsafe { get_registered_callback_type_enum() };
239+
let callback_type = unsafe { get_registered_callback_type_internal() };
240240

241241
let callback_type = match callback_type {
242242
Some(ct) => ct,
243243
None => return Ok(()), // No callback registered
244244
};
245245

246246
match callback_type {
247-
CallbackType::Frame => emit_runtime_stack_by_frames(w),
248-
CallbackType::StacktraceString => emit_runtime_stack_by_stacktrace_string(w),
247+
"frame" => emit_runtime_stack_by_frames(w),
248+
"stacktrace_string" => emit_runtime_stack_by_stacktrace_string(w),
249+
_ => Ok(()), // Unknown callback type
249250
}
250251
}
251252

0 commit comments

Comments
 (0)