Skip to content

Commit 1a13d11

Browse files
committed
Trigger a panic on allocation error on nightly Rust
In issue rust-lang#66342, we're seeing extremely large allocations by rustc (4GB for the `hex` crate, which is only a few hundred lines). This is exhausing the memory on CI, causing jobs to fail intermittently. This PR installs a custom allocation error hook for nightly compilers, which attempts to trigger a panic after printing the initial error message. Hopefully, this will allow us to retrieve a backtrace when one of these large spurious allocations occurs. The hook is installed in `librustc_driver`, so that other compiler frontends (e.g. clippy) will get this logic as well. I'm unsure if this needs to be behind any kind of additional feature gate, beyond being ngithly only. This only affects compiler frontends, not generic users of `libstd`. While this will nake OOM errors on nightly much more verbose, I don't think this is necessarily a bad thing. I would expect that out of memory errors when running the compiler are usually infrequent, so most users will probably never notice this change. If any users are experiencing rust-lang#66342 (or something like it) on their own crates, the extra output might even be useful to them. I don't know of any reasonable way of writing a test for this. I manually verified the implementation by inserting: `let _a: Vec<usize> = Vec::with_capacity(9999999999)` into `librustc_driver` after the hook installation, and verified that a backtrace was printed. If we're very unlucky, it may turn out the large allocation on CI happens to occur after several large successful allocations, leaving extremely little memory left when we try to panic. If this is the case, then we may fail to panic or print the backtrace, since panicking currently allocates memory. However, we will still print an error message, so the output will be no less useful (though a little more spammy) then before.
1 parent 695fe96 commit 1a13d11

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

src/librustc_driver/lib.rs

+10
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#![feature(set_stdio)]
1313
#![feature(no_debug)]
1414
#![feature(integer_atomics)]
15+
#![feature(alloc_error_hook)]
16+
#![feature(alloc_internals)]
1517

1618
#![recursion_limit="256"]
1719

@@ -149,6 +151,14 @@ pub fn run_compiler(
149151
file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
150152
emitter: Option<Box<dyn Write + Send>>
151153
) -> interface::Result<()> {
154+
155+
// Install a custom alloc error hook on Nightly, to try
156+
// so we can try to generate a backtrace on OOM in the compiler
157+
// See https://github.com/rust-lang/rust/issues/66342 for details
158+
if UnstableFeatures::from_environment().is_nightly_build() {
159+
std::alloc::set_alloc_error_hook(std::alloc::rustc_alloc_error_hook);
160+
}
161+
152162
let mut args = Vec::new();
153163
for arg in at_args {
154164
match args::arg_expand(arg.clone()) {

src/libstd/alloc.rs

+15
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,21 @@ pub fn take_alloc_error_hook() -> fn(Layout) {
198198
}
199199
}
200200

201+
/// A custom error hook, used by librustc_driver.
202+
/// This lives in `libstd` so that we can call `dumb_print`.
203+
///
204+
/// This hook prints out a message like the default error hook,
205+
/// but then panics to generate a backtrace. If we are completely
206+
/// out of memory, panicking and/or backtrace generation may fail:
207+
/// this is fine, since the backtrace is best-effort only. We
208+
/// are guaranteed to print the actual error message, though.
209+
#[doc(hidden)]
210+
#[unstable(feature = "alloc_internals", issue = "0")]
211+
pub fn rustc_alloc_error_hook(layout: Layout) {
212+
dumb_print(format_args!("memory allocation of {} bytes failed. backtrace:", layout.size()));
213+
panic!();
214+
}
215+
201216
fn default_alloc_error_hook(layout: Layout) {
202217
dumb_print(format_args!("memory allocation of {} bytes failed", layout.size()));
203218
}

0 commit comments

Comments
 (0)