Skip to content

Commit da2f268

Browse files
committed
Review comments
1 parent 3ba7f46 commit da2f268

File tree

4 files changed

+43
-42
lines changed

4 files changed

+43
-42
lines changed

src/shims/panic.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
4848
// Get the raw pointer stored in arg[0] (the panic payload).
4949
let &[payload] = check_arg_count(args)?;
5050
let payload = this.read_scalar(payload)?.check_init()?;
51-
this.set_panic_payload(payload);
51+
let thread = this.active_thread_mut();
52+
assert!(
53+
thread.panic_payload.is_none(),
54+
"the panic runtime should avoid double-panics"
55+
);
56+
thread.panic_payload = Some(payload);
5257

5358
// Jump to the unwind block to begin unwinding.
5459
this.unwind_to_block(unwind);
@@ -130,7 +135,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
130135

131136
// The Thread's `panic_payload` holds what was passed to `miri_start_panic`.
132137
// This is exactly the second argument we need to pass to `catch_fn`.
133-
let payload = this.take_panic_payload();
138+
let payload = this.active_thread_mut().panic_payload.take().unwrap();
134139

135140
// Push the `catch_fn` stackframe.
136141
let f_instance = this.memory.get_fn(catch_unwind.catch_fn)?.as_instance()?;

src/thread.rs

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,7 @@ pub struct Thread<'mir, 'tcx> {
119119
/// The temporary used for storing the argument of
120120
/// the call to `miri_start_panic` (the panic payload) when unwinding.
121121
/// This is pointer-sized, and matches the `Payload` type in `src/libpanic_unwind/miri.rs`.
122-
panic_payload: Option<Scalar<Tag>>,
123-
122+
pub(crate) panic_payload: Option<Scalar<Tag>>,
124123
}
125124

126125
impl<'mir, 'tcx> Thread<'mir, 'tcx> {
@@ -519,21 +518,6 @@ impl<'mir, 'tcx: 'mir> ThreadManager<'mir, 'tcx> {
519518
throw_machine_stop!(TerminationInfo::Deadlock);
520519
}
521520
}
522-
523-
/// Store the panic payload when beginning unwinding.
524-
fn set_panic_payload(&mut self, payload: Scalar<Tag>) {
525-
let thread = self.active_thread_mut();
526-
assert!(
527-
thread.panic_payload.is_none(),
528-
"the panic runtime should avoid double-panics"
529-
);
530-
thread.panic_payload = Some(payload);
531-
}
532-
533-
/// Retrieve the panic payload, for use in `catch_unwind`.
534-
fn take_panic_payload(&mut self) -> Scalar<Tag> {
535-
self.active_thread_mut().panic_payload.take().unwrap()
536-
}
537521
}
538522

539523
// Public interface to thread management.
@@ -593,6 +577,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
593577
this.machine.threads.get_active_thread_id()
594578
}
595579

580+
#[inline]
581+
fn active_thread_mut(&mut self) -> &mut Thread<'mir, 'tcx> {
582+
let this = self.eval_context_mut();
583+
this.machine.threads.active_thread_mut()
584+
}
585+
596586
#[inline]
597587
fn get_total_thread_count(&self) -> usize {
598588
let this = self.eval_context_ref();
@@ -711,16 +701,4 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
711701
}
712702
Ok(())
713703
}
714-
715-
/// Store the panic payload when beginning unwinding.
716-
fn set_panic_payload(&mut self, payload: Scalar<Tag>) {
717-
let this = self.eval_context_mut();
718-
this.machine.threads.set_panic_payload(payload);
719-
}
720-
721-
/// Retrieve the panic payload, for use in `catch_unwind`.
722-
fn take_panic_payload(&mut self) -> Scalar<Tag> {
723-
let this = self.eval_context_mut();
724-
this.machine.threads.take_panic_payload()
725-
}
726704
}

tests/run-pass/panic/concurrent-panic.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
// ignore-windows: Concurrency on Windows is not supported yet.
2+
3+
//! Cause a panic in one thread while another thread is unwinding. This checks
4+
//! that separate threads have their own panicking state.
5+
26
use std::sync::{Arc, Condvar, Mutex};
37
use std::thread::{spawn, JoinHandle};
48

@@ -12,11 +16,12 @@ impl BlockOnDrop {
1216

1317
impl Drop for BlockOnDrop {
1418
fn drop(&mut self) {
19+
eprintln!("Thread 2 blocking on thread 1");
1520
let _ = self.0.take().unwrap().join();
21+
eprintln!("Thread 1 has exited");
1622
}
1723
}
1824

19-
/// Cause a panic in one thread while another thread is unwinding.
2025
fn main() {
2126
let t1_started_pair = Arc::new((Mutex::new(false), Condvar::new()));
2227
let t2_started_pair = Arc::new((Mutex::new(false), Condvar::new()));
@@ -28,6 +33,7 @@ fn main() {
2833
let t1_started_pair = t1_started_pair.clone();
2934
let t1_continue_mutex = t1_continue_mutex.clone();
3035
spawn(move || {
36+
eprintln!("Thread 1 starting, will block on mutex");
3137
let (mutex, condvar) = &*t1_started_pair;
3238
*mutex.lock().unwrap() = true;
3339
condvar.notify_one();
@@ -36,6 +42,16 @@ fn main() {
3642
panic!("panic in thread 1");
3743
})
3844
};
45+
46+
// Wait for thread 1 to signal it has started.
47+
let (t1_started_mutex, t1_started_condvar) = &*t1_started_pair;
48+
let mut t1_started_guard = t1_started_mutex.lock().unwrap();
49+
while !*t1_started_guard {
50+
t1_started_guard = t1_started_condvar.wait(t1_started_guard).unwrap();
51+
}
52+
eprintln!("Thread 1 reported it has started");
53+
// Thread 1 should now be blocked waiting on t1_continue_mutex.
54+
3955
let t2 = {
4056
let t2_started_pair = t2_started_pair.clone();
4157
let block_on_drop = BlockOnDrop::new(t1);
@@ -50,24 +66,18 @@ fn main() {
5066
})
5167
};
5268

53-
// Wait for thread 1 to signal it has started.
54-
let (t1_started_mutex, t1_started_condvar) = &*t1_started_pair;
55-
let mut t1_started_guard = t1_started_mutex.lock().unwrap();
56-
while !*t1_started_guard {
57-
t1_started_guard = t1_started_condvar.wait(t1_started_guard).unwrap();
58-
}
59-
// Thread 1 should now be blocked waiting on t1_continue_mutex.
60-
6169
// Wait for thread 2 to signal it has started.
6270
let (t2_started_mutex, t2_started_condvar) = &*t2_started_pair;
6371
let mut t2_started_guard = t2_started_mutex.lock().unwrap();
6472
while !*t2_started_guard {
6573
t2_started_guard = t2_started_condvar.wait(t2_started_guard).unwrap();
6674
}
75+
eprintln!("Thread 2 reported it has started");
6776
// Thread 2 should now have already panicked and be in the middle of
6877
// unwinding. It should now be blocked on joining thread 1.
6978

7079
// Unlock t1_continue_mutex, and allow thread 1 to proceed.
80+
eprintln!("Unlocking mutex");
7181
drop(t1_continue_guard);
7282
// Thread 1 will panic the next time it is scheduled. This will test the
7383
// behavior of interest to this test, whether Miri properly handles
@@ -77,4 +87,5 @@ fn main() {
7787
// already be blocked on joining thread 1, so thread 1 will be scheduled
7888
// to run next, as it is the only ready thread.
7989
assert!(t2.join().is_err());
90+
eprintln!("Thread 2 has exited");
8091
}
Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
warning: thread support is experimental. For example, Miri does not detect data races yet.
22

3-
thread '<unnamed>' panicked at 'panic in thread 2', $DIR/concurrent-panic.rs:49:13
4-
thread '<unnamed>' panicked at 'panic in thread 1', $DIR/concurrent-panic.rs:36:13
3+
Thread 1 starting, will block on mutex
4+
Thread 1 reported it has started
5+
thread '<unnamed>' panicked at 'panic in thread 2', $DIR/concurrent-panic.rs:65:13
6+
Thread 2 blocking on thread 1
7+
Thread 2 reported it has started
8+
Unlocking mutex
9+
thread '<unnamed>' panicked at 'panic in thread 1', $DIR/concurrent-panic.rs:42:13
10+
Thread 1 has exited
11+
Thread 2 has exited

0 commit comments

Comments
 (0)