Skip to content

Commit cdbfa06

Browse files
authored
Merge branch 'main' into gyuheon0h/alpine-x86_64-dev-container
2 parents d76a2a5 + c89b6df commit cdbfa06

23 files changed

Lines changed: 854 additions & 48 deletions
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
issuer: https://gitlab.ddbuild.io
2+
3+
subject_pattern: "project_path:DataDog/.*"
4+
5+
claim_pattern:
6+
project_id: "2260"
7+
ref: "refs/heads/(main|release|igor/versioning/.*)" # TODO: remove testing branch and uncomment ref_protected
8+
# ref_protected: "true"
9+
10+
permissions:
11+
contents: write

bin_tests/tests/crashtracker_bin_test.rs

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,40 @@ fn test_crash_tracking_bin_runtime_callback_frame() {
125125
run_crash_test_with_artifacts(&config, &artifacts_map, &artifacts, validator).unwrap();
126126
}
127127

128+
#[test]
129+
#[cfg(target_os = "linux")]
130+
#[cfg_attr(miri, ignore)]
131+
fn test_crash_tracking_thread_name() {
132+
let config = CrashTestConfig::new(
133+
BuildProfile::Release,
134+
TestMode::DoNothing,
135+
CrashType::NullDeref,
136+
);
137+
let artifacts = StandardArtifacts::new(config.profile);
138+
let artifacts_map = build_artifacts(&artifacts.as_slice()).unwrap();
139+
140+
let validator: ValidatorFn = Box::new(|payload, _fixtures| {
141+
let error = &payload["error"];
142+
let thread_name = error["thread_name"]
143+
.as_str()
144+
.expect("thread_name should be present");
145+
assert!(
146+
!thread_name.trim().is_empty(),
147+
"thread_name should not be empty: {thread_name:?}"
148+
);
149+
assert!(
150+
// Cutting `crashtracker_bin_test` to `crashtracker_bin` because linux
151+
// thread name is limited to 15 characters
152+
thread_name.contains("crashtracker_bi"),
153+
"thread_name should contain binary name: {thread_name:?}"
154+
);
155+
156+
Ok(())
157+
});
158+
159+
run_crash_test_with_artifacts(&config, &artifacts_map, &artifacts, validator).unwrap();
160+
}
161+
128162
#[test]
129163
#[cfg_attr(miri, ignore)]
130164
fn test_crash_tracking_bin_runtime_callback_string() {
@@ -1045,17 +1079,20 @@ fn assert_telemetry_message(crash_telemetry: &[u8], crash_typ: &str) {
10451079
let tags = tags_raw
10461080
.split(',')
10471081
.filter(|t| !t.starts_with("uuid:"))
1082+
.map(|t| t.to_string())
10481083
.collect::<std::collections::HashSet<_>>();
10491084

1050-
let base_expected_tags: std::collections::HashSet<&str> =
1085+
let current_schema_version = libdd_crashtracker::CrashInfo::current_schema_version();
1086+
1087+
let base_expected_tags: std::collections::HashSet<String> =
10511088
std::collections::HashSet::from_iter([
1052-
"data_schema_version:1.4",
1089+
format!("data_schema_version:{current_schema_version}"),
10531090
// "incomplete:false", // TODO: re-add after fixing musl unwinding
1054-
"is_crash:true",
1055-
"profiler_collecting_sample:1",
1056-
"profiler_inactive:0",
1057-
"profiler_serializing:0",
1058-
"profiler_unwinding:0",
1091+
"is_crash:true".to_string(),
1092+
"profiler_collecting_sample:1".to_string(),
1093+
"profiler_inactive:0".to_string(),
1094+
"profiler_serializing:0".to_string(),
1095+
"profiler_unwinding:0".to_string(),
10591096
]);
10601097

10611098
match crash_typ {

builder/src/arch/apple.rs

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

4+
use std::ffi::OsStr;
45
use std::os::unix::process::ExitStatusExt;
56
use std::process::Command;
67

7-
use std::ffi::OsStr;
8+
use crate::utils::wait_for_success;
89

910
pub const NATIVE_LIBS: &str =
1011
" -framework Security -framework CoreFoundation -liconv -lSystem -lresolv -lc -lm -liconv";
@@ -43,13 +44,13 @@ pub fn fix_rpath(lib_path: &str) {
4344

4445
pub fn strip_libraries(lib_path: &str) {
4546
// objcopy is not available in macos image. Investigate llvm-objcopy
46-
let mut strip = Command::new("strip")
47+
let strip = Command::new("strip")
4748
.arg("-S")
4849
.arg(lib_path.to_owned() + "/libdatadog_profiling.dylib")
4950
.spawn()
5051
.expect("Failed to spawn strip");
5152

52-
strip.wait().expect("Failed to strip library");
53+
wait_for_success(strip, "strip");
5354
}
5455

5556
pub fn add_additional_files(_lib_path: &str, _target_path: &OsStr) {}

builder/src/arch/linux.rs

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

4+
use std::ffi::OsStr;
45
use std::process::Command;
56

6-
use std::ffi::OsStr;
7+
use crate::utils::wait_for_success;
78

89
pub const NATIVE_LIBS: &str = " -ldl -lrt -lpthread -lc -lm -lrt -lpthread -lutil -ldl -lutil";
910
pub const PROF_DYNAMIC_LIB: &str = "libdatadog_profiling.so";
@@ -21,50 +22,50 @@ pub const RUSTFLAGS: [&str; 4] = [
2122

2223
pub fn fix_rpath(lib_path: &str) {
2324
if REMOVE_RPATH {
24-
let mut patchelf = Command::new("patchelf")
25+
let patchelf = Command::new("patchelf")
2526
.arg("--remove-rpath")
2627
.arg(lib_path)
2728
.spawn()
2829
.expect("failed to spawn patchelf");
2930

30-
patchelf.wait().expect("failed to remove rpath");
31+
wait_for_success(patchelf, "patchelf");
3132
}
3233
}
3334

3435
pub fn strip_libraries(lib_path: &str) {
35-
let mut rm_section = Command::new("objcopy")
36+
let rm_section = Command::new("objcopy")
3637
.arg("--remove-section")
3738
.arg(".llvmbc")
3839
.arg(lib_path.to_owned() + "/libdatadog_profiling.a")
3940
.spawn()
4041
.expect("failed to spawn objcopy");
4142

42-
rm_section.wait().expect("Failed to remove llvmbc section");
43+
wait_for_success(rm_section, "objcopy (remove llvmbc section)");
4344

44-
let mut create_debug = Command::new("objcopy")
45+
let create_debug = Command::new("objcopy")
4546
.arg("--only-keep-debug")
4647
.arg(lib_path.to_owned() + "/libdatadog_profiling.so")
4748
.arg(lib_path.to_owned() + "/libdatadog_profiling.debug")
4849
.spawn()
4950
.expect("Failed to spawn objcopy");
5051

51-
create_debug.wait().expect("Failed to extract debug info");
52+
wait_for_success(create_debug, "objcopy (extract debug info)");
5253

53-
let mut strip = Command::new("strip")
54+
let strip = Command::new("strip")
5455
.arg("-S")
5556
.arg(lib_path.to_owned() + "/libdatadog_profiling.so")
5657
.spawn()
5758
.expect("Failed to spawn strip");
5859

59-
strip.wait().expect("Failed to strip library");
60+
wait_for_success(strip, "strip");
6061

61-
let mut debug = Command::new("objcopy")
62+
let debug = Command::new("objcopy")
6263
.arg("--add-gnu-debuglink=".to_string() + lib_path + "/libdatadog_profiling.debug")
6364
.arg(lib_path.to_owned() + "/libdatadog_profiling.so")
6465
.spawn()
6566
.expect("Failed to spawn objcopy");
6667

67-
debug.wait().expect("Failed to set debuglink");
68+
wait_for_success(debug, "objcopy (set debuglink)");
6869
}
6970

7071
pub fn add_additional_files(_lib_path: &str, _target_path: &OsStr) {}

builder/src/arch/musl.rs

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

4+
use std::ffi::OsStr;
45
use std::process::Command;
56

6-
use std::ffi::OsStr;
7+
use crate::utils::wait_for_success;
78

89
pub const NATIVE_LIBS: &str = " -lssp_nonshared -lc";
910
pub const PROF_DYNAMIC_LIB: &str = "libdatadog_profiling.so";
@@ -30,39 +31,39 @@ pub fn fix_rpath(lib_path: &str) {
3031
}
3132

3233
pub fn strip_libraries(lib_path: &str) {
33-
let mut rm_section = Command::new("objcopy")
34+
let rm_section = Command::new("objcopy")
3435
.arg("--remove-section")
3536
.arg(".llvmbc")
3637
.arg(lib_path.to_owned() + "/libdatadog_profiling.a")
3738
.spawn()
3839
.expect("failed to spawn objcopy");
3940

40-
rm_section.wait().expect("Failed to remove llvmbc section");
41+
wait_for_success(rm_section, "objcopy (remove llvmbc section)");
4142

42-
let mut create_debug = Command::new("objcopy")
43+
let create_debug = Command::new("objcopy")
4344
.arg("--only-keep-debug")
4445
.arg(lib_path.to_owned() + "/libdatadog_profiling.so")
4546
.arg(lib_path.to_owned() + "/libdatadog_profiling.debug")
4647
.spawn()
4748
.expect("Failed to spawn objcopy");
4849

49-
create_debug.wait().expect("Failed to extract debug info");
50+
wait_for_success(create_debug, "objcopy (extract debug info)");
5051

51-
let mut strip = Command::new("strip")
52+
let strip = Command::new("strip")
5253
.arg("-s")
5354
.arg(lib_path.to_owned() + "/libdatadog_profiling.so")
5455
.spawn()
5556
.expect("Failed to spawn strip");
5657

57-
strip.wait().expect("Failed to strip library");
58+
wait_for_success(strip, "strip");
5859

59-
let mut debug = Command::new("objcopy")
60+
let debug = Command::new("objcopy")
6061
.arg("--add-gnu-debuglink=".to_string() + lib_path + "/libdatadog_profiling.debug")
6162
.arg(lib_path.to_owned() + "/libdatadog_profiling.so")
6263
.spawn()
6364
.expect("Failed to spawn objcopy");
6465

65-
debug.wait().expect("Failed to set debuglink");
66+
wait_for_success(debug, "objcopy (set debuglink)");
6667
}
6768

6869
pub fn add_additional_files(_lib_path: &str, _target_path: &OsStr) {}

builder/src/common.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
use crate::arch;
55
use crate::module::Module;
6-
use crate::utils::project_root;
6+
use crate::utils::{project_root, wait_for_success};
77
use anyhow::Result;
88
use std::fs;
99
use std::path::PathBuf;
@@ -18,7 +18,7 @@ pub struct Common {
1818

1919
impl Module for Common {
2020
fn build(&self) -> Result<()> {
21-
let mut cargo = Command::new("cargo")
21+
let cargo = Command::new("cargo")
2222
.env("RUSTFLAGS", arch::RUSTFLAGS.join(" "))
2323
.current_dir(project_root())
2424
.args([
@@ -33,7 +33,7 @@ impl Module for Common {
3333
.spawn()
3434
.expect("failed to spawn cargo");
3535

36-
cargo.wait().expect("Cargo failed");
36+
wait_for_success(cargo, "Cargo");
3737
Ok(())
3838
}
3939

builder/src/profiling.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
use crate::arch;
55
use crate::module::Module;
6-
use crate::utils::{file_replace, project_root};
6+
use crate::utils::{file_replace, project_root, wait_for_success};
77
use anyhow::Result;
88
use serde::Deserialize;
99
use std::ffi::OsStr;
@@ -196,14 +196,14 @@ impl Module for Profiling {
196196
let mut args = cargo_args.clone();
197197
args.append(&mut vec!["--crate-type", crate_type]);
198198

199-
let mut cargo = Command::new("cargo")
199+
let cargo = Command::new("cargo")
200200
.env("RUSTFLAGS", arch::RUSTFLAGS.join(" "))
201201
.current_dir(project_root())
202202
.args(args)
203203
.spawn()
204204
.expect("failed to spawn cargo");
205205

206-
cargo.wait().expect("Cargo failed");
206+
wait_for_success(cargo, "Cargo");
207207
}
208208

209209
Ok(())

builder/src/utils.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use anyhow::{anyhow, Result};
55
use std::fs::{self, OpenOptions};
66
use std::io::Write;
77
use std::path::{Path, PathBuf};
8+
use std::process::Child;
89

910
pub fn file_replace(file_in: &str, file_out: &str, target: &str, replace: &str) -> Result<()> {
1011
let content = fs::read_to_string(file_in)?;
@@ -26,3 +27,15 @@ pub fn project_root() -> PathBuf {
2627
.unwrap()
2728
.to_path_buf()
2829
}
30+
31+
/// Waits for a child process to complete and panics if it fails.
32+
pub fn wait_for_success(mut child: Child, name: &str) {
33+
let status = child
34+
.wait()
35+
.unwrap_or_else(|_| panic!("{name} failed to wait"));
36+
assert!(
37+
status.success(),
38+
"{name} failed with exit code: {:?}",
39+
status.code()
40+
);
41+
}

docs/RFCs/0011-crashtracker-structured-log-format-V1_X.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ Consumers of the crash data format SHOULD be designed to handle all versions fro
7878
- `stack`: **[required]**
7979
This represents the stack of the crashing thread.
8080
See below for more details on how stacktraces are formatted.
81+
- `thread_name`: **[optional]**
82+
Name of the crashing thread
8183
- `files`: **[optional]**
8284
A `Map<filename, contents>` where `contents` is an array of plain text strings, one per line.
8385
Useful files for triage and debugging, such as `/proc/self/maps` or `/proc/meminfo`.
@@ -273,6 +275,15 @@ This section documents the evolution of the crashtracker structured log format a
273275

274276
**Motivation:** When symbol names are demangled for readability, the original mangled names are lost. This makes debugging difficult when mangled names are needed (e.g., comparing against compiler-generated symbols). The `mangled_name` field preserves the original mangled name when demangling occurs.
275277

278+
### Version 1.5
279+
*Added thread_name to `ErrorData`
280+
281+
**Changes from v1.4:**
282+
- Added `thread_name` field to `Error` objects (optional string)
283+
- Updated `data_schema_version` to "1.5"
284+
285+
**Motivation:** Having access to thread name of the crashing thread helps debugging, especially within multithreaded programs.
286+
276287
## Appendix A: Example output
277288

278289
An example crash report in version 1.0 format is [available here](artifacts/0005-crashtracker-example.json).
@@ -281,7 +292,7 @@ Note: This example uses version 1.0 format. Version 1.1+ may include additional
281292

282293
## Appendix B: Json Schema
283294

284-
The current JSON schema (version 1.4) is [available here](artifacts/0009-crashtracker-schema.json).
295+
The current JSON schema (version 1.5) is [available here](artifacts/crashtracker-unified-runtime-stack-schema-v1_5.json).
285296

286297
Historical schemas are also available:
287298
- [Version 1.0 schema](artifacts/0005-crashtracker-schema.json)

0 commit comments

Comments
 (0)