@@ -6,7 +6,7 @@ use core::sync::atomic::{Ordering, compiler_fence};
6
6
use core:: {
7
7
ffi:: c_void,
8
8
marker:: PhantomData ,
9
- ptr:: { self , null_mut} ,
9
+ ptr:: { null , null_mut} ,
10
10
time:: Duration ,
11
11
} ;
12
12
@@ -43,6 +43,12 @@ use crate::{inputs::Input, observers::ObserversTuple, state::HasCurrentTestcase}
43
43
/// The inmem executor's handlers.
44
44
#[ expect( missing_debug_implementations) ]
45
45
pub struct InProcessHooks < I , S > {
46
+ /// On crash C function pointer
47
+ #[ cfg( feature = "std" ) ]
48
+ pub crash_handler : * const c_void ,
49
+ /// On timeout C function pointer
50
+ #[ cfg( feature = "std" ) ]
51
+ pub timeout_handler : * const c_void ,
46
52
/// `TImer` struct
47
53
#[ cfg( feature = "std" ) ]
48
54
pub timer : TimerStruct ,
@@ -190,6 +196,19 @@ impl<I, S> ExecutorHook<I, S> for InProcessHooks<I, S> {
190
196
fn init ( & mut self , _state : & mut S ) { }
191
197
/// Call before running a target.
192
198
fn pre_exec ( & mut self , _state : & mut S , _input : & I ) {
199
+ #[ cfg( feature = "std" ) ]
200
+ // This is very important!!!!!
201
+ // Don't remove these pointer settings.
202
+ // Imagine there are two executors, you have to set the correct crash handlers for each of the executor.
203
+ unsafe {
204
+ let data = & raw mut GLOBAL_STATE ;
205
+ assert ! ( ( * data) . crash_handler == null( ) ) ;
206
+ // usually timeout handler and crash handler is set together
207
+ // so no check for timeout handler is null or not
208
+ ( * data) . crash_handler = self . crash_handler ;
209
+ ( * data) . timeout_handler = self . timeout_handler ;
210
+ }
211
+
193
212
#[ cfg( all( feature = "std" , not( all( miri, target_vendor = "apple" ) ) ) ) ]
194
213
self . timer_mut ( ) . set_timer ( ) ;
195
214
}
@@ -200,6 +219,12 @@ impl<I, S> ExecutorHook<I, S> for InProcessHooks<I, S> {
200
219
// We're calling this only once per execution, in a single thread.
201
220
#[ cfg( all( feature = "std" , not( all( miri, target_vendor = "apple" ) ) ) ) ]
202
221
self . timer_mut ( ) . unset_timer ( ) ;
222
+ #[ cfg( feature = "std" ) ]
223
+ unsafe {
224
+ let data = & raw mut GLOBAL_STATE ;
225
+ ( * data) . crash_handler = null ( ) ;
226
+ ( * data) . timeout_handler = null ( ) ;
227
+ }
203
228
}
204
229
}
205
230
@@ -234,18 +259,15 @@ impl<I, S> InProcessHooks<I, S> {
234
259
setup_signal_handler ( data) ?;
235
260
}
236
261
237
- #[ cfg( feature = "std" ) ]
238
- unsafe {
239
- let data = & raw mut GLOBAL_STATE ;
240
- ( * data) . crash_handler =
241
- unix_signal_handler:: inproc_crash_handler :: < E , EM , I , OF , S , Z > as * const c_void ;
242
- ( * data) . timeout_handler =
243
- unix_signal_handler:: inproc_timeout_handler :: < E , EM , I , OF , S , Z > as * const _ ;
244
- }
245
-
246
262
compiler_fence ( Ordering :: SeqCst ) ;
247
263
Ok ( Self {
248
264
#[ cfg( feature = "std" ) ]
265
+ crash_handler : unix_signal_handler:: inproc_crash_handler :: < E , EM , I , OF , S , Z >
266
+ as * const c_void ,
267
+ #[ cfg( feature = "std" ) ]
268
+ timeout_handler : unix_signal_handler:: inproc_timeout_handler :: < E , EM , I , OF , S , Z >
269
+ as * const _ ,
270
+ #[ cfg( feature = "std" ) ]
249
271
timer : TimerStruct :: new ( exec_tmout) ,
250
272
phantom : PhantomData ,
251
273
} )
@@ -278,7 +300,7 @@ impl<I, S> InProcessHooks<I, S> {
278
300
> ( ) ;
279
301
setup_exception_handler ( data) ?;
280
302
compiler_fence ( Ordering :: SeqCst ) ;
281
- ( * data ) . crash_handler =
303
+ let crash_handler =
282
304
crate :: executors:: hooks:: windows:: windows_exception_handler:: inproc_crash_handler :: <
283
305
E ,
284
306
EM ,
@@ -296,9 +318,10 @@ impl<I, S> InProcessHooks<I, S> {
296
318
S ,
297
319
Z ,
298
320
> as * const c_void ;
299
- ( * data) . timeout_handler = timeout_handler;
300
321
let timer = TimerStruct :: new ( exec_tmout, timeout_handler) ;
301
322
ret = Ok ( Self {
323
+ crash_handler,
324
+ timeout_handler,
302
325
timer,
303
326
phantom : PhantomData ,
304
327
} ) ;
@@ -336,6 +359,10 @@ impl<I, S> InProcessHooks<I, S> {
336
359
#[ cfg( not( windows) ) ]
337
360
pub fn nop ( ) -> Self {
338
361
Self {
362
+ #[ cfg( feature = "std" ) ]
363
+ crash_handler : null ( ) ,
364
+ #[ cfg( feature = "std" ) ]
365
+ timeout_handler : null ( ) ,
339
366
#[ cfg( feature = "std" ) ]
340
367
timer : TimerStruct :: new ( Duration :: from_millis ( 5000 ) ) ,
341
368
phantom : PhantomData ,
@@ -414,7 +441,7 @@ impl InProcessExecutorHandlerData {
414
441
#[ cfg( all( feature = "std" , any( unix, windows) ) ) ]
415
442
pub ( crate ) unsafe fn take_current_input < ' a , I > ( & mut self ) -> & ' a I {
416
443
let r = unsafe { ( self . current_input_ptr as * const I ) . as_ref ( ) . unwrap ( ) } ;
417
- self . current_input_ptr = ptr :: null ( ) ;
444
+ self . current_input_ptr = null ( ) ;
418
445
r
419
446
}
420
447
@@ -509,19 +536,19 @@ pub static mut GLOBAL_STATE: InProcessExecutorHandlerData = InProcessExecutorHan
509
536
// The fuzzer ptr for signal handling
510
537
fuzzer_ptr : null_mut ( ) ,
511
538
// The executor ptr for signal handling
512
- executor_ptr : ptr :: null ( ) ,
539
+ executor_ptr : null ( ) ,
513
540
// The current input for signal handling
514
- current_input_ptr : ptr :: null ( ) ,
541
+ current_input_ptr : null ( ) ,
515
542
516
543
#[ cfg( feature = "std" ) ]
517
544
signal_handler_depth : 0 ,
518
545
519
546
// The crash handler fn
520
547
#[ cfg( feature = "std" ) ]
521
- crash_handler : ptr :: null ( ) ,
548
+ crash_handler : null ( ) ,
522
549
// The timeout handler fn
523
550
#[ cfg( feature = "std" ) ]
524
- timeout_handler : ptr :: null ( ) ,
551
+ timeout_handler : null ( ) ,
525
552
#[ cfg( all( windows, feature = "std" ) ) ]
526
553
ptp_timer : None ,
527
554
#[ cfg( all( windows, feature = "std" ) ) ]
0 commit comments