From b15dc1ac8265406bbfdbf69ec17eb040667b785f Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 6 Nov 2018 11:13:04 -0800 Subject: [PATCH 1/3] 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) ``` --- src/cargo/core/compiler/mod.rs | 20 +++++++++-- tests/testsuite/build.rs | 62 ++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 59834c40915..a2b5d8d59fd 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -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}; @@ -275,6 +276,18 @@ fn rustc<'a, 'cfg>( } } + fn internal_if_simple_exit_code(err: Error) -> Error { + if err + .downcast_ref::() + .as_ref() + .and_then(|perr| perr.exit.and_then(|e| e.code())) + .is_none() + { + return err; + } + Internal::new(err).into() + } + state.running(&rustc); if json_messages { exec.exec_json( @@ -284,13 +297,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))?; } diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index 928bddde6fc..5f5a69c8e38 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -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(); +} From 0203caedbc7fe3b15cc819ff869c1ae32b05ee0c Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 6 Nov 2018 13:17:08 -0800 Subject: [PATCH 2/3] Show abnormal errors on windows, too. --- src/cargo/core/compiler/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index a2b5d8d59fd..10d65f55525 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -281,7 +281,7 @@ fn rustc<'a, 'cfg>( .downcast_ref::() .as_ref() .and_then(|perr| perr.exit.and_then(|e| e.code())) - .is_none() + != Some(1) { return err; } From 6bc5e7123e6d57fc916a12b1f8611e0a75aa3d67 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 6 Nov 2018 14:16:54 -0800 Subject: [PATCH 3/3] More conservative on error codes. --- src/cargo/core/compiler/mod.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 10d65f55525..6f9a42df069 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -277,15 +277,16 @@ fn rustc<'a, 'cfg>( } fn internal_if_simple_exit_code(err: Error) -> Error { - if err + // 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::() .as_ref() .and_then(|perr| perr.exit.and_then(|e| e.code())) - != Some(1) { - return err; + Some(n) if n < 128 => Internal::new(err).into(), + _ => err, } - Internal::new(err).into() } state.running(&rustc);