-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Export crashes through telemetry #285
Merged
Merged
Changes from 18 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
636dc99
Export crashes through telemetry
paullegranddc 78761a8
Make bin_test work with the crashtracker in library
paullegranddc a8bf45f
Merge branch 'main' into paullgdc/upload_crashes_to_telemetry
paullegranddc 47c7f68
Fix tests in some env
paullegranddc 4a3c49e
Fix windows tests
paullegranddc bea6edc
Skip bin tests on windows
paullegranddc 744a866
Log stderr if test fails
paullegranddc 71a39b1
adress PR comments
paullegranddc cf9c813
Do not resolve frames
paullegranddc 0de580f
Remove import
paullegranddc 5d5315e
Fix tests on alpine
paullegranddc 8807029
Add context to crashtracker tests
paullegranddc ae7ac10
fmt
paullegranddc 9039866
Add assertion on sdout
paullegranddc 24cd340
Merge branch 'main' into paullgdc/upload_crashes_to_telemetry
paullegranddc 8729a24
Merge branch 'main' into paullgdc/upload_crashes_to_telemetry
paullegranddc 1b61275
send telemetry on partial crash data
paullegranddc acddc38
update license-3rdparty.yml
paullegranddc f94d5c5
complete comment
paullegranddc File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. | ||
# This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2021-Present Datadog, Inc. | ||
|
||
[package] | ||
name = "bin_tests" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
once_cell = "1.18" | ||
anyhow = "1.0" | ||
current_platform = "0.2.0" | ||
datadog-profiling = { path = "../profiling" } | ||
datadog-crashtracker = { path = "../crashtracker" } | ||
ddcommon = { path = "../ddcommon" } | ||
tempfile = "3.3" | ||
serde_json = { version = "1.0" } | ||
hyper = { version = "0.14", default-features = false } | ||
|
||
[[bin]] | ||
name = "crashtracker_bin_test" | ||
|
||
[[bin]] | ||
name = "test_the_tests" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. | ||
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2023-Present Datadog, Inc. | ||
|
||
#[cfg(not(unix))] | ||
fn main() {} | ||
|
||
#[cfg(unix)] | ||
fn main() -> anyhow::Result<()> { | ||
unix::main() | ||
} | ||
|
||
#[cfg(unix)] | ||
mod unix { | ||
use anyhow::Context; | ||
use std::env; | ||
|
||
use datadog_crashtracker::{ | ||
self as crashtracker, CrashtrackerConfiguration, CrashtrackerMetadata, | ||
}; | ||
use datadog_profiling::exporter::Tag; | ||
|
||
#[inline(never)] | ||
unsafe fn deref_ptr(p: *mut u8) { | ||
*std::hint::black_box(p) = std::hint::black_box(1); | ||
} | ||
|
||
pub fn main() -> anyhow::Result<()> { | ||
let mut args = env::args().skip(1); | ||
let output_filename = args.next().context("Unexpected number of arguments")?; | ||
let receiver_binary = args.next().context("Unexpected number of arguments")?; | ||
let stderr_filename = args.next().context("Unexpected number of arguments")?; | ||
let stdout_filename = args.next().context("Unexpected number of arguments")?; | ||
crashtracker::init( | ||
CrashtrackerConfiguration { | ||
create_alt_stack: true, | ||
endpoint: Some(datadog_profiling::exporter::Endpoint { | ||
url: ddcommon::parse_uri(&format!("file://{}", output_filename))?, | ||
api_key: None, | ||
}), | ||
path_to_receiver_binary: receiver_binary, | ||
resolve_frames: crashtracker::CrashtrackerResolveFrames::Never, | ||
stderr_filename: Some(stderr_filename), | ||
stdout_filename: Some(stdout_filename), | ||
collect_stacktrace: true, | ||
}, | ||
CrashtrackerMetadata { | ||
profiling_library_name: "libdatadog".to_owned(), | ||
profiling_library_version: "1.0.0".to_owned(), | ||
family: "native".to_owned(), | ||
tags: vec![ | ||
Tag::new("service", "foo").unwrap(), | ||
Tag::new("service_version", "bar").unwrap(), | ||
Tag::new("runtime-id", "xyz").unwrap(), | ||
Tag::new("language", "native").unwrap(), | ||
], | ||
}, | ||
)?; | ||
crashtracker::begin_profiling_op(crashtracker::ProfilingOpTypes::CollectingSample)?; | ||
unsafe { | ||
deref_ptr(std::ptr::null_mut::<u8>()); | ||
} | ||
crashtracker::end_profiling_op(crashtracker::ProfilingOpTypes::CollectingSample)?; | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. | ||
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2023-Present Datadog, Inc. | ||
|
||
#[cfg(not(unix))] | ||
fn main() {} | ||
|
||
#[cfg(unix)] | ||
fn main() -> anyhow::Result<()> { | ||
datadog_crashtracker::receiver_entry_point() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. | ||
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2023-Present Datadog, Inc. | ||
|
||
/// This is an empty binary used to test the machinery of building bins | ||
/// in cargo test works | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0. | ||
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2023-Present Datadog, Inc. | ||
|
||
use std::{collections::HashMap, env, ops::DerefMut, path::PathBuf, process, sync::Mutex}; | ||
|
||
use anyhow::Ok; | ||
use once_cell::sync::OnceCell; | ||
|
||
/// This crate implements an abstraction over compilation with cargo with the purpose | ||
/// of testing full binaries or dynamic libraries, instead if just rust static libraries. | ||
/// | ||
/// The main entrypoint is `fn build_artifacts` which takes a list of artifacts to build, | ||
/// either executable crates, cdylib, or extra binaries, invokes cargo and return the path | ||
/// of the built artifact. | ||
/// | ||
/// Builds are cached between invocations so that multiple tests can use the same artifact | ||
/// without doing expensive work twice. | ||
/// | ||
/// It is assumed that functions in this crate are invoked in the context of a cargo #[test] | ||
/// item, or a `cargo run` command to be able to locate artifacts built by cargo from the position | ||
/// of the current binary. | ||
|
||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] | ||
pub enum ArtifactType { | ||
ExecutablePackage, | ||
CDylib, | ||
Bin, | ||
} | ||
|
||
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] | ||
pub enum BuildProfile { | ||
Debug, | ||
Release, | ||
} | ||
|
||
#[derive(Debug, PartialEq, Eq, Hash, Clone)] | ||
pub struct ArtifactsBuild { | ||
pub name: String, | ||
pub artifact_type: ArtifactType, | ||
pub build_profile: BuildProfile, | ||
pub triple_target: Option<String>, | ||
} | ||
|
||
fn inner_build_artifact(c: &ArtifactsBuild) -> anyhow::Result<PathBuf> { | ||
let mut build_cmd = process::Command::new(env!("CARGO")); | ||
build_cmd.arg("build"); | ||
if let BuildProfile::Release = c.build_profile { | ||
build_cmd.arg("--release"); | ||
} | ||
match c.artifact_type { | ||
ArtifactType::ExecutablePackage | ArtifactType::CDylib => build_cmd.arg("-p"), | ||
ArtifactType::Bin => build_cmd.arg("--bin"), | ||
}; | ||
build_cmd.arg(&c.name); | ||
|
||
let output = build_cmd.output().unwrap(); | ||
if !output.status.success() { | ||
anyhow::bail!( | ||
"Cargo build failed: status code {:?}\nstderr:\n {}", | ||
output.status.code(), | ||
String::from_utf8_lossy(&output.stderr) | ||
); | ||
} | ||
|
||
/// This static variable contains the path in which cargo puts it's build artifacts | ||
/// This relies on the assumption that the current binary is assumed to not have been moved from it's directory | ||
static ARTIFACT_DIR: OnceCell<PathBuf> = OnceCell::new(); | ||
let artifact_dir = ARTIFACT_DIR.get_or_init(|| { | ||
let test_bin_location = PathBuf::from(env::args().next().unwrap()); | ||
let mut location_components = test_bin_location.components().rev().peekable(); | ||
loop { | ||
let Some(c) = location_components.peek() else { | ||
break; | ||
}; | ||
if c.as_os_str() == "target" { | ||
break; | ||
} | ||
location_components.next(); | ||
} | ||
location_components.rev().collect::<PathBuf>() | ||
}); | ||
|
||
let mut artifact_path = artifact_dir.clone(); | ||
artifact_path.push(match c.build_profile { | ||
BuildProfile::Debug => "debug", | ||
BuildProfile::Release => "release", | ||
}); | ||
|
||
match c.artifact_type { | ||
ArtifactType::ExecutablePackage | ArtifactType::Bin => artifact_path.push(&c.name), | ||
ArtifactType::CDylib => { | ||
let name = "lib".to_owned() | ||
+ &c.name.replace('-', "_") | ||
+ "." | ||
+ shared_lib_extension( | ||
c.triple_target | ||
.as_deref() | ||
.unwrap_or(current_platform::CURRENT_PLATFORM), | ||
)?; | ||
artifact_path.push(name); | ||
} | ||
}; | ||
Ok(artifact_path) | ||
} | ||
|
||
/// Caches and returns the path of the artifacts built by cargo | ||
/// This function should only be called from cargo tests | ||
pub fn build_artifacts<'b>( | ||
crates: &[&'b ArtifactsBuild], | ||
) -> anyhow::Result<HashMap<&'b ArtifactsBuild, PathBuf>> { | ||
static ARTIFACTS: OnceCell<Mutex<HashMap<ArtifactsBuild, PathBuf>>> = OnceCell::new(); | ||
|
||
let mut res = HashMap::new(); | ||
|
||
let artifacts = ARTIFACTS.get_or_init(|| Mutex::new(HashMap::new())); | ||
for &c in crates { | ||
let mut artifacts = artifacts.lock().unwrap(); | ||
let artifacts = artifacts.deref_mut(); | ||
|
||
if artifacts.contains_key(c) { | ||
res.insert(c, artifacts.get(c).unwrap().clone()); | ||
} else { | ||
let p = inner_build_artifact(c)?; | ||
res.insert(c, p.clone()); | ||
artifacts.insert(c.clone(), p); | ||
} | ||
} | ||
|
||
Ok(res) | ||
} | ||
|
||
fn shared_lib_extension(triple_target: &str) -> anyhow::Result<&'static str> { | ||
let (_arch, rest) = triple_target | ||
.split_once('-') | ||
.ok_or_else(|| anyhow::anyhow!("malformed triple target {}", triple_target))?; | ||
Ok( | ||
if rest.starts_with("unknown-linux") || rest.starts_with("alpine-linux") { | ||
"so" | ||
} else if rest.starts_with("pc-windows") { | ||
"dll" | ||
} else if rest.starts_with("apple-darwin") { | ||
"dylib" | ||
} else { | ||
return Err(anyhow::anyhow!( | ||
"unrecognized triple-target {}", | ||
triple_target | ||
)); | ||
}, | ||
) | ||
} | ||
|
||
#[macro_export] | ||
macro_rules! timeit { | ||
($op_name:literal, $op:block) => {{ | ||
let start = std::time::Instant::now(); | ||
let res = $op; | ||
let delta = std::time::Instant::now().duration_since(start); | ||
println!( | ||
concat!($op_name, " took {} ms"), | ||
delta.as_secs_f64() * 1000.0 | ||
); | ||
res | ||
}}; | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this machinery necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a comment at the top of the module describing what it does