Skip to content

Commit c737cea

Browse files
authored
Merge pull request #1121 from vcfxb/master
Remove panic wrapper in tracing callback
2 parents bce4478 + c54f448 commit c737cea

File tree

1 file changed

+27
-12
lines changed

1 file changed

+27
-12
lines changed

src/tracing.rs

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::{
55

66
use libc::{c_char, c_int};
77

8-
use crate::{panic, raw, util::Binding, Error};
8+
use crate::{raw, util::Binding, Error};
99

1010
/// Available tracing levels. When tracing is set to a particular level,
1111
/// callers will be provided tracing at the given level and all lower levels.
@@ -112,17 +112,32 @@ extern "C" fn tracing_cb_c(level: raw::git_trace_level_t, msg: *const c_char) {
112112
// Convert from a CStr to &[u8] to pass to the rust code callback.
113113
let msg: &[u8] = CStr::to_bytes(msg);
114114

115-
// Do the remaining part of this function in a panic wrapper, to catch any panics it produces.
116-
panic::wrap(|| {
117-
// Convert the raw trace level into a type we can pass to the rust callback fn.
118-
//
119-
// SAFETY: Currently the implementation of this function (above) may panic, but is only marked as unsafe to match
120-
// the trait definition, thus we can consider this call safe.
121-
let level: TraceLevel = unsafe { Binding::from_raw(level) };
122-
123-
// Call the user-supplied callback (which may panic).
124-
(cb)(level, msg);
125-
});
115+
// Do not bother with wrapping any of the following calls in `panic::wrap`:
116+
//
117+
// The previous implementation used `panic::wrap` here but never called `panic::check` to determine if the
118+
// trace callback had panicked, much less what caused it.
119+
//
120+
// This had the potential to lead to lost errors/unwinds, confusing to debugging situations, and potential issues
121+
// catching panics in other parts of the `git2-rs` codebase.
122+
//
123+
// Instead, we simply call the next two lines, both of which may panic, directly. We can rely on the
124+
// `extern "C"` semantics to appropriately catch the panics generated here and abort the process:
125+
//
126+
// Per <https://doc.rust-lang.org/std/panic/fn.catch_unwind.html>:
127+
// > Rust functions that are expected to be called from foreign code that does not support
128+
// > unwinding (such as C compiled with -fno-exceptions) should be defined using extern "C", which ensures
129+
// > that if the Rust code panics, it is automatically caught and the process is aborted. If this is the desired
130+
// > behavior, it is not necessary to use catch_unwind explicitly. This function should instead be used when
131+
// > more graceful error-handling is needed.
132+
133+
// Convert the raw trace level into a type we can pass to the rust callback fn.
134+
//
135+
// SAFETY: Currently the implementation of this function (above) may panic, but is only marked as unsafe to match
136+
// the trait definition, thus we can consider this call safe.
137+
let level: TraceLevel = unsafe { Binding::from_raw(level) };
138+
139+
// Call the user-supplied callback (which may panic).
140+
(cb)(level, msg);
126141
}
127142

128143
#[cfg(test)]

0 commit comments

Comments
 (0)