@@ -222,13 +222,9 @@ impl Iterator for ChildListener {
222
222
}
223
223
224
224
/// An error came up while waiting on the child process to do something.
225
+ /// It likely died, with this return code if we have one.
225
226
#[ derive( Debug ) ]
226
- enum ExecError {
227
- /// The child process died with this return code, if we have one.
228
- Died ( Option < i32 > ) ,
229
- /// Something errored, but we should ignore it and proceed.
230
- Shrug ,
231
- }
227
+ pub struct ExecEnd ( pub Option < i32 > ) ;
232
228
233
229
/// This is the main loop of the supervisor process. It runs in a separate
234
230
/// process from the rest of Miri (but because we fork, addresses for anything
@@ -238,7 +234,7 @@ pub fn sv_loop(
238
234
init_pid : unistd:: Pid ,
239
235
event_tx : ipc:: IpcSender < MemEvents > ,
240
236
confirm_tx : ipc:: IpcSender < Confirmation > ,
241
- ) -> Result < !, Option < i32 > > {
237
+ ) -> Result < !, ExecEnd > {
242
238
// Get the pagesize set and make sure it isn't still on the zero sentinel value!
243
239
let page_size = PAGE_SIZE . load ( std:: sync:: atomic:: Ordering :: Relaxed ) ;
244
240
assert_ne ! ( page_size, 0 ) ;
@@ -258,12 +254,7 @@ pub fn sv_loop(
258
254
let mut curr_pid = init_pid;
259
255
260
256
// There's an initial sigstop we need to deal with.
261
- wait_for_signal ( Some ( curr_pid) , signal:: SIGSTOP , false ) . map_err ( |e| {
262
- match e {
263
- ExecError :: Died ( code) => code,
264
- ExecError :: Shrug => None ,
265
- }
266
- } ) ?;
257
+ wait_for_signal ( Some ( curr_pid) , signal:: SIGSTOP , false ) ?;
267
258
ptrace:: cont ( curr_pid, None ) . unwrap ( ) ;
268
259
269
260
for evt in listener {
@@ -303,21 +294,14 @@ pub fn sv_loop(
303
294
// If it was a segfault, check if it was an artificial one
304
295
// caused by it trying to access the MiriMachine memory.
305
296
signal:: SIGSEGV =>
306
- match handle_segfault (
297
+ handle_segfault (
307
298
pid,
308
299
& ch_pages,
309
300
ch_stack. unwrap ( ) ,
310
301
page_size,
311
302
& cs,
312
303
& mut acc_events,
313
- ) {
314
- Err ( e) =>
315
- match e {
316
- ExecError :: Died ( code) => return Err ( code) ,
317
- ExecError :: Shrug => continue ,
318
- } ,
319
- _ => ( ) ,
320
- } ,
304
+ ) ?,
321
305
// Something weird happened.
322
306
_ => {
323
307
eprintln ! ( "Process unexpectedly got {signal}; continuing..." ) ;
@@ -335,7 +319,7 @@ pub fn sv_loop(
335
319
ptrace:: syscall ( pid, None ) . unwrap ( ) ;
336
320
}
337
321
ExecEvent :: Died ( code) => {
338
- return Err ( code) ;
322
+ return Err ( ExecEnd ( code) ) ;
339
323
}
340
324
}
341
325
}
@@ -375,7 +359,7 @@ fn wait_for_signal(
375
359
pid : Option < unistd:: Pid > ,
376
360
wait_signal : signal:: Signal ,
377
361
init_cont : bool ,
378
- ) -> Result < unistd:: Pid , ExecError > {
362
+ ) -> Result < unistd:: Pid , ExecEnd > {
379
363
if init_cont {
380
364
ptrace:: cont ( pid. unwrap ( ) , None ) . unwrap ( ) ;
381
365
}
@@ -385,13 +369,13 @@ fn wait_for_signal(
385
369
Some ( pid) => wait:: Id :: Pid ( pid) ,
386
370
None => wait:: Id :: All ,
387
371
} ;
388
- let stat = wait:: waitid ( wait_id, WAIT_FLAGS ) . map_err ( |_| ExecError :: Died ( None ) ) ?;
372
+ let stat = wait:: waitid ( wait_id, WAIT_FLAGS ) . map_err ( |_| ExecEnd ( None ) ) ?;
389
373
let ( signal, pid) = match stat {
390
374
// Report the cause of death, if we know it.
391
375
wait:: WaitStatus :: Exited ( _, code) => {
392
- return Err ( ExecError :: Died ( Some ( code) ) ) ;
376
+ return Err ( ExecEnd ( Some ( code) ) ) ;
393
377
}
394
- wait:: WaitStatus :: Signaled ( _, _, _) => return Err ( ExecError :: Died ( None ) ) ,
378
+ wait:: WaitStatus :: Signaled ( _, _, _) => return Err ( ExecEnd ( None ) ) ,
395
379
wait:: WaitStatus :: Stopped ( pid, signal) => ( signal, pid) ,
396
380
wait:: WaitStatus :: PtraceEvent ( pid, signal, _) => ( signal, pid) ,
397
381
// This covers PtraceSyscall and variants that are impossible with
@@ -404,7 +388,7 @@ fn wait_for_signal(
404
388
if signal == wait_signal {
405
389
return Ok ( pid) ;
406
390
} else {
407
- ptrace:: cont ( pid, signal) . map_err ( |_| ExecError :: Died ( None ) ) ?;
391
+ ptrace:: cont ( pid, signal) . map_err ( |_| ExecEnd ( None ) ) ?;
408
392
}
409
393
}
410
394
}
@@ -418,7 +402,7 @@ fn handle_segfault(
418
402
page_size : usize ,
419
403
cs : & capstone:: Capstone ,
420
404
acc_events : & mut Vec < AccessEvent > ,
421
- ) -> Result < ( ) , ExecError > {
405
+ ) -> Result < ( ) , ExecEnd > {
422
406
/// This is just here to not pollute the main namespace with `capstone::prelude::*`.
423
407
#[ inline]
424
408
fn capstone_disassemble (
@@ -538,7 +522,7 @@ fn handle_segfault(
538
522
539
523
// Get information on what caused the segfault. This contains the address
540
524
// that triggered it.
541
- let siginfo = ptrace:: getsiginfo ( pid) . map_err ( |_| ExecError :: Shrug ) ? ;
525
+ let siginfo = ptrace:: getsiginfo ( pid) . unwrap ( ) ;
542
526
// All x86, ARM, etc. instructions only have at most one memory operand
543
527
// (thankfully!)
544
528
// SAFETY: si_addr is safe to call.
@@ -599,7 +583,7 @@ fn handle_segfault(
599
583
// Don't use wait_for_signal here since 1 instruction doesn't give room
600
584
// for any uncertainty + we don't want it `cont()`ing randomly by accident
601
585
// Also, don't let it continue with unprotected memory if something errors!
602
- let _ = wait:: waitid ( wait:: Id :: Pid ( pid) , WAIT_FLAGS ) . map_err ( |_| ExecError :: Died ( None ) ) ?;
586
+ let _ = wait:: waitid ( wait:: Id :: Pid ( pid) , WAIT_FLAGS ) . map_err ( |_| ExecEnd ( None ) ) ?;
603
587
604
588
// Zero out again to be safe
605
589
for a in ( ch_stack..ch_stack. strict_add ( FAKE_STACK_SIZE ) ) . step_by ( ARCH_WORD_SIZE ) {
@@ -651,7 +635,7 @@ fn handle_segfault(
651
635
eprintln ! ( "Expected access on pages: {ch_pages:#018x?}" ) ;
652
636
eprintln ! ( "Register dump: {regs:#x?}" ) ;
653
637
ptrace:: kill ( pid) . unwrap ( ) ;
654
- Err ( ExecError :: Died ( None ) )
638
+ Err ( ExecEnd ( None ) )
655
639
}
656
640
}
657
641
0 commit comments