File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff 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
You can’t perform that action at this time.
0 commit comments