Capture runnable backtraces only when detecting nondeterminism

This commit is contained in:
Antonio Scandurra 2022-11-28 19:35:33 +01:00
parent d0709e7bfa
commit cd2a8579b9
2 changed files with 25 additions and 9 deletions

View file

@ -75,6 +75,7 @@ struct DeterministicState {
waiting_backtrace: Option<backtrace::Backtrace>, waiting_backtrace: Option<backtrace::Backtrace>,
next_runnable_id: usize, next_runnable_id: usize,
poll_history: Vec<usize>, poll_history: Vec<usize>,
enable_runnable_backtraces: bool,
runnable_backtraces: collections::HashMap<usize, backtrace::Backtrace>, runnable_backtraces: collections::HashMap<usize, backtrace::Backtrace>,
} }
@ -129,6 +130,7 @@ impl Deterministic {
waiting_backtrace: None, waiting_backtrace: None,
next_runnable_id: 0, next_runnable_id: 0,
poll_history: Default::default(), poll_history: Default::default(),
enable_runnable_backtraces: false,
runnable_backtraces: Default::default(), runnable_backtraces: Default::default(),
})), })),
parker: Default::default(), parker: Default::default(),
@ -139,6 +141,10 @@ impl Deterministic {
self.state.lock().poll_history.clone() self.state.lock().poll_history.clone()
} }
pub fn enable_runnable_backtrace(&self) {
self.state.lock().enable_runnable_backtraces = true;
}
pub fn runnable_backtrace(&self, runnable_id: usize) -> backtrace::Backtrace { pub fn runnable_backtrace(&self, runnable_id: usize) -> backtrace::Backtrace {
let mut backtrace = self.state.lock().runnable_backtraces[&runnable_id].clone(); let mut backtrace = self.state.lock().runnable_backtraces[&runnable_id].clone();
backtrace.resolve(); backtrace.resolve();
@ -169,9 +175,11 @@ impl Deterministic {
{ {
let mut state = state.lock(); let mut state = state.lock();
id = util::post_inc(&mut state.next_runnable_id); id = util::post_inc(&mut state.next_runnable_id);
state if state.enable_runnable_backtraces {
.runnable_backtraces state
.insert(id, backtrace::Backtrace::new_unresolved()); .runnable_backtraces
.insert(id, backtrace::Backtrace::new_unresolved());
}
} }
let unparker = self.parker.lock().unparker(); let unparker = self.parker.lock().unparker();
@ -194,9 +202,11 @@ impl Deterministic {
{ {
let mut state = state.lock(); let mut state = state.lock();
id = util::post_inc(&mut state.next_runnable_id); id = util::post_inc(&mut state.next_runnable_id);
state if state.enable_runnable_backtraces {
.runnable_backtraces state
.insert(id, backtrace::Backtrace::new_unresolved()); .runnable_backtraces
.insert(id, backtrace::Backtrace::new_unresolved());
}
} }
let unparker = self.parker.lock().unparker(); let unparker = self.parker.lock().unparker();
@ -225,9 +235,11 @@ impl Deterministic {
{ {
let mut state = state.lock(); let mut state = state.lock();
id = util::post_inc(&mut state.next_runnable_id); id = util::post_inc(&mut state.next_runnable_id);
state if state.enable_runnable_backtraces {
.runnable_backtraces state
.insert(id, backtrace::Backtrace::new()); .runnable_backtraces
.insert(id, backtrace::Backtrace::new_unresolved());
}
} }
let unparker = self.parker.lock().unparker(); let unparker = self.parker.lock().unparker();

View file

@ -72,6 +72,10 @@ pub fn run_test(
} }
let deterministic = executor::Deterministic::new(seed); let deterministic = executor::Deterministic::new(seed);
if detect_nondeterminism {
deterministic.enable_runnable_backtrace();
}
let leak_detector = Arc::new(Mutex::new(LeakDetector::default())); let leak_detector = Arc::new(Mutex::new(LeakDetector::default()));
let mut cx = TestAppContext::new( let mut cx = TestAppContext::new(
foreground_platform.clone(), foreground_platform.clone(),