Skip to content

Commit c4b6850

Browse files
[mq] [skip ddci] working branch - merge f1e7d11 on top of main at 0e8c2c6
{"baseBranch":"main","baseCommit":"0e8c2c6f7c7dc856784c559340c17cc7d53a4bd5","createdAt":"2026-03-13T11:27:58.157893Z","headSha":"f1e7d1110fd842c611de94f0eacb9f42868e0e9c","id":"503a1f47-40e4-4218-b9f6-d7efd8ce5934","nextMergeabilityCheckAt":"2026-03-13T13:16:01.053469Z","priority":"200","pullRequestNumber":"1705","queuedAt":"2026-03-13T12:16:06.193282Z","status":"STATUS_QUEUED"}
2 parents 965ee25 + f1e7d11 commit c4b6850

File tree

14 files changed

+564
-332
lines changed

14 files changed

+564
-332
lines changed

bin_tests/src/bin/crashing_test_app.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ mod unix {
1818
use std::sync::Arc;
1919
use std::time::Duration;
2020

21-
use libdd_common::{tag, Endpoint};
21+
use libdd_common::tag;
2222
use libdd_crashtracker::{
2323
self as crashtracker, CrashtrackerConfiguration, CrashtrackerReceiverConfig, Metadata,
2424
};
@@ -91,19 +91,17 @@ mod unix {
9191
let stdout_filename = format!("{output_dir}/out.stdout");
9292

9393
ensure!(!output_url.is_empty(), "output_url must not be empty");
94-
let endpoint = Some(Endpoint::from_slice(&output_url));
95-
96-
let config = CrashtrackerConfiguration::new(
97-
vec![], // additional_files
98-
true, // create_alt_stack
99-
true, // use_alt_stack
100-
endpoint,
101-
crashtracker::StacktraceCollection::EnabledWithSymbolsInReceiver,
102-
crashtracker::default_signals(),
103-
Some(TEST_COLLECTOR_TIMEOUT),
104-
Some("".to_string()), // unix_socket_path
105-
true, // demangle_names
106-
)?;
94+
95+
let config = CrashtrackerConfiguration::builder()
96+
.create_alt_stack(true)
97+
.use_alt_stack(true)
98+
.endpoint_url(&output_url)
99+
.resolve_frames(crashtracker::StacktraceCollection::EnabledWithSymbolsInReceiver)
100+
.signals(crashtracker::default_signals())
101+
.timeout(TEST_COLLECTOR_TIMEOUT)
102+
.unix_socket_path("".to_string())
103+
.demangle_names(true)
104+
.build()?;
107105

108106
let metadata = Metadata {
109107
library_name: "libdatadog".to_owned(),

bin_tests/src/bin/crashtracker_bin_test.rs

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ mod unix {
2222
use std::process;
2323
use std::time::Duration;
2424

25-
use libdd_common::{tag, Endpoint};
25+
use libdd_common::tag;
2626
use libdd_crashtracker::{
2727
self as crashtracker, CrashtrackerConfiguration, CrashtrackerReceiverConfig, Metadata,
2828
StackFrame, StackTrace,
@@ -73,12 +73,6 @@ mod unix {
7373
let stdout_filename = format!("{output_dir}/out.stdout");
7474
let output_dir: &Path = output_dir.as_ref();
7575

76-
let endpoint = if output_url.is_empty() {
77-
None
78-
} else {
79-
Some(Endpoint::from_slice(output_url))
80-
};
81-
8276
// The configuration can be modified by a Behavior (testing plan), so it is mut here.
8377
// Unlike a normal harness, in this harness tests are run in individual processes, so race
8478
// issues are avoided.
@@ -97,17 +91,16 @@ mod unix {
9791
Err(_) => crashtracker::StacktraceCollection::WithoutSymbols,
9892
};
9993

100-
let mut config = CrashtrackerConfiguration::new(
101-
vec![],
102-
true,
103-
true,
104-
endpoint,
105-
stacktrace_collection,
106-
crashtracker::default_signals(),
107-
Some(TEST_COLLECTOR_TIMEOUT),
108-
Some("".to_string()),
109-
true,
110-
)?;
94+
let mut config = CrashtrackerConfiguration::builder()
95+
.create_alt_stack(true)
96+
.demangle_names(true)
97+
.endpoint_url(output_url)
98+
.resolve_frames(stacktrace_collection)
99+
.signals(crashtracker::default_signals())
100+
.timeout(TEST_COLLECTOR_TIMEOUT)
101+
.unix_socket_path("".to_string())
102+
.use_alt_stack(true)
103+
.build()?;
111104

112105
let metadata = Metadata {
113106
library_name: "libdatadog".to_owned(),

bin_tests/tests/crashtracker_bin_test.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,23 +1331,23 @@ fn crash_tracking_empty_endpoint() {
13311331
#[cfg_attr(miri, ignore)]
13321332
#[cfg(unix)]
13331333
fn test_receiver_emits_debug_logs_on_receiver_issue() -> anyhow::Result<()> {
1334+
use std::time::Duration;
1335+
13341336
let receiver = artifacts::crashtracker_receiver(BuildProfile::Debug);
13351337
let artifacts = build_artifacts(&[&receiver])?;
13361338
let fixtures = bin_tests::test_runner::TestFixtures::new()?;
13371339

13381340
let missing_file = fixtures.output_dir.join("missing_additional_file.txt");
13391341

1340-
let config = CrashtrackerConfiguration::new(
1341-
vec![missing_file.display().to_string()],
1342-
true,
1343-
true,
1344-
None,
1345-
StacktraceCollection::WithoutSymbols,
1346-
libdd_crashtracker::default_signals(),
1347-
Some(std::time::Duration::from_millis(500)),
1348-
None,
1349-
true,
1350-
)?;
1342+
let config = CrashtrackerConfiguration::builder()
1343+
.additional_files(vec![missing_file.display().to_string()])
1344+
.create_alt_stack(true)
1345+
.demangle_names(true)
1346+
.resolve_frames(StacktraceCollection::WithoutSymbols)
1347+
.signals(libdd_crashtracker::default_signals())
1348+
.timeout(Duration::from_millis(500))
1349+
.use_alt_stack(true)
1350+
.build()?;
13511351

13521352
let metadata = Metadata {
13531353
library_name: "libdatadog".to_owned(),

datadog-sidecar/src/unix.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -220,18 +220,25 @@ fn init_crashtracker(dependency_paths: *const *const libc::c_char) -> anyhow::Re
220220
LogMethod::Disabled => None,
221221
};
222222

223+
let mut config_builder = CrashtrackerConfiguration::builder()
224+
.create_alt_stack(true)
225+
.use_alt_stack(true)
226+
.resolve_frames(StacktraceCollection::EnabledWithSymbolsInReceiver)
227+
.demangle_names(true);
228+
if let Some(ep) = Config::get().crashtracker_endpoint.as_ref() {
229+
config_builder = config_builder.endpoint_url(&ep.url.to_string());
230+
if let Some(api_key) = ep.api_key.as_deref() {
231+
config_builder = config_builder.endpoint_api_key(api_key);
232+
}
233+
config_builder = config_builder
234+
.endpoint_timeout_ms(ep.timeout_ms)
235+
.endpoint_use_system_resolver(ep.use_system_resolver);
236+
if let Some(test_token) = ep.test_token.as_deref() {
237+
config_builder = config_builder.endpoint_test_token(test_token);
238+
}
239+
}
223240
libdd_crashtracker::init(
224-
CrashtrackerConfiguration::new(
225-
vec![],
226-
true,
227-
true,
228-
Config::get().crashtracker_endpoint.clone(),
229-
StacktraceCollection::EnabledWithSymbolsInReceiver,
230-
vec![],
231-
None,
232-
None,
233-
true,
234-
)?,
241+
config_builder.build()?,
235242
CrashtrackerReceiverConfig::new(
236243
receiver_args,
237244
vec![],

examples/ffi/crashtracking.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <stdlib.h>
99
#include <string.h>
1010

11+
#define MAX_FILE_PATH 512
1112
#define INIT_FROM_SLICE(s) \
1213
{ .ptr = s.ptr, .len = s.len }
1314

@@ -51,10 +52,10 @@ int main(int argc, char **argv) {
5152
}
5253

5354
// Build output file paths
54-
char report_path[512];
55-
char stderr_path[512];
56-
char stdout_path[512];
57-
snprintf(report_path, sizeof(report_path), "%s/crashreport.json", output_dir);
55+
char report_path[MAX_FILE_PATH];
56+
char stderr_path[MAX_FILE_PATH];
57+
char stdout_path[MAX_FILE_PATH];
58+
snprintf(report_path, sizeof(report_path), "file://%s/crashreport.json", output_dir);
5859
snprintf(stderr_path, sizeof(stderr_path), "%s/stderr.txt", output_dir);
5960
snprintf(stdout_path, sizeof(stdout_path), "%s/stdout.txt", output_dir);
6061

@@ -82,13 +83,11 @@ int main(int argc, char **argv) {
8283
.optional_stdout_filename = slice(stdout_path),
8384
};
8485

85-
struct ddog_Endpoint *endpoint = ddog_endpoint_from_filename(slice(report_path));
86-
8786
// Get the default signals and explicitly use them.
8887
struct ddog_crasht_Slice_CInt signals = ddog_crasht_default_signals();
8988
ddog_crasht_Config config = {
9089
.create_alt_stack = false,
91-
.endpoint = endpoint,
90+
.endpoint = slice(report_path),
9291
.resolve_frames = DDOG_CRASHT_STACKTRACE_COLLECTION_ENABLED_WITH_INPROCESS_SYMBOLS,
9392
.signals = INIT_FROM_SLICE(signals),
9493
};
@@ -101,7 +100,6 @@ int main(int argc, char **argv) {
101100
};
102101

103102
handle_result(ddog_crasht_init(config, receiver_config, metadata));
104-
ddog_endpoint_drop(endpoint);
105103

106104
handle_result(ddog_crasht_begin_op(DDOG_CRASHT_OP_TYPES_PROFILER_COLLECTING_SAMPLE));
107105
handle_uintptr_t_result(ddog_crasht_insert_span_id(0, 42));

examples/ffi/crashtracking_unhandled_exception.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include <stdlib.h>
2121
#include <string.h>
2222

23+
#define MAX_FILE_PATH 512
24+
2325
static ddog_CharSlice slice(const char *s) {
2426
return (ddog_CharSlice){.ptr = s, .len = strlen(s)};
2527
}
@@ -110,13 +112,13 @@ int main(int argc, char **argv) {
110112
.env = env_slice,
111113
};
112114

113-
struct ddog_Endpoint *endpoint =
114-
ddog_endpoint_from_filename(slice(output_file));
115+
char endpoint[MAX_FILE_PATH];
116+
snprintf(endpoint, sizeof(endpoint), "file://%s", output_file);
115117

116118
struct ddog_crasht_Slice_CInt signals = ddog_crasht_default_signals();
117119
ddog_crasht_Config config = {
118120
.create_alt_stack = false,
119-
.endpoint = endpoint,
121+
.endpoint = slice(endpoint),
120122
.resolve_frames = DDOG_CRASHT_STACKTRACE_COLLECTION_DISABLED,
121123
.signals = {.ptr = signals.ptr, .len = signals.len},
122124
};
@@ -130,7 +132,6 @@ int main(int argc, char **argv) {
130132

131133
handle_void(ddog_crasht_init(config, receiver_config, metadata),
132134
"ddog_crasht_init");
133-
ddog_endpoint_drop(endpoint);
134135

135136
// Build a runtime StackTrace with two synthetic frames.
136137
ddog_crasht_StackTrace_NewResult tr = ddog_crasht_StackTrace_new();

libdd-crashtracker-ffi/src/collector/datatypes.rs

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright 2024-Present Datadog, Inc. https://www.datadoghq.com/
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use libdd_common::Endpoint;
54
use libdd_common_ffi::slice::{AsBytes, CharSlice};
65
use libdd_common_ffi::{Error, Slice};
76
pub use libdd_crashtracker::{OpTypes, StacktraceCollection};
@@ -61,7 +60,7 @@ pub struct Config<'a> {
6160
pub demangle_names: bool,
6261
/// The endpoint to send the crash report to (can be a file://).
6362
/// If None, the crashtracker will infer the agent host from env variables.
64-
pub endpoint: Option<&'a Endpoint>,
63+
pub endpoint: CharSlice<'a>,
6564
/// Optional filename for a unix domain socket if the receiver is used asynchonously
6665
pub optional_unix_socket_filename: CharSlice<'a>,
6766
pub resolve_frames: StacktraceCollection,
@@ -88,29 +87,23 @@ impl<'a> TryFrom<Config<'a>> for libdd_crashtracker::CrashtrackerConfiguration {
8887
}
8988
vec
9089
};
91-
let create_alt_stack = value.create_alt_stack;
92-
let use_alt_stack = value.use_alt_stack;
93-
let endpoint = value.endpoint.cloned();
94-
let resolve_frames = value.resolve_frames;
95-
let signals = value.signals.iter().copied().collect();
96-
let timeout = if value.timeout_ms == 0 {
97-
None
98-
} else {
99-
Some(Duration::from_millis(value.timeout_ms as u64))
100-
};
101-
let unix_socket_path = value.optional_unix_socket_filename.try_to_string_option()?;
102-
let demangle_names = value.demangle_names;
103-
Self::new(
104-
additional_files,
105-
create_alt_stack,
106-
use_alt_stack,
107-
endpoint,
108-
resolve_frames,
109-
signals,
110-
timeout,
111-
unix_socket_path,
112-
demangle_names,
113-
)
90+
let mut builder = Self::builder()
91+
.additional_files(additional_files)
92+
.create_alt_stack(value.create_alt_stack)
93+
.demangle_names(value.demangle_names)
94+
.resolve_frames(value.resolve_frames)
95+
.signals(value.signals.iter().copied().collect())
96+
.use_alt_stack(value.use_alt_stack);
97+
if let Some(url) = value.endpoint.try_to_string_option()? {
98+
builder = builder.endpoint_url(&url);
99+
}
100+
if value.timeout_ms != 0 {
101+
builder = builder.timeout(Duration::from_millis(value.timeout_ms as u64));
102+
}
103+
if let Some(path) = value.optional_unix_socket_filename.try_to_string_option()? {
104+
builder = builder.unix_socket_path(path);
105+
}
106+
builder.build()
114107
}
115108
}
116109

libdd-crashtracker/benches/receiver_bench.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,18 @@ fn add_proc_info(report: &mut String) {
3737
fn add_config(report: &mut String) {
3838
writeln!(report, "{DD_CRASHTRACK_BEGIN_CONFIG}")
3939
.expect("Failed to write DD_CRASHTRACK_BEGIN_CONFIG");
40-
let config = CrashtrackerConfiguration::new(
41-
vec![], // additional_files
42-
true, // create_alt_stack
43-
true, // use_alt_stack
44-
None,
45-
StacktraceCollection::EnabledWithSymbolsInReceiver,
46-
default_signals(),
47-
Some(Duration::from_secs(10)),
48-
Some("".to_string()), // unix_socket_path
49-
true, // demangle_names
50-
)
51-
.expect("Failed to create crashtracker configuration");
40+
41+
let config = CrashtrackerConfiguration::builder()
42+
.create_alt_stack(true)
43+
.use_alt_stack(true)
44+
.resolve_frames(StacktraceCollection::EnabledWithSymbolsInReceiver)
45+
.signals(default_signals())
46+
.timeout(Duration::from_secs(10))
47+
.unix_socket_path("".to_string())
48+
.demangle_names(true)
49+
.build()
50+
.expect("Failed to create crashtracker configuration");
51+
5252
let config_str =
5353
serde_json::to_string(&config).expect("Failed to serialize crashtracker configuration");
5454
writeln!(report, "{config_str}").expect("Failed to write crashtracker configuration");

0 commit comments

Comments
 (0)