Skip to content

Commit e611c33

Browse files
committed
Fix panic after bailout in previous request
1 parent 3626b11 commit e611c33

1 file changed

Lines changed: 23 additions & 7 deletions

File tree

ext/logging.c

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -194,13 +194,29 @@ static void ddtrace_log_callback(ddog_CharSlice msg) {
194194
if (error_log_fd != -1) {
195195
ddtrace_log_with_time(error_log_fd, message, (int)msg.len);
196196
} else {
197-
if (msg.ptr[msg.len]) {
198-
message = zend_strndup(msg.ptr, msg.len);
199-
php_log_err(message);
200-
free(message);
201-
} else {
202-
php_log_err(message);
203-
}
197+
// Temporarily disable user abort to prevent zend_bailout() from being
198+
// called inside php_log_err(). This callback is invoked from Rust while
199+
// a RefCell borrow is held. A bailout (longjmp) would skip Rust
200+
// destructors, leaving the RefCell<Option<Dispatch>> permanently
201+
// borrowed and causing a panic on the following request.
202+
// If we STILL have a bailout, ... The safest thing to is probably to
203+
// catch it. We shouldn't log though, or risk a new bailout.
204+
bool orig_ignore_user_abort = PG(ignore_user_abort);
205+
PG(ignore_user_abort) = 1;
206+
volatile char *allocated_msg = NULL;
207+
zend_try {
208+
if (msg.ptr[msg.len]) {
209+
message = zend_strndup(msg.ptr, msg.len);
210+
allocated_msg = message;
211+
php_log_err(message);
212+
free(message);
213+
} else {
214+
php_log_err(message);
215+
}
216+
} zend_catch {
217+
free((void*)allocated_msg);
218+
} zend_end_try();
219+
PG(ignore_user_abort) = orig_ignore_user_abort;
204220
}
205221
}
206222

0 commit comments

Comments
 (0)