Skip to content

Commit

Permalink
Auto merge of #6270 - ehuss:no-internal-signal, r=alexcrichton
Browse files Browse the repository at this point in the history
Don't treat rustc exit on signal as internal error.

If rustc exits with a signal, previously all you saw was:
```
   Compiling foo ...
error: Could not compile `foo`.

To learn more, run the command again with --verbose.
```

Now it shows the complete error by default:
```
   Compiling foo ...
error: Could not compile `foo`.

Caused by:
  process didn't exit successfully: `rustc ...` (signal: 6, SIGABRT: process abort signal)
```
  • Loading branch information
bors committed Nov 7, 2018
2 parents 787bee6 + 6bc5e71 commit a83cd61
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 3 deletions.
21 changes: 18 additions & 3 deletions src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ use std::io::{self, Write};
use std::path::{self, Path, PathBuf};
use std::sync::Arc;

use failure::Error;
use same_file::is_same_file;
use serde_json;

use core::manifest::TargetSourcePath;
use core::profiles::{Lto, Profile};
use core::{PackageId, Target};
use util::errors::{CargoResult, CargoResultExt, Internal};
use util::errors::{CargoResult, CargoResultExt, Internal, ProcessError};
use util::paths;
use util::{self, machine_message, Freshness, ProcessBuilder, process};
use util::{internal, join_paths, profile};
Expand Down Expand Up @@ -275,6 +276,19 @@ fn rustc<'a, 'cfg>(
}
}

fn internal_if_simple_exit_code(err: Error) -> Error {
// If a signal on unix (code == None) or an abnormal termination
// on Windows (codes like 0xC0000409), don't hide the error details.
match err
.downcast_ref::<ProcessError>()
.as_ref()
.and_then(|perr| perr.exit.and_then(|e| e.code()))
{
Some(n) if n < 128 => Internal::new(err).into(),
_ => err,
}
}

state.running(&rustc);
if json_messages {
exec.exec_json(
Expand All @@ -284,13 +298,14 @@ fn rustc<'a, 'cfg>(
mode,
&mut assert_is_empty,
&mut |line| json_stderr(line, &package_id, &target),
).map_err(Internal::new)
)
.map_err(internal_if_simple_exit_code)
.chain_err(|| format!("Could not compile `{}`.", name))?;
} else if build_plan {
state.build_plan(buildkey, rustc.clone(), outputs.clone());
} else {
exec.exec_and_capture_output(rustc, &package_id, &target, mode, state)
.map_err(Internal::new)
.map_err(internal_if_simple_exit_code)
.chain_err(|| format!("Could not compile `{}`.", name))?;
}

Expand Down
62 changes: 62 additions & 0 deletions tests/testsuite/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4373,3 +4373,65 @@ fn target_filters_workspace_not_found() {
.with_stderr("[ERROR] no library targets found in packages: a, b")
.run();
}

#[cfg(unix)]
#[test]
fn signal_display() {
// Cause the compiler to crash with a signal.
let foo = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
[dependencies]
pm = { path = "pm" }
"#,
)
.file(
"src/lib.rs",
r#"
#[macro_use]
extern crate pm;
#[derive(Foo)]
pub struct S;
"#,
)
.file(
"pm/Cargo.toml",
r#"
[package]
name = "pm"
version = "0.1.0"
[lib]
proc-macro = true
"#,
)
.file(
"pm/src/lib.rs",
r#"
extern crate proc_macro;
use proc_macro::TokenStream;
#[proc_macro_derive(Foo)]
pub fn derive(_input: TokenStream) -> TokenStream {
std::process::abort()
}
"#,
)
.build();

foo.cargo("build")
.with_stderr("\
[COMPILING] pm [..]
[COMPILING] foo [..]
[ERROR] Could not compile `foo`.
Caused by:
process didn't exit successfully: `rustc [..]` (signal: 6, SIGABRT: process abort signal)
")
.with_status(101)
.run();
}

0 comments on commit a83cd61

Please sign in to comment.