Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/tools/miri/ci/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ case $HOST_TARGET in
# Partially supported targets (tier 2)
BASIC="empty_main integer heap_alloc libc-mem vec string btreemap" # ensures we have the basics: pre-main code, system allocator
UNIX="hello panic/panic panic/unwind concurrency/simple atomic libc-mem libc-misc libc-random env num_cpus" # the things that are very similar across all Unixes, and hence easily supported there
TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap random thread sync concurrency epoll eventfd
TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap random thread sync concurrency epoll eventfd prctl
TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std
TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std
;;
Expand Down
96 changes: 41 additions & 55 deletions src/tools/miri/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ pub fn report_result<'tcx>(
StackedBorrowsUb { .. } | TreeBorrowsUb { .. } | DataRace { .. } =>
Some("Undefined Behavior"),
LocalDeadlock => {
labels.push(format!("this thread got stuck here"));
labels.push(format!("thread got stuck here"));
None
}
GlobalDeadlock => {
Expand All @@ -264,10 +264,7 @@ pub fn report_result<'tcx>(
report_msg(
DiagLevel::Error,
format!("the evaluated program deadlocked"),
vec![format!(
"thread `{}` got stuck here",
ecx.machine.threads.get_thread_display_name(thread)
)],
vec![format!("thread got stuck here")],
vec![],
vec![],
&stacktrace,
Expand Down Expand Up @@ -558,86 +555,75 @@ fn report_msg<'tcx>(
thread: Option<ThreadId>,
machine: &MiriMachine<'tcx>,
) {
let span = match stacktrace.first() {
Some(fi) => fi.span,
None =>
match thread {
Some(thread_id) => machine.threads.thread_ref(thread_id).origin_span,
None => DUMMY_SP,
},
};
let sess = machine.tcx.sess;
let origin_span = thread.map(|t| machine.threads.thread_ref(t).origin_span).unwrap_or(DUMMY_SP);
let span = stacktrace.first().map(|fi| fi.span).unwrap_or(origin_span);
// The only time we do not have an origin span is for `main`, and there we check the signature
// upfront. So we should always have a span here.
assert!(!span.is_dummy());

let tcx = machine.tcx;
let level = match diag_level {
DiagLevel::Error => Level::Error,
DiagLevel::Warning => Level::Warning,
DiagLevel::Note => Level::Note,
};
let mut err = Diag::<()>::new(sess.dcx(), level, title);
let mut err = Diag::<()>::new(tcx.sess.dcx(), level, title);
err.span(span);

// Show main message.
if !span.is_dummy() {
for line in span_msg {
err.span_label(span, line);
}
} else {
// Make sure we show the message even when it is a dummy span.
for line in span_msg {
err.note(line);
}
err.note("(no span available)");
for line in span_msg {
err.span_label(span, line);
}

// Show note and help messages.
let mut extra_span = false;
for (span_data, note) in notes {
if let Some(span_data) = span_data {
err.span_note(span_data.span(), note);
extra_span = true;
} else {
err.note(note);
}
}
for (span_data, help) in helps {
if let Some(span_data) = span_data {
err.span_help(span_data.span(), help);
extra_span = true;
} else {
err.help(help);
}
}
// Only print thread name if there are multiple threads.
if let Some(thread) = thread
&& machine.threads.get_total_thread_count() > 1
{
err.note(format!(
"this is on thread `{}`",
machine.threads.get_thread_display_name(thread)
));
}

// Add backtrace
if stacktrace.len() > 1 {
let mut backtrace_title = String::from("BACKTRACE");
if extra_span {
write!(backtrace_title, " (of the first span)").unwrap();
}
if let Some(thread) = thread {
let thread_name = machine.threads.get_thread_display_name(thread);
if thread_name != "main" {
// Only print thread name if it is not `main`.
write!(backtrace_title, " on thread `{thread_name}`").unwrap();
};
}
write!(backtrace_title, ":").unwrap();
err.note(backtrace_title);
for (idx, frame_info) in stacktrace.iter().enumerate() {
let is_local = machine.is_local(frame_info.instance);
// No span for non-local frames and the first frame (which is the error site).
if is_local && idx > 0 {
err.subdiagnostic(frame_info.as_note(machine.tcx));
} else {
let sm = sess.source_map();
if stacktrace.len() > 0 {
// Skip it if we'd only shpw the span we have already shown
if stacktrace.len() > 1 {
let sm = tcx.sess.source_map();
let mut out = format!("stack backtrace:");
for (idx, frame_info) in stacktrace.iter().enumerate() {
let span = sm.span_to_diagnostic_string(frame_info.span);
err.note(format!("{frame_info} at {span}"));
write!(out, "\n{idx}: {}", frame_info.instance).unwrap();
write!(out, "\n at {span}").unwrap();
}
err.note(out);
}
} else if stacktrace.len() == 0 && !span.is_dummy() {
err.note(format!(
"this {} occurred while pushing a call frame onto an empty stack",
level.to_str()
));
// For TLS dtors and non-main threads, show the "origin"
if !origin_span.is_dummy() {
let what = if stacktrace.len() > 1 {
"the last function in that backtrace"
} else {
"the current function"
};
err.span_note(origin_span, format!("{what} got called indirectly due to this code"));
}
} else if !span.is_dummy() {
err.note(format!("this {level} occurred while pushing a call frame onto an empty stack"));
err.note("the span indicates which code caused the function to be called, but may not be the literal call site");
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//@only-target: darwin
//@compile-flags: -Zmiri-fixed-schedule
#![feature(sync_unsafe_cell)]

use std::cell::SyncUnsafeCell;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ LL | let _val = atomic_ref.load(Ordering::Relaxed);
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: this is on thread `unnamed-ID`
note: the current function got called indirectly due to this code
--> tests/fail-dep/concurrency/apple_os_unfair_lock_move_with_queue.rs:LL:CC
|
LL | / ... s.spawn(|| {
LL | | ... let atomic_ref = unsafe { &*lock.get().cast::<AtomicU32>() };
LL | | ... let _val = atomic_ref.load(Ordering::Relaxed);
LL | | ... });
| |________^

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ LL | libc::pthread_cond_destroy(cond2.as_mut_ptr());
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
= note: inside `check` at tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC
note: inside `main`
--> tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC
|
LL | check()
| ^^^^^^^
= note: stack backtrace:
0: check
at tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC
1: main
at tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ LL | libc::pthread_cond_destroy(&mut cond2 as *mut _);
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE:
= note: inside `check` at tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC
note: inside `main`
--> tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC
|
LL | check()
| ^^^^^^^
= note: stack backtrace:
0: check
at tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC
1: main
at tests/fail-dep/concurrency/libc_pthread_cond_move.rs:LL:CC

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ LL | libc::pthread_create(&mut native, ptr::null(), thread_start, pt
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: this is on thread `unnamed-ID`
= note: this error occurred while pushing a call frame onto an empty stack
= note: the span indicates which code caused the function to be called, but may not be the literal call site

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ LL | libc::pthread_create(&mut native, ptr::null(), thread_start, pt
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: this is on thread `unnamed-ID`
= note: this error occurred while pushing a call frame onto an empty stack
= note: the span indicates which code caused the function to be called, but may not be the literal call site

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ LL | assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0);
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: this is on thread `main`

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ LL | ... assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0);
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: this is on thread `main`

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ LL | ... assert_eq!(libc::pthread_join(thread_id, ptr::null_mut()), 0);
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: this is on thread `unnamed-ID`
note: the current function got called indirectly due to this code
--> tests/fail-dep/concurrency/libc_pthread_join_main.rs:LL:CC
|
LL | let handle = thread::spawn(move || {
| __________________^
LL | | unsafe {
LL | | assert_eq!(libc::pthread_join(thread_id, ptr::null_mut()), 0);
LL | | }
LL | | });
| |______^

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ LL | ... assert_eq!(libc::pthread_join(native_copy, ptr::null_mut()), 0);
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: this is on thread `unnamed-ID`
note: the current function got called indirectly due to this code
--> tests/fail-dep/concurrency/libc_pthread_join_multiple.rs:LL:CC
|
LL | ... let handle = thread::spawn(move || {
| ____________________^
LL | | ... assert_eq!(libc::pthread_join(native_copy, ptr::null_mut()), 0);
LL | | ... });
| |________^

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ LL | assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0);
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: this is on thread `unnamed-ID`
note: the current function got called indirectly due to this code
--> tests/fail-dep/concurrency/libc_pthread_join_self.rs:LL:CC
|
LL | let handle = thread::spawn(|| {
| __________________^
LL | | unsafe {
LL | | let native: libc::pthread_t = libc::pthread_self();
LL | | assert_eq!(libc::pthread_join(native, ptr::null_mut()), 0);
LL | | }
LL | | });
| |______^

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,33 @@ error: the evaluated program deadlocked
--> RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
|
LL | let ret = unsafe { libc::pthread_join(id, ptr::null_mut()) };
| ^ thread `main` got stuck here
| ^ thread got stuck here
|
= note: BACKTRACE:
= note: inside `std::sys::thread::PLATFORM::Thread::join` at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
= note: inside `std::thread::lifecycle::JoinInner::<'_, ()>::join` at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC
= note: inside `std::thread::JoinHandle::<()>::join` at RUSTLIB/std/src/thread/join_handle.rs:LL:CC
note: inside `main`
--> tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC
|
LL | / thread::spawn(move || {
LL | | assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0);
LL | | })
LL | | .join()
| |_______________^
= note: this is on thread `main`
= note: stack backtrace:
0: std::sys::thread::PLATFORM::Thread::join
at RUSTLIB/std/src/sys/thread/PLATFORM.rs:LL:CC
1: std::thread::lifecycle::JoinInner::join
at RUSTLIB/std/src/thread/lifecycle.rs:LL:CC
2: std::thread::JoinHandle::join
at RUSTLIB/std/src/thread/join_handle.rs:LL:CC
3: main
at tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC

error: the evaluated program deadlocked
--> tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC
|
LL | assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0);
| ^ thread `unnamed-ID` got stuck here
| ^ thread got stuck here
|
= note: this is on thread `unnamed-ID`
note: the current function got called indirectly due to this code
--> tests/fail-dep/concurrency/libc_pthread_mutex_deadlock.rs:LL:CC
|
LL | / thread::spawn(move || {
LL | | assert_eq!(libc::pthread_mutex_lock(lock_copy.0.get() as *mut _), 0);
LL | | })
| |__________^

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,25 @@ LL | self.1.deallocate(From::from(ptr.cast()), layout);
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: BACKTRACE on thread `unnamed-ID`:
= note: inside `<std::boxed::Box<Mutex> as std::ops::Drop>::drop` at RUSTLIB/alloc/src/boxed.rs:LL:CC
= note: inside `std::ptr::drop_in_place::<std::boxed::Box<Mutex>> - shim(Some(std::boxed::Box<Mutex>))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC
= note: inside `std::mem::drop::<std::boxed::Box<Mutex>>` at RUSTLIB/core/src/mem/mod.rs:LL:CC
note: inside closure
= note: this is on thread `unnamed-ID`
= note: stack backtrace:
0: <std::boxed::Box<Mutex> as std::ops::Drop>::drop
at RUSTLIB/alloc/src/boxed.rs:LL:CC
1: std::ptr::drop_in_place))
at RUSTLIB/core/src/ptr/mod.rs:LL:CC
2: std::mem::drop
at RUSTLIB/core/src/mem/mod.rs:LL:CC
3: main::{closure#0}::{closure#2}
at tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.rs:LL:CC
note: the last function in that backtrace got called indirectly due to this code
--> tests/fail-dep/concurrency/libc_pthread_mutex_free_while_queued.rs:LL:CC
|
LL | drop(unsafe { Box::from_raw(m.get().cast::<Mutex>()) });
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | / s.spawn(|| {
LL | | // Ensure we happen-after the initialization write.
LL | | assert!(initialized.load(Ordering::Acquire));
... |
LL | | });
| |__________^

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

Expand Down
Loading
Loading