-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Internal Status Access Violation with constant redefinition #135870
Comments
On the playground both stable and nightly give:
|
@bjorn3 there are several non-standard flags in the user's output: I believe it is the |
Didn't notice that. https://rust.godbolt.org/z/nqfqqjo8h
|
Another oddity is that I get SIGSEGV on aarch64-apple-darwin and STATUS_ACCESS_VIOLATION on x86_64-pc-windows-msvc, but I get the deadlock detection on x86_64-apple-darwin. |
Reduction ( const FOO: usize = FOO; Bisection: searched nightlies: from nightly-2024-12-16 to nightly-2025-01-22 bisected with cargo-bisect-rustc v0.6.9Host triple: x86_64-unknown-linux-gnu cargo bisect-rustc --start=2024-12-16 --script run.sh @rustbot label:S-has-mcve WG-compiler-parallel S-has-bisection |
That bisects to removing driver queries? @bjorn3 |
That PR touched some code around handling of fatal error when they were emitted from inside a TyCtxt. |
@bjorn3 That's unfortunate because it may mean error handling has regressed under |
Reduced revert to fix this issue (will update as I minimize it)diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 2d76f6ec7d6..564b8e0f49a 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1349,6 +1349,33 @@ pub struct GlobalCtxt<'tcx> {
/// Stores memory for globals (statics/consts).
pub(crate) alloc_map: Lock<interpret::AllocMap<'tcx>>,
+
+ current_gcx: CurrentGcx,
+}
+
+impl<'tcx> GlobalCtxt<'tcx> {
+ /// Installs `self` in a `TyCtxt` and `ImplicitCtxt` for the duration of
+ /// `f`.
+ pub fn enter<F, R>(&'tcx self, f: F) -> R
+ where
+ F: FnOnce(TyCtxt<'tcx>) -> R,
+ {
+ let icx = tls::ImplicitCtxt::new(self);
+
+ // Reset `current_gcx` to `None` when we exit.
+ let _on_drop = defer(move || {
+ *self.current_gcx.value.write() = None;
+ });
+
+ // Set this `GlobalCtxt` as the current one.
+ {
+ let mut guard = self.current_gcx.value.write();
+ assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
+ *guard = Some(self as *const _ as *const ());
+ }
+
+ tls::enter_context(&icx, || f(icx.tcx))
+ }
}
/// This is used to get a reference to a `GlobalCtxt` if one is available.
@@ -1539,23 +1566,10 @@ pub fn create_global_ctxt<T>(
canonical_param_env_cache: Default::default(),
data_layout,
alloc_map: Lock::new(interpret::AllocMap::new()),
+ current_gcx,
});
- let icx = tls::ImplicitCtxt::new(&gcx);
-
- // Reset `current_gcx` to `None` when we exit.
- let _on_drop = defer(|| {
- *current_gcx.value.write() = None;
- });
-
- // Set this `GlobalCtxt` as the current one.
- {
- let mut guard = current_gcx.value.write();
- assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
- *guard = Some(&gcx as *const _ as *const ());
- }
-
- tls::enter_context(&icx, || f(icx.tcx))
+ gcx.enter(f)
}
/// Obtain all lang items of this crate and all dependencies (recursively) |
This is the minimal change that will fix this crash. Somehow inlining diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 2d76f6ec7d6..564b8e0f49a 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1349,6 +1349,33 @@ pub struct GlobalCtxt<'tcx> {
/// Stores memory for globals (statics/consts).
pub(crate) alloc_map: Lock<interpret::AllocMap<'tcx>>,
+
+ current_gcx: CurrentGcx,
+}
+
+impl<'tcx> GlobalCtxt<'tcx> {
+ /// Installs `self` in a `TyCtxt` and `ImplicitCtxt` for the duration of
+ /// `f`.
+ pub fn enter<F, R>(&'tcx self, f: F) -> R
+ where
+ F: FnOnce(TyCtxt<'tcx>) -> R,
+ {
+ let icx = tls::ImplicitCtxt::new(self);
+
+ // Reset `current_gcx` to `None` when we exit.
+ let _on_drop = defer(move || {
+ *self.current_gcx.value.write() = None;
+ });
+
+ // Set this `GlobalCtxt` as the current one.
+ {
+ let mut guard = self.current_gcx.value.write();
+ assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
+ *guard = Some(self as *const _ as *const ());
+ }
+
+ tls::enter_context(&icx, || f(icx.tcx))
+ }
}
/// This is used to get a reference to a `GlobalCtxt` if one is available.
@@ -1539,23 +1566,10 @@ pub fn create_global_ctxt<T>(
canonical_param_env_cache: Default::default(),
data_layout,
alloc_map: Lock::new(interpret::AllocMap::new()),
+ current_gcx,
});
- let icx = tls::ImplicitCtxt::new(&gcx);
-
- // Reset `current_gcx` to `None` when we exit.
- let _on_drop = defer(|| {
- *current_gcx.value.write() = None;
- });
-
- // Set this `GlobalCtxt` as the current one.
- {
- let mut guard = current_gcx.value.write();
- assert!(guard.is_none(), "no `GlobalCtxt` is currently set");
- *guard = Some(&gcx as *const _ as *const ());
- }
-
- tls::enter_context(&icx, || f(icx.tcx))
+ gcx.enter(f)
}
/// Obtain all lang items of this crate and all dependencies (recursively) |
I think we should probably land it. When working on the parallel queries tests and rustc-rayon, the crash above sometimes showed up as failures to get the |
I guess. It is just weird that inlining |
For sure. Something unobvious and fragile is going on. |
Likely not related to this crash, but when trying to run rustc in miri I found UB with
And another one without
Rustc patches to run under miridiff --git a/Cargo.lock b/Cargo.lock
index 10889139e8d..659730136a9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1947,8 +1947,6 @@ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
[[package]]
name = "jobserver"
version = "0.1.32"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
dependencies = [
"libc",
]
@@ -2258,8 +2256,6 @@ dependencies = [
[[package]]
name = "memchr"
version = "2.7.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "memmap2"
diff --git a/Cargo.toml b/Cargo.toml
index b773030b4ca..7f6a71f11e1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -93,3 +93,7 @@ codegen-units = 1
# FIXME: LTO cannot be enabled for binaries in a workspace
# <https://github.com/rust-lang/cargo/issues/9330>
# lto = true
+
+[patch.crates-io]
+jobserver = { path = "jobserver-0.1.32" }
+memchr = { path = "memchr-2.7.4" }
diff --git a/compiler/rustc_data_structures/src/flat_map_in_place.rs b/compiler/rustc_data_structures/src/flat_map_in_place.rs
index e66b00b7557..9e8aabebc40 100644
--- a/compiler/rustc_data_structures/src/flat_map_in_place.rs
+++ b/compiler/rustc_data_structures/src/flat_map_in_place.rs
@@ -1,4 +1,4 @@
-use std::ptr;
+use std::{mem, ptr};
use smallvec::{Array, SmallVec};
use thin_vec::ThinVec;
@@ -69,5 +69,55 @@ impl<T, A: Array<Item = T>> FlatMapInPlace<T> for SmallVec<A> {
}
impl<T> FlatMapInPlace<T> for ThinVec<T> {
- flat_map_in_place!();
+ fn flat_map_in_place<F, I>(&mut self, mut f: F)
+ where
+ F: FnMut(T) -> I,
+ I: IntoIterator<Item = T>,
+ {
+ struct LeakGuard<'a, T>(&'a mut ThinVec<T>);
+
+ impl<'a, T> Drop for LeakGuard<'a, T> {
+ fn drop(&mut self) {
+ unsafe {
+ self.0.set_len(0); // make sure we just leak elements in case of panic
+ }
+ }
+ }
+
+ let this = LeakGuard(self);
+
+ let mut read_i = 0;
+ let mut write_i = 0;
+ unsafe {
+ while read_i < this.0.len() {
+ // move the read_i'th item out of the vector and map it
+ // to an iterator
+ let e = ptr::read(this.0.as_ptr().add(read_i));
+ let iter = f(e).into_iter();
+ read_i += 1;
+
+ for e in iter {
+ if write_i < read_i {
+ ptr::write(this.0.as_mut_ptr().add(write_i), e);
+ write_i += 1;
+ } else {
+ // If this is reached we ran out of space
+ // in the middle of the vector.
+ // However, the vector is in a valid state here,
+ // so we just do a somewhat inefficient insert.
+ this.0.insert(write_i, e);
+
+ read_i += 1;
+ write_i += 1;
+ }
+ }
+ }
+
+ // write_i tracks the number of actually written new items.
+ this.0.set_len(write_i);
+
+ // The ThinVec is in a sane state again. Prevent the LeakGuard from leaking the data.
+ mem::forget(this);
+ }
+ }
}
diff --git a/compiler/rustc_data_structures/src/memmap.rs b/compiler/rustc_data_structures/src/memmap.rs
index c7f66b2fee8..d64a5862f4e 100644
--- a/compiler/rustc_data_structures/src/memmap.rs
+++ b/compiler/rustc_data_structures/src/memmap.rs
@@ -3,13 +3,13 @@
use std::ops::{Deref, DerefMut};
/// A trivial wrapper for [`memmap2::Mmap`] (or `Vec<u8>` on WASM).
-#[cfg(not(target_arch = "wasm32"))]
+#[cfg(not(any(miri, target_arch = "wasm32")))]
pub struct Mmap(memmap2::Mmap);
-#[cfg(target_arch = "wasm32")]
+#[cfg(any(miri, target_arch = "wasm32"))]
pub struct Mmap(Vec<u8>);
-#[cfg(not(target_arch = "wasm32"))]
+#[cfg(not(any(miri, target_arch = "wasm32")))]
impl Mmap {
/// # Safety
///
@@ -29,7 +29,7 @@ pub unsafe fn map(file: File) -> io::Result<Self> {
}
}
-#[cfg(target_arch = "wasm32")]
+#[cfg(any(miri, target_arch = "wasm32"))]
impl Mmap {
#[inline]
pub unsafe fn map(mut file: File) -> io::Result<Self> {
@@ -56,13 +56,13 @@ fn as_ref(&self) -> &[u8] {
}
}
-#[cfg(not(target_arch = "wasm32"))]
+#[cfg(not(any(miri, target_arch = "wasm32")))]
pub struct MmapMut(memmap2::MmapMut);
-#[cfg(target_arch = "wasm32")]
+#[cfg(any(miri, target_arch = "wasm32"))]
pub struct MmapMut(Vec<u8>);
-#[cfg(not(target_arch = "wasm32"))]
+#[cfg(not(any(miri, target_arch = "wasm32")))]
impl MmapMut {
#[inline]
pub fn map_anon(len: usize) -> io::Result<Self> {
@@ -82,7 +82,7 @@ pub fn make_read_only(self) -> std::io::Result<Mmap> {
}
}
-#[cfg(target_arch = "wasm32")]
+#[cfg(any(miri, target_arch = "wasm32"))]
impl MmapMut {
#[inline]
pub fn map_anon(len: usize) -> io::Result<Self> {
diff --git a/compiler/rustc_data_structures/src/stack.rs b/compiler/rustc_data_structures/src/stack.rs
index 3d6d0003483..d00cce7effc 100644
--- a/compiler/rustc_data_structures/src/stack.rs
+++ b/compiler/rustc_data_structures/src/stack.rs
@@ -18,5 +18,5 @@
/// Should not be sprinkled around carelessly, as it causes a little bit of overhead.
#[inline]
pub fn ensure_sufficient_stack<R>(f: impl FnOnce() -> R) -> R {
- stacker::maybe_grow(RED_ZONE, STACK_PER_RECURSION, f)
+ f() //stacker::maybe_grow(RED_ZONE, STACK_PER_RECURSION, f)
}
diff --git a/compiler/rustc_driver/Cargo.toml b/compiler/rustc_driver/Cargo.toml
index ae9712ad66d..81a113fe3f8 100644
--- a/compiler/rustc_driver/Cargo.toml
+++ b/compiler/rustc_driver/Cargo.toml
@@ -4,7 +4,7 @@ version = "0.0.0"
edition = "2021"
[lib]
-crate-type = ["dylib"]
+#crate-type = ["dylib"]
[dependencies]
# tidy-alphabetical-start
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 20be2144609..41da6c6c0ca 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -89,10 +89,10 @@
#[macro_use]
mod print;
mod session_diagnostics;
-#[cfg(all(unix, any(target_env = "gnu", target_os = "macos")))]
+#[cfg(all(not(miri), unix, any(target_env = "gnu", target_os = "macos")))]
mod signal_handler;
-#[cfg(not(all(unix, any(target_env = "gnu", target_os = "macos"))))]
+#[cfg(not(all(not(miri), unix, any(target_env = "gnu", target_os = "macos"))))]
mod signal_handler {
/// On platforms which don't support our signal handler's requirements,
/// simply use the default signal handler provided by std.
@@ -1474,7 +1474,7 @@ pub fn init_logger(early_dcx: &EarlyDiagCtxt, cfg: rustc_log::LoggerConfig) {
/// Install our usual `ctrlc` handler, which sets [`rustc_const_eval::CTRL_C_RECEIVED`].
/// Making this handler optional lets tools can install a different handler, if they wish.
pub fn install_ctrlc_handler() {
- #[cfg(not(target_family = "wasm"))]
+ #[cfg(all(not(miri), not(target_family = "wasm")))]
ctrlc::set_handler(move || {
// Indicate that we have been signaled to stop, then give the rest of the compiler a bit of
// time to check CTRL_C_RECEIVED and run its own shutdown logic, but after a short amount
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs
index 984b8104f53..529d118cdd4 100644
--- a/compiler/rustc_interface/src/util.rs
+++ b/compiler/rustc_interface/src/util.rs
@@ -247,6 +247,7 @@ pub fn get_codegen_backend(
}
#[cfg(feature = "llvm")]
"llvm" => rustc_codegen_llvm::LlvmCodegenBackend::new,
+ "dummy" => DummyCodegenBackend::new,
backend_name => get_codegen_sysroot(early_dcx, sysroot, backend_name),
}
});
@@ -257,6 +258,44 @@ pub fn get_codegen_backend(
unsafe { load() }
}
+struct DummyCodegenBackend;
+
+impl DummyCodegenBackend {
+ fn new() -> Box<dyn CodegenBackend> {
+ Box::new(DummyCodegenBackend)
+ }
+}
+
+impl CodegenBackend for DummyCodegenBackend {
+ fn locale_resource(&self) -> &'static str {
+ ""
+ }
+
+ fn codegen_crate<'tcx>(
+ &self,
+ tcx: rustc_middle::ty::TyCtxt<'tcx>,
+ metadata: rustc_metadata::EncodedMetadata,
+ need_metadata_module: bool,
+ ) -> Box<dyn std::any::Any> {
+ todo!()
+ }
+
+ fn join_codegen(
+ &self,
+ ongoing_codegen: Box<dyn std::any::Any>,
+ sess: &Session,
+ outputs: &OutputFilenames,
+ ) -> (
+ rustc_codegen_ssa::CodegenResults,
+ rustc_data_structures::fx::FxIndexMap<
+ rustc_middle::dep_graph::WorkProductId,
+ rustc_middle::dep_graph::WorkProduct,
+ >,
+ ) {
+ todo!()
+ }
+}
+
// This is used for rustdoc, but it uses similar machinery to codegen backend
// loading, so we leave the code here. It is potentially useful for other tools
// that want to invoke the rustc binary while linking to rustc as well.
diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs
index ec83761da4a..bbda7c213db 100644
--- a/compiler/rustc_session/src/filesearch.rs
+++ b/compiler/rustc_session/src/filesearch.rs
@@ -63,7 +63,10 @@ fn current_dll_path() -> Result<PathBuf, String> {
use std::ffi::{CStr, OsStr};
use std::os::unix::prelude::*;
- #[cfg(not(target_os = "aix"))]
+ #[cfg(miri)]
+ return Err("must manually specify --sysroot in miri".to_owned());
+
+ #[cfg(all(not(miri), not(target_os = "aix")))]
unsafe {
let addr = current_dll_path as usize as *mut _;
let mut info = std::mem::zeroed();
@@ -160,8 +163,7 @@ fn current_dll_path() -> Result<PathBuf, String> {
pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> {
let target = crate::config::host_tuple();
- let mut sysroot_candidates: SmallVec<[PathBuf; 2]> =
- smallvec![get_or_default_sysroot().expect("Failed finding sysroot")];
+ let mut sysroot_candidates: SmallVec<[PathBuf; 2]> = smallvec![];
let path = current_dll_path().and_then(|s| try_canonicalize(s).map_err(|e| e.to_string()));
if let Ok(dll) = path {
// use `parent` twice to chop off the file name and then also the Where jobserver is slightly patched to avoid a direct pipe2 syscall and with the fcntl call removed. Running miri is done using |
The first ( |
…mulacrum Upgrade elsa to the newest version. This was locked to 1.7.1 because of an error in the elsa release process that has since been fixed. Upgrading has the advantage that the elsa code runs properly in miri, at least with tree borrows. This was spawned from rust-lang#135870 (comment)
…rash, r=lqd Add a workaround for parallel rustc crashing when there are delayed bugs This doesn't fix the root cause of this crash, but at least stops it from happening for the time being. Workaround for rust-lang#135870
Rollup merge of rust-lang#135988 - bjorn3:workaround_parallel_rustc_crash, r=lqd Add a workaround for parallel rustc crashing when there are delayed bugs This doesn't fix the root cause of this crash, but at least stops it from happening for the time being. Workaround for rust-lang#135870
Upgrade elsa to the newest version. This was locked to 1.7.1 because of an error in the elsa release process that has since been fixed. Upgrading has the advantage that the elsa code runs properly in miri, at least with tree borrows. This was spawned from rust-lang#135870 (comment)
Upgrade elsa to the newest version. This was locked to 1.7.1 because of an error in the elsa release process that has since been fixed. Upgrading has the advantage that the elsa code runs properly in miri, at least with tree borrows. This was spawned from rust-lang#135870 (comment)
@TheIronBorn this should be fixed on nightly by now, thanks to #135988. Thanks for opening an issue! |
I intentionally left this issue open as my PR is just a workaround and not a root cause fix. |
I know. The root cause is unfixed but this issue is fixed. Duplicates are being opened though, and don't see this as fixed. Please open a dedicated issue to fix the root cause, and mention it in the wg-parallel-rustc tracking issues. |
Opened #136499 |
Upgrade elsa to the newest version. This was locked to 1.7.1 because of an error in the elsa release process that has since been fixed. Upgrading has the advantage that the elsa code runs properly in miri, at least with tree borrows. This was spawned from rust-lang#135870 (comment)
Upgrade elsa to the newest version. This was locked to 1.7.1 because of an error in the elsa release process that has since been fixed. Upgrading has the advantage that the elsa code runs properly in miri, at least with tree borrows. This was spawned from rust-lang#135870 (comment)
Upgrade elsa to the newest version. This was locked to 1.7.1 because of an error in the elsa release process that has since been fixed. Upgrading has the advantage that the elsa code runs properly in miri, at least with tree borrows. This was spawned from rust-lang/rust#135870 (comment)
Couple of changes to run rustc in miri This is not the full set of patches required to run rustc in miri, but it is the fast majority of the changes to rustc itself. There is also a change to the jobserver crate necessary and on arm64 a change to the memchr crate. Running rustc in miri has already found some UB: rust-lang#136579 cc rust-lang#135870 (comment)
Upgrade elsa to the newest version. This was locked to 1.7.1 because of an error in the elsa release process that has since been fixed. Upgrading has the advantage that the elsa code runs properly in miri, at least with tree borrows. This was spawned from rust-lang/rust#135870 (comment)
Couple of changes to run rustc in miri This is not the full set of patches required to run rustc in miri, but it is the fast majority of the changes to rustc itself. There is also a change to the jobserver crate necessary and on arm64 a change to the memchr crate. Running rustc in miri has already found some UB: rust-lang#136579 cc rust-lang#135870 (comment)
Couple of changes to run rustc in miri This is not the full set of patches required to run rustc in miri, but it is the fast majority of the changes to rustc itself. There is also a change to the jobserver crate necessary and on arm64 a change to the memchr crate. Running rustc in miri has already found some UB: rust-lang#136579 cc rust-lang#135870 (comment)
Rollup merge of rust-lang#136580 - bjorn3:miri_fixes, r=lqd Couple of changes to run rustc in miri This is not the full set of patches required to run rustc in miri, but it is the fast majority of the changes to rustc itself. There is also a change to the jobserver crate necessary and on arm64 a change to the memchr crate. Running rustc in miri has already found some UB: rust-lang#136579 cc rust-lang#135870 (comment)
Upgrade elsa to the newest version. This was locked to 1.7.1 because of an error in the elsa release process that has since been fixed. Upgrading has the advantage that the elsa code runs properly in miri, at least with tree borrows. This was spawned from rust-lang/rust#135870 (comment)
Fix UB in ThinVec::flat_map_in_place `thin_vec.as_ptr()` goes through the `Deref` impl of `ThinVec`, which will not allow access to any memory as we did call `set_len(0)` first. Found in the process of investigating rust-lang#135870.
Fix UB in ThinVec::flat_map_in_place `thin_vec.as_ptr()` goes through the `Deref` impl of `ThinVec`, which will not allow access to any memory as we did call `set_len(0)` first. Found in the process of investigating rust-lang#135870.
Fix UB in ThinVec::flat_map_in_place `thin_vec.as_ptr()` goes through the `Deref` impl of `ThinVec`, which will not allow access to any memory as we did call `set_len(0)` first. Found in the process of investigating rust-lang#135870.
Rollup merge of rust-lang#136579 - bjorn3:fix_thinvec_ext_ub, r=BoxyUwU Fix UB in ThinVec::flat_map_in_place `thin_vec.as_ptr()` goes through the `Deref` impl of `ThinVec`, which will not allow access to any memory as we did call `set_len(0)` first. Found in the process of investigating rust-lang#135870.
Code
Meta
rustc --version --verbose
:Error output
The text was updated successfully, but these errors were encountered: