mirror of
https://github.com/rui314/mold.git
synced 2026-11-09 04:49:33 -10:00
Remove the temporary output file on a panic
A panic aborts the process in release builds, skipping the cleanup that a fatal error or a SIGSEGV/SIGBUS does, so a failed link left its .<output>.<pid> file behind. Install a panic hook that removes the file and then calls the default hook, so the panic message, backtrace and abort stay as they were. The hook runs on the panicking thread, so it also covers rayon workers and the extern "C" LTO plugin callbacks.
This commit is contained in:
1 parent
3d7bed0abd
commit
a0d62d97f7
3 files changed
+18
-1
No files matched your search
@@ -99,6 +99,7 @@ pub fn link<E: Target>(cmdline: Cmdline) -> LinkResult {
|
||||
|
||||
let t_all = ctx.timer("all");
|
||||
crate::subprocess::install_signal_handler();
|
||||
error::install_panic_hook();
|
||||
|
||||
// Fork a subprocess unless --no-fork is given.
|
||||
if ctx.args.fork {
|
||||
|
||||
@@ -114,6 +114,17 @@ pub fn exit_after_cleanup(status: i32) -> ! {
|
||||
std::process::exit(status)
|
||||
}
|
||||
|
||||
/// Makes a panic remove a partially-written output file, as a fatal error
|
||||
/// does, before the default hook reports the panic. Nothing recovers from
|
||||
/// a panic, so it always terminates the process.
|
||||
pub fn install_panic_hook() {
|
||||
let default_hook = std::panic::take_hook();
|
||||
std::panic::set_hook(Box::new(move |info| {
|
||||
crate::output_file::cleanup();
|
||||
default_hook(info);
|
||||
}));
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! fatal {
|
||||
($($arg:tt)*) => {
|
||||
|
||||
@@ -27,4 +27,9 @@ off=$(readelf -SW $t/a.o | sed 's/\[ *[0-9]*\]//' |
|
||||
# past the 8-byte section.
|
||||
printf '\0\1\0\0\0\0\0\0' | dd of=$t/a.o bs=1 seek=$((16#$off)) conv=notrunc status=none
|
||||
|
||||
not $CC -B. -o $t/exe $t/a.o $t/b.o >& /dev/null
|
||||
# mold panics on this input. The panic must not leave the temporary
|
||||
# output file behind.
|
||||
rm -rf $t/out
|
||||
mkdir $t/out
|
||||
not $CC -B. -o $t/out/exe $t/a.o $t/b.o >& /dev/null
|
||||
[ -z "$(ls -A $t/out)" ]
|
||||
Reference in new issue
Block a user