@@ -5,7 +5,7 @@ use std::{
5
5
6
6
use libc:: { c_char, c_int} ;
7
7
8
- use crate :: { panic , raw, util:: Binding , Error } ;
8
+ use crate :: { raw, util:: Binding , Error } ;
9
9
10
10
/// Available tracing levels. When tracing is set to a particular level,
11
11
/// 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) {
112
112
// Convert from a CStr to &[u8] to pass to the rust code callback.
113
113
let msg: & [ u8 ] = CStr :: to_bytes ( msg) ;
114
114
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) ;
126
141
}
127
142
128
143
#[ cfg( test) ]
0 commit comments