Hi! As has been noted several times in the past, and most recently e.g. in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64511#c13 generating backtrace from internal_error call in driver's execute is undesirable, there is nothing wrong in the driver, the problem is that the compiler crashed. This confuses lots of people. The following patch avoids printing backtrace in that case.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2015-01-22 Jakub Jelinek <ja...@redhat.com> * diagnostic-core.h (internal_error_no_backtrace): New prototype. * diagnostic.def (DK_ICE_NOBT): New kind. * diagnostic.c (diagnostic_action_after_output): Handle DK_ICE_NOBT like DK_ICE, but never print backtrace. (diagnostic_report_diagnostic): Handle DK_ICE_NOBT like DK_ICE. (internal_error_no_backtrace): New function. * gcc.c (execute): Use internal_error_no_backtrace instead of internal_error. fortran/ * gfc-diagnostic.def (DK_ICE_NOBT): New kind. --- gcc/diagnostic-core.h.jj 2015-01-05 13:07:13.000000000 +0100 +++ gcc/diagnostic-core.h 2015-01-22 09:09:09.352920684 +0100 @@ -56,6 +56,8 @@ extern const char *trim_filename (const #endif extern void internal_error (const char *, ...) ATTRIBUTE_GCC_DIAG(1,2) ATTRIBUTE_NORETURN; +extern void internal_error_no_backtrace (const char *, ...) + ATTRIBUTE_GCC_DIAG(1,2) ATTRIBUTE_NORETURN; /* Pass one of the OPT_W* from options.h as the first parameter. */ extern bool warning (int, const char *, ...) ATTRIBUTE_GCC_DIAG(2,3); extern bool warning_n (location_t, int, int, const char *, const char *, ...) --- gcc/diagnostic.def.jj 2015-01-05 13:07:13.000000000 +0100 +++ gcc/diagnostic.def 2015-01-22 09:01:48.575490585 +0100 @@ -45,3 +45,6 @@ DEFINE_DIAGNOSTIC_KIND (DK_PERMERROR, "p /* This one is just for counting DK_WARNING promoted to DK_ERROR due to -Werror and -Werror=warning. */ DEFINE_DIAGNOSTIC_KIND (DK_WERROR, "error: ", NULL) +/* This is like DK_ICE, but backtrace is not printed. Used in the driver + when reporting fatal signal in the compiler. */ +DEFINE_DIAGNOSTIC_KIND (DK_ICE_NOBT, "internal compiler error: ", "error") --- gcc/diagnostic.c.jj 2015-01-05 13:07:15.000000000 +0100 +++ gcc/diagnostic.c 2015-01-22 09:13:34.166407314 +0100 @@ -518,9 +518,11 @@ diagnostic_action_after_output (diagnost break; case DK_ICE: + case DK_ICE_NOBT: { - struct backtrace_state *state = - backtrace_create_state (NULL, 0, bt_err_callback, NULL); + struct backtrace_state *state = NULL; + if (diag_kind == DK_ICE) + state = backtrace_create_state (NULL, 0, bt_err_callback, NULL); int count = 0; if (state != NULL) backtrace_full (state, 2, bt_callback, bt_err_callback, @@ -739,7 +741,8 @@ diagnostic_report_diagnostic (diagnostic /* If we're reporting an ICE in the middle of some other error, try to flush out the previous error, then let this one through. Don't do this more than once. */ - if (diagnostic->kind == DK_ICE && context->lock == 1) + if ((diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT) + && context->lock == 1) pp_newline_and_flush (context->printer); else error_recursion (context); @@ -812,7 +815,7 @@ diagnostic_report_diagnostic (diagnostic context->lock++; - if (diagnostic->kind == DK_ICE) + if (diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT) { #ifndef ENABLE_CHECKING /* When not checking, ICEs are converted to fatal errors when an @@ -1237,6 +1240,23 @@ internal_error (const char *gmsgid, ...) report_diagnostic (&diagnostic); va_end (ap); + gcc_unreachable (); +} + +/* Like internal_error, but no backtrace will be printed. Used when + the internal error does not happen at the current location, but happened + somewhere else. */ +void +internal_error_no_backtrace (const char *gmsgid, ...) +{ + diagnostic_info diagnostic; + va_list ap; + + va_start (ap, gmsgid); + diagnostic_set_info (&diagnostic, gmsgid, &ap, input_location, DK_ICE_NOBT); + report_diagnostic (&diagnostic); + va_end (ap); + gcc_unreachable (); } --- gcc/gcc.c.jj 2015-01-15 23:39:03.000000000 +0100 +++ gcc/gcc.c 2015-01-22 09:06:03.565111399 +0100 @@ -2909,8 +2909,9 @@ execute (void) } else #endif - internal_error ("%s (program %s)", - strsignal (WTERMSIG (status)), commands[i].prog); + internal_error_no_backtrace ("%s (program %s)", + strsignal (WTERMSIG (status)), + commands[i].prog); } else if (WIFEXITED (status) && WEXITSTATUS (status) >= MIN_FATAL_STATUS) --- gcc/fortran/gfc-diagnostic.def.jj 2015-01-05 13:07:19.000000000 +0100 +++ gcc/fortran/gfc-diagnostic.def 2015-01-22 09:09:52.411186741 +0100 @@ -45,3 +45,6 @@ DEFINE_DIAGNOSTIC_KIND (DK_PERMERROR, "p /* This one is just for counting DK_WARNING promoted to DK_ERROR due to -Werror and -Werror=warning. */ DEFINE_DIAGNOSTIC_KIND (DK_WERROR, "error", NULL) +/* This is like DK_ICE, but backtrace is not printed. Used in the driver + when reporting fatal signal in the compiler. */ +DEFINE_DIAGNOSTIC_KIND (DK_ICE_NOBT, "internal compiler error", "error") Jakub