Skip to content

Commit 46a7d28

Browse files
committed
Handle unwinding fatal errors in codegen workers
1 parent 4eedad3 commit 46a7d28

File tree

1 file changed

+21
-32
lines changed
  • compiler/rustc_codegen_ssa/src/back

1 file changed

+21
-32
lines changed

compiler/rustc_codegen_ssa/src/back/write.rs

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::assert_matches::assert_matches;
22
use std::marker::PhantomData;
3+
use std::panic::AssertUnwindSafe;
34
use std::path::{Path, PathBuf};
45
use std::sync::Arc;
56
use std::sync::mpsc::{Receiver, Sender, channel};
@@ -14,8 +15,8 @@ use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard};
1415
use rustc_errors::emitter::Emitter;
1516
use rustc_errors::translation::Translator;
1617
use rustc_errors::{
17-
Diag, DiagArgMap, DiagCtxt, DiagMessage, ErrCode, FatalError, Level, MultiSpan, Style,
18-
Suggestions,
18+
Diag, DiagArgMap, DiagCtxt, DiagMessage, ErrCode, FatalError, FatalErrorMarker, Level,
19+
MultiSpan, Style, Suggestions,
1920
};
2021
use rustc_fs_util::link_or_copy;
2122
use rustc_incremental::{
@@ -1722,37 +1723,10 @@ fn spawn_work<'a, B: ExtraBackendMethods>(
17221723
let cgcx = cgcx.clone();
17231724

17241725
B::spawn_named_thread(cgcx.time_trace, work.short_description(), move || {
1725-
// Set up a destructor which will fire off a message that we're done as
1726-
// we exit.
1727-
struct Bomb<B: ExtraBackendMethods> {
1728-
coordinator_send: Sender<Message<B>>,
1729-
result: Option<Result<WorkItemResult<B>, FatalError>>,
1730-
}
1731-
impl<B: ExtraBackendMethods> Drop for Bomb<B> {
1732-
fn drop(&mut self) {
1733-
let msg = match self.result.take() {
1734-
Some(Ok(result)) => Message::WorkItem::<B> { result: Ok(result) },
1735-
Some(Err(FatalError)) => {
1736-
Message::WorkItem::<B> { result: Err(Some(WorkerFatalError)) }
1737-
}
1738-
None => Message::WorkItem::<B> { result: Err(None) },
1739-
};
1740-
drop(self.coordinator_send.send(msg));
1741-
}
1742-
}
1743-
1744-
let mut bomb = Bomb::<B> { coordinator_send, result: None };
1745-
1746-
// Execute the work itself, and if it finishes successfully then flag
1747-
// ourselves as a success as well.
1748-
//
1749-
// Note that we ignore any `FatalError` coming out of `execute_work_item`,
1750-
// as a diagnostic was already sent off to the main thread - just
1751-
// surface that there was an error in this worker.
1752-
bomb.result = {
1726+
let result = std::panic::catch_unwind(AssertUnwindSafe(|| {
17531727
let module_config = cgcx.config(work.module_kind());
17541728

1755-
Some(match work {
1729+
match work {
17561730
WorkItem::Optimize(m) => {
17571731
let _timer =
17581732
cgcx.prof.generic_activity_with_arg("codegen_module_optimize", &*m.name);
@@ -1788,8 +1762,23 @@ fn spawn_work<'a, B: ExtraBackendMethods>(
17881762
cgcx.prof.generic_activity_with_arg("codegen_module_perform_lto", m.name());
17891763
execute_thin_lto_work_item(&cgcx, m, module_config)
17901764
}
1791-
})
1765+
}
1766+
}));
1767+
1768+
let msg = match result {
1769+
Ok(Ok(result)) => Message::WorkItem::<B> { result: Ok(result) },
1770+
1771+
// We ignore any `FatalError` coming out of `execute_work_item`, as a
1772+
// diagnostic was already sent off to the main thread - just surface
1773+
// that there was an error in this worker.
1774+
Ok(Err(FatalError)) => Message::WorkItem::<B> { result: Err(Some(WorkerFatalError)) },
1775+
Err(err) if err.is::<FatalErrorMarker>() => {
1776+
Message::WorkItem::<B> { result: Err(Some(WorkerFatalError)) }
1777+
}
1778+
1779+
Err(_) => Message::WorkItem::<B> { result: Err(None) },
17921780
};
1781+
drop(coordinator_send.send(msg));
17931782
})
17941783
.expect("failed to spawn work thread");
17951784
}

0 commit comments

Comments
 (0)