Skip to content

Commit 6ea9883

Browse files
Include thread spawn in backtrace
1 parent ec037c6 commit 6ea9883

File tree

58 files changed

+1129
-8
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1129
-8
lines changed

src/concurrency/thread.rs

+31-8
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,9 @@ pub struct Thread<'tcx> {
235235
/// The join status.
236236
join_status: ThreadJoinStatus,
237237

238+
// ThreadId that spawned this thread and backtrace to where this thread was spawned
239+
thread_spawn_context: Option<(ThreadId, Vec<FrameInfo<'tcx>>)>,
240+
238241
/// Stack of active panic payloads for the current thread. Used for storing
239242
/// the argument of the call to `miri_start_unwind` (the panic payload) when unwinding.
240243
/// This is pointer-sized, and matches the `Payload` type in `src/libpanic_unwind/miri.rs`.
@@ -321,13 +324,18 @@ impl<'tcx> std::fmt::Debug for Thread<'tcx> {
321324
}
322325

323326
impl<'tcx> Thread<'tcx> {
324-
fn new(name: Option<&str>, on_stack_empty: Option<StackEmptyCallback<'tcx>>) -> Self {
327+
fn new(
328+
name: Option<&str>,
329+
on_stack_empty: Option<StackEmptyCallback<'tcx>>,
330+
thread_spawn_context: Option<(ThreadId, Vec<FrameInfo<'tcx>>)>,
331+
) -> Self {
325332
Self {
326333
state: ThreadState::Enabled,
327334
thread_name: name.map(|name| Vec::from(name.as_bytes())),
328335
stack: Vec::new(),
329336
top_user_relevant_frame: None,
330337
join_status: ThreadJoinStatus::Joinable,
338+
thread_spawn_context,
331339
panic_payloads: Vec::new(),
332340
last_error: None,
333341
on_stack_empty,
@@ -345,6 +353,7 @@ impl VisitProvenance for Thread<'_> {
345353
state: _,
346354
thread_name: _,
347355
join_status: _,
356+
thread_spawn_context: _,
348357
on_stack_empty: _, // we assume the closure captures no GC-relevant state
349358
} = self;
350359

@@ -475,7 +484,7 @@ impl<'tcx> Default for ThreadManager<'tcx> {
475484
fn default() -> Self {
476485
let mut threads = IndexVec::new();
477486
// Create the main thread and add it to the list of threads.
478-
threads.push(Thread::new(Some("main"), None));
487+
threads.push(Thread::new(Some("main"), None, None));
479488
Self {
480489
active_thread: ThreadId::MAIN_THREAD,
481490
threads,
@@ -542,9 +551,13 @@ impl<'tcx> ThreadManager<'tcx> {
542551
}
543552

544553
/// Create a new thread and returns its id.
545-
fn create_thread(&mut self, on_stack_empty: StackEmptyCallback<'tcx>) -> ThreadId {
554+
fn create_thread(
555+
&mut self,
556+
on_stack_empty: StackEmptyCallback<'tcx>,
557+
thread_spawn_context: Option<(ThreadId, Vec<FrameInfo<'tcx>>)>,
558+
) -> ThreadId {
546559
let new_thread_id = ThreadId::new(self.threads.len());
547-
self.threads.push(Thread::new(None, Some(on_stack_empty)));
560+
self.threads.push(Thread::new(None, Some(on_stack_empty), thread_spawn_context));
548561
new_thread_id
549562
}
550563

@@ -711,6 +724,13 @@ impl<'tcx> ThreadManager<'tcx> {
711724
self.threads[thread].thread_display_name(thread)
712725
}
713726

727+
pub fn get_thread_spawn_context(
728+
&self,
729+
thread: ThreadId,
730+
) -> Option<&(ThreadId, Vec<FrameInfo<'tcx>>)> {
731+
self.threads[thread].thread_spawn_context.as_ref()
732+
}
733+
714734
/// Put the thread into the blocked state.
715735
fn block_thread(
716736
&mut self,
@@ -924,10 +944,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
924944
let this = self.eval_context_mut();
925945

926946
// Create the new thread
927-
let new_thread_id = this.machine.threads.create_thread({
928-
let mut state = tls::TlsDtorsState::default();
929-
Box::new(move |m| state.on_stack_empty(m))
930-
});
947+
let new_thread_id = this.machine.threads.create_thread(
948+
{
949+
let mut state = tls::TlsDtorsState::default();
950+
Box::new(move |m| state.on_stack_empty(m))
951+
},
952+
Some((this.machine.threads.active_thread(), this.generate_stacktrace())),
953+
);
931954
let current_span = this.machine.current_span();
932955
if let Some(data_race) = &mut this.machine.data_race {
933956
data_race.thread_created(&this.machine.threads, new_thread_id, current_span);

src/diagnostics.rs

+30
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,36 @@ pub fn report_msg<'tcx>(
588588
}
589589
}
590590

591+
// Traverse thread spawns to display thread backtraces up to main thread
592+
if let Some(mut thread) = thread {
593+
let mut thread_spawn_context = machine.threads.get_thread_spawn_context(thread);
594+
595+
while let Some((spawning_thread, thread_spawn_backtrace)) = thread_spawn_context {
596+
err.note(format!(
597+
"thread `{}` was spawned by thread `{}`",
598+
machine.threads.get_thread_display_name(thread),
599+
machine.threads.get_thread_display_name(*spawning_thread)
600+
));
601+
let (pruned_stacktrace, _was_pruned) =
602+
prune_stacktrace(thread_spawn_backtrace.to_vec(), machine);
603+
604+
for (idx, frame_info) in pruned_stacktrace.iter().enumerate() {
605+
let is_local = machine.is_local(frame_info);
606+
// No span for non-local frames except the first frame (which is the error site).
607+
if is_local && idx > 0 {
608+
err.subdiagnostic(frame_info.as_note(machine.tcx));
609+
} else {
610+
let sm = sess.source_map();
611+
let span = sm.span_to_embeddable_string(frame_info.span);
612+
err.note(format!("{frame_info} at {span}"));
613+
}
614+
}
615+
616+
thread = *spawning_thread;
617+
thread_spawn_context = machine.threads.get_thread_spawn_context(thread);
618+
}
619+
}
620+
591621
err.emit();
592622
}
593623

tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ error: Undefined Behavior: calling a function with more arguments than it expect
55
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
66
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
77
= note: BACKTRACE on thread `unnamed-ID`:
8+
= note: thread `unnamed-ID` was spawned by thread `main`
9+
= note: inside `main` at tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs:LL:CC
810

911
error: aborting due to 1 previous error
1012

tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ error: Undefined Behavior: calling a function with fewer arguments than it requi
55
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
66
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
77
= note: BACKTRACE on thread `unnamed-ID`:
8+
= note: thread `unnamed-ID` was spawned by thread `main`
9+
= note: inside `main` at tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs:LL:CC
810

911
error: aborting due to 1 previous error
1012

tests/fail-dep/concurrency/libc_pthread_join_main.stderr

+16
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,22 @@ LL | assert_eq!(libc::pthread_join(thread_id, ptr::null_mut()), 0);
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
99
= note: BACKTRACE on thread `unnamed-ID`:
1010
= note: inside closure at tests/fail-dep/concurrency/libc_pthread_join_main.rs:LL:CC
11+
= note: thread `unnamed-ID` was spawned by thread `main`
12+
= note: inside `std::sys::pal::PLATFORM::thread::Thread::new` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
13+
= note: inside `std::thread::Builder::spawn_unchecked_::<'_, {closure@tests/fail-dep/concurrency/libc_pthread_join_main.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
14+
= note: inside `std::thread::Builder::spawn_unchecked::<{closure@tests/fail-dep/concurrency/libc_pthread_join_main.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
15+
= note: inside `std::thread::Builder::spawn::<{closure@tests/fail-dep/concurrency/libc_pthread_join_main.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
16+
= note: inside `std::thread::spawn::<{closure@tests/fail-dep/concurrency/libc_pthread_join_main.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
17+
note: inside `main`
18+
--> tests/fail-dep/concurrency/libc_pthread_join_main.rs:LL:CC
19+
|
20+
LL | let handle = thread::spawn(move || {
21+
| __________________^
22+
LL | | unsafe {
23+
LL | | assert_eq!(libc::pthread_join(thread_id, ptr::null_mut()), 0);
24+
LL | | }
25+
LL | | });
26+
| |______^
1127

1228
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
1329

tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr

+14
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,20 @@ LL | ... assert_eq!(libc::pthread_join(native_copy, ptr::null_mut()), 0);
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
99
= note: BACKTRACE on thread `unnamed-ID`:
1010
= note: inside closure at tests/fail-dep/concurrency/libc_pthread_join_multiple.rs:LL:CC
11+
= note: thread `unnamed-ID` was spawned by thread `main`
12+
= note: inside `std::sys::pal::PLATFORM::thread::Thread::new` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
13+
= note: inside `std::thread::Builder::spawn_unchecked_::<'_, {closure@tests/fail-dep/concurrency/libc_pthread_join_multiple.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
14+
= note: inside `std::thread::Builder::spawn_unchecked::<{closure@tests/fail-dep/concurrency/libc_pthread_join_multiple.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
15+
= note: inside `std::thread::Builder::spawn::<{closure@tests/fail-dep/concurrency/libc_pthread_join_multiple.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
16+
= note: inside `std::thread::spawn::<{closure@tests/fail-dep/concurrency/libc_pthread_join_multiple.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
17+
note: inside `main`
18+
--> tests/fail-dep/concurrency/libc_pthread_join_multiple.rs:LL:CC
19+
|
20+
LL | ... let handle = thread::spawn(move || {
21+
| ____________________^
22+
LL | | ... assert_eq!(libc::pthread_join(native_copy, ptr::null_mut()), 0);
23+
LL | | ... });
24+
| |________^
1125

1226
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
1327

tests/fail-dep/concurrency/libc_pthread_join_self.stderr

+17
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,23 @@ LL | assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0);
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
99
= note: BACKTRACE on thread `unnamed-ID`:
1010
= note: inside closure at tests/fail-dep/concurrency/libc_pthread_join_self.rs:LL:CC
11+
= note: thread `unnamed-ID` was spawned by thread `main`
12+
= note: inside `std::sys::pal::PLATFORM::thread::Thread::new` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
13+
= note: inside `std::thread::Builder::spawn_unchecked_::<'_, {closure@tests/fail-dep/concurrency/libc_pthread_join_self.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
14+
= note: inside `std::thread::Builder::spawn_unchecked::<{closure@tests/fail-dep/concurrency/libc_pthread_join_self.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
15+
= note: inside `std::thread::Builder::spawn::<{closure@tests/fail-dep/concurrency/libc_pthread_join_self.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
16+
= note: inside `std::thread::spawn::<{closure@tests/fail-dep/concurrency/libc_pthread_join_self.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
17+
note: inside `main`
18+
--> tests/fail-dep/concurrency/libc_pthread_join_self.rs:LL:CC
19+
|
20+
LL | let handle = thread::spawn(|| {
21+
| __________________^
22+
LL | | unsafe {
23+
LL | | let native: libc::pthread_t = libc::pthread_self();
24+
LL | | assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0);
25+
LL | | }
26+
LL | | });
27+
| |______^
1128

1229
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
1330

tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.stderr

+13
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@ LL | assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _
66
|
77
= note: BACKTRACE on thread `unnamed-ID`:
88
= note: inside closure at tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC
9+
= note: thread `unnamed-ID` was spawned by thread `main`
10+
= note: inside `std::sys::pal::PLATFORM::thread::Thread::new` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
11+
= note: inside `std::thread::Builder::spawn_unchecked_::<'_, {closure@tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
12+
= note: inside `std::thread::Builder::spawn_unchecked::<{closure@tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
13+
= note: inside `std::thread::Builder::spawn::<{closure@tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
14+
= note: inside `std::thread::spawn::<{closure@tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
15+
note: inside `main`
16+
--> tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC
17+
|
18+
LL | / thread::spawn(move || {
19+
LL | | assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0);
20+
LL | | })
21+
| |__________^
922

1023
error: deadlock: the evaluated program deadlocked
1124
--> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC

tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.stderr

+13
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,19 @@ LL | ...t_eq!(libc::pthread_mutex_unlock(lock_copy.0.get() as *mut _), 0);
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
99
= note: BACKTRACE on thread `unnamed-ID`:
1010
= note: inside closure at tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.rs:LL:CC
11+
= note: thread `unnamed-ID` was spawned by thread `main`
12+
= note: inside `std::sys::pal::PLATFORM::thread::Thread::new` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
13+
= note: inside `std::thread::Builder::spawn_unchecked_::<'_, {closure@tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
14+
= note: inside `std::thread::Builder::spawn_unchecked::<{closure@tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
15+
= note: inside `std::thread::Builder::spawn::<{closure@tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
16+
= note: inside `std::thread::spawn::<{closure@tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
17+
note: inside `main`
18+
--> tests/fail-dep/concurrency/libc_pthread_mutex_wrong_owner.rs:LL:CC
19+
|
20+
LL | / ... thread::spawn(move || {
21+
LL | | ... assert_eq!(libc::pthread_mutex_unlock(lock_copy.0.get() as *mut _), 0);
22+
LL | | ... })
23+
| |________^
1124

1225
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
1326

tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.stderr

+13
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,19 @@ LL | ... assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _),
88
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
99
= note: BACKTRACE on thread `unnamed-ID`:
1010
= note: inside closure at tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.rs:LL:CC
11+
= note: thread `unnamed-ID` was spawned by thread `main`
12+
= note: inside `std::sys::pal::PLATFORM::thread::Thread::new` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
13+
= note: inside `std::thread::Builder::spawn_unchecked_::<'_, {closure@tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
14+
= note: inside `std::thread::Builder::spawn_unchecked::<{closure@tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
15+
= note: inside `std::thread::Builder::spawn::<{closure@tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
16+
= note: inside `std::thread::spawn::<{closure@tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
17+
note: inside `main`
18+
--> tests/fail-dep/concurrency/libc_pthread_rwlock_read_wrong_owner.rs:LL:CC
19+
|
20+
LL | / ... thread::spawn(move || {
21+
LL | | ... assert_eq!(libc::pthread_rwlock_unlock(lock_copy.0.get() as *mut _), 0);
22+
LL | | ... })
23+
| |________^
1124

1225
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
1326

tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.stderr

+13
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@ LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mu
66
|
77
= note: BACKTRACE on thread `unnamed-ID`:
88
= note: inside closure at tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC
9+
= note: thread `unnamed-ID` was spawned by thread `main`
10+
= note: inside `std::sys::pal::PLATFORM::thread::Thread::new` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
11+
= note: inside `std::thread::Builder::spawn_unchecked_::<'_, {closure@tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
12+
= note: inside `std::thread::Builder::spawn_unchecked::<{closure@tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
13+
= note: inside `std::thread::Builder::spawn::<{closure@tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
14+
= note: inside `std::thread::spawn::<{closure@tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
15+
note: inside `main`
16+
--> tests/fail-dep/concurrency/libc_pthread_rwlock_write_read_deadlock.rs:LL:CC
17+
|
18+
LL | / thread::spawn(move || {
19+
LL | | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0);
20+
LL | | })
21+
| |__________^
922

1023
error: deadlock: the evaluated program deadlocked
1124
--> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC

tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.stderr

+13
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@ LL | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mu
66
|
77
= note: BACKTRACE on thread `unnamed-ID`:
88
= note: inside closure at tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC
9+
= note: thread `unnamed-ID` was spawned by thread `main`
10+
= note: inside `std::sys::pal::PLATFORM::thread::Thread::new` at RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC
11+
= note: inside `std::thread::Builder::spawn_unchecked_::<'_, {closure@tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
12+
= note: inside `std::thread::Builder::spawn_unchecked::<{closure@tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
13+
= note: inside `std::thread::Builder::spawn::<{closure@tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
14+
= note: inside `std::thread::spawn::<{closure@tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC}, ()>` at RUSTLIB/std/src/thread/mod.rs:LL:CC
15+
note: inside `main`
16+
--> tests/fail-dep/concurrency/libc_pthread_rwlock_write_write_deadlock.rs:LL:CC
17+
|
18+
LL | / thread::spawn(move || {
19+
LL | | assert_eq!(libc::pthread_rwlock_wrlock(lock_copy.0.get() as *mut _), 0);
20+
LL | | })
21+
| |__________^
922

1023
error: deadlock: the evaluated program deadlocked
1124
--> RUSTLIB/std/src/sys/pal/PLATFORM/thread.rs:LL:CC

0 commit comments

Comments
 (0)