diff mbox

Don't emit backtrace from driver upon fatal compiler signals

Message ID 20150122203511.GJ1746@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Jan. 22, 2015, 8:35 p.m. UTC
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  <jakub@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.


	Jakub

Comments

Ian Lance Taylor Jan. 23, 2015, 2:50 a.m. UTC | #1
On Thu, Jan 22, 2015 at 12:35 PM, Jakub Jelinek <jakub@redhat.com> wrote:
>
> 2015-01-22  Jakub Jelinek  <jakub@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.

This is OK.

Thanks for taking care of this.

Ian
Dodji Seketeli Jan. 23, 2015, 7:21 a.m. UTC | #2
Ian Lance Taylor <iant@golang.org> writes:

> On Thu, Jan 22, 2015 at 12:35 PM, Jakub Jelinek <jakub@redhat.com> wrote:
>>
>> 2015-01-22  Jakub Jelinek  <jakub@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.
>
> This is OK.

FWIW, this is fine from me too,

> Thanks for taking care of this.

Indeed.

Cheers,
diff mbox

Patch

--- 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")