-
Notifications
You must be signed in to change notification settings - Fork 13
Wrap ffi calls with catch_unwind. #1083
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
base: main
Are you sure you want to change the base?
Conversation
9b2b792
to
762337a
Compare
BenchmarksComparisonBenchmark execution time: 2025-06-03 07:28:07 Comparing candidate commit 67006bc in PR branch Found 0 performance improvements and 0 performance regressions! Performance is the same for 52 metrics, 2 unstable metrics. CandidateCandidate benchmark detailsGroup 1
Group 2
Group 3
Group 4
Group 5
Group 6
Group 7
Group 8
Group 9
Group 10
Group 11
Group 12
Group 13
BaselineOmitted due to size. |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1083 +/- ##
==========================================
- Coverage 70.96% 70.92% -0.04%
==========================================
Files 330 330
Lines 49898 49936 +38
==========================================
+ Hits 35409 35419 +10
- Misses 14489 14517 +28
🚀 New features to boost your workflow:
|
Artifact Size Benchmark Reportaarch64-alpine-linux-musl
aarch64-unknown-linux-gnu
libdatadog-x64-windows
libdatadog-x86-windows
x86_64-alpine-linux-musl
x86_64-unknown-linux-gnu
|
762337a
to
a4e42c9
Compare
a4e42c9
to
67006bc
Compare
@@ -57,6 +59,8 @@ impl Display for ExporterErrorCode { | |||
Self::NetworkUnknown => write!(f, "Unknown network error"), | |||
Self::Serde => write!(f, "Serialization/Deserialization error"), | |||
Self::TimedOut => write!(f, "Operation timed out"), | |||
#[cfg(feature = "catch_panic")] | |||
Self::Panic => write!(f, "Operation panicked"), |
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.
Should we be returning more information here? Something that would be helpful when these errors wind up in telemetry logs?
macro_rules! gen_error { | ||
($l:expr) => { | ||
Some(Box::new(ExporterError::new($l, &$l.to_string()))) | ||
}; | ||
} | ||
|
||
#[cfg(feature = "catch_panic")] | ||
macro_rules! catch_panic { |
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.
non-blocking: should this eventually be a proc macro? So we can just do:
#[catch_unwind]
fn foo() {
}
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.
+1
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.
LGTM. A couple of ideas that we can talk more about for follow-up but this is a good start.
Hey nice, that we are going forward that way. I have one question: do we plan to have this for all the ffi APIs ? |
($f:expr, $err:expr) => { | ||
match catch_unwind(AssertUnwindSafe(|| $f)) { | ||
Ok(ret) => ret, | ||
Err(_) => $err, |
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.
You could log the panic here I think so we have more contextual information on what crashed
Err(_) => $err, | |
Err(panic_info) => { | |
let msg = if let Some(s) = panic_info.downcast_ref::<&str>() { | |
Some(s) | |
} else if let Some(s) = panic_info.downcast_ref::<String>() { | |
Some(s) | |
} else { | |
None | |
}; | |
if let Some(msg) = msg { ... log the message with error level }; | |
$err | |
}, |
What does this PR do?
Prevent panics from unwindind in the host language so we can avoid UB.
Motivation
Currently there is no guarantee that the trace exporter methods are panic free so there is the possibility that unwinding in the host language can cause UB.
Additional Notes
The wrapper is feature gated by "catch_unwind" feature and it's enabled by default. The aim of the feature is having a mechanism to disable the feature if the performance penalty is higher than expected.