diff mbox

Dump function on internal errors

Message ID alpine.LNX.2.20.13.1705291907090.20167@monopod.intra.ispras.ru
State New
Headers show

Commit Message

Alexander Monakov May 29, 2017, 4:15 p.m. UTC
Hi,

On Wed, 24 May 2017, Richard Biener wrote:
> current_pass might be NULL so you better do set_internal_error_hook when
> we start executing passes (I detest global singletons to do such stuff anyway).

I think there are other problems in this patch, dump_function_to_file won't work
after transition to RTL (it only handles GIMPLE).  It's much better to just use
existing dump routine in passes.c and use the existing diagnostic callbacks.

Here's an alternative, imho a bit more streamlined patch.  Here's how the new
notice is placed:

ice.c: In function ‘fn1.part.0’:
ice.c:24:1: error: size of loop 1 should be 1, not 2
 }
 ^
function dumped to file ice.c.227r.expand
ice.c:24:1: internal compiler error: in verify_loop_structure, at cfgloop.c:1644
0x92aeb8 verify_loop_structure()
        /home/am/pr80640/gcc/gcc/cfgloop.c:1644


Bootstrapped on x86_64, OK for trunk?

Alexander

	* passes.c (emergency_dump_function): New.
	* tree-pass.h (emergency_dump_function): Declare.
	* plugin.c (plugins_internal_error_function): Remove.
	* plugin.h (plugins_internal_error_function): Remove declaration.
        * toplev.c (internal_error_function): New static function.  Use it...
	(general_init): ...here.
---
 gcc/passes.c    | 14 ++++++++++++++
 gcc/plugin.c    | 10 ----------
 gcc/plugin.h    |  2 --
 gcc/toplev.c    | 14 +++++++++++++-
 gcc/tree-pass.h |  1 +
 5 files changed, 28 insertions(+), 13 deletions(-)

Comments

Jakub Jelinek May 29, 2017, 4:22 p.m. UTC | #1
On Mon, May 29, 2017 at 07:15:33PM +0300, Alexander Monakov wrote:
> @@ -1063,6 +1064,17 @@ open_auxiliary_file (const char *ext)
>    return file;
>  }
>  
> +/* Auxiliary callback for the diagnostics code.  */
> +
> +static void
> +internal_error_function (diagnostic_context *context ATTRIBUTE_UNUSED,
> +			 const char *msgid ATTRIBUTE_UNUSED,
> +			 va_list *ap ATTRIBUTE_UNUSED)
> +{
> +  warn_if_plugins ();
> +  emergency_dump_function ();

What if there is another ICE during the dumping?  Won't we then
end in endless recursion?  Perhaps global_dc->internal_error should
be cleared here first?
Also, as none of the arguments are used and we are in C++,
perhaps it should be
static void
internal_error_function (diagnostic_context *, const char *, va_list *)
{
?

	Jakub
Alexander Monakov May 29, 2017, 4:34 p.m. UTC | #2
On Mon, 29 May 2017, Jakub Jelinek wrote:
> What if there is another ICE during the dumping?  Won't we then
> end in endless recursion?  Perhaps global_dc->internal_error should
> be cleared here first?

Hm, no, as far as I can see existing diagnostic machinery is supposed to fully
handle that.  It detects recursion; see e.g. diagnostic.c: error_recursion.

> Also, as none of the arguments are used and we are in C++,
> perhaps it should be
> static void
> internal_error_function (diagnostic_context *, const char *, va_list *)
> {
> ?

Ah, it seems GCC tends to use either the long-winded form I've copy-pasted in my
patch, or the slightly shorter variant with 'type_name ARG_UNUSED (arg_name)'.
The shorthand form you're pointing out seems to be used only once, in
vmsdbgout.c, as far as I can tell.  I'll be happy to change my patch as desired
by the reviewer, of course :)

Alexander
Andi Kleen May 29, 2017, 4:42 p.m. UTC | #3
On Mon, May 29, 2017 at 07:15:33PM +0300, Alexander Monakov wrote:
> Hi,
> 
> On Wed, 24 May 2017, Richard Biener wrote:
> > current_pass might be NULL so you better do set_internal_error_hook when
> > we start executing passes (I detest global singletons to do such stuff anyway).
> 
> I think there are other problems in this patch, dump_function_to_file won't work
> after transition to RTL (it only handles GIMPLE).  It's much better to just use
> existing dump routine in passes.c and use the existing diagnostic callbacks.

Your patch looks good to me.

Thanks,
-Andi
Alexander Monakov May 29, 2017, 4:46 p.m. UTC | #4
On Mon, 29 May 2017, Alexander Monakov wrote:
> On Mon, 29 May 2017, Jakub Jelinek wrote:
> > Also, as none of the arguments are used and we are in C++,
> > perhaps it should be
> > static void
> > internal_error_function (diagnostic_context *, const char *, va_list *)
> > {
> > ?
> 
> Ah, it seems GCC tends to use either the long-winded form I've copy-pasted in my
> patch, or the slightly shorter variant with 'type_name ARG_UNUSED (arg_name)'.
> The shorthand form you're pointing out seems to be used only once, in
> vmsdbgout.c, as far as I can tell.

Scratch this, I totally botched my grep invocation.  There's plenty of instances
where the shorthand form is used, and I'll be happy to use it here as well.

Alexander
Jakub Jelinek May 29, 2017, 4:53 p.m. UTC | #5
On Mon, May 29, 2017 at 07:46:22PM +0300, Alexander Monakov wrote:
> On Mon, 29 May 2017, Alexander Monakov wrote:
> > On Mon, 29 May 2017, Jakub Jelinek wrote:
> > > Also, as none of the arguments are used and we are in C++,
> > > perhaps it should be
> > > static void
> > > internal_error_function (diagnostic_context *, const char *, va_list *)
> > > {
> > > ?
> > 
> > Ah, it seems GCC tends to use either the long-winded form I've copy-pasted in my
> > patch, or the slightly shorter variant with 'type_name ARG_UNUSED (arg_name)'.
> > The shorthand form you're pointing out seems to be used only once, in
> > vmsdbgout.c, as far as I can tell.
> 
> Scratch this, I totally botched my grep invocation.  There's plenty of instances
> where the shorthand form is used, and I'll be happy to use it here as well.

Generally, ARG_UNUSED or ATTRIBUTE_UNUSED needs to be used if the argument
is used conditionally (e.g. in macro that on some target uses its argument
and on another target ignores it).  Otherwise, sometimes somebody wants to
make clear what the names of the ignored arguments are, in that case one
can use those 2 forms too.  If the arguments are not used and it isn't
important how they are called, C++ omitted argument names are fine.

	Jakub
Alexander Monakov May 29, 2017, 6:10 p.m. UTC | #6
On Mon, 29 May 2017, Alexander Monakov wrote:
> +/* This helper function is invoked from diagnostic routines prior to aborting
> +   due to internal compiler error.  If a dump file is set up, dump the
> +   current function.  */
> +
> +void
> +emergency_dump_function ()
> +{
> +  if (!dump_file || !current_pass || !cfun)
> +    return;
> +  fnotice (stderr, "function dumped to file %s\n", dump_file_name);
> +  execute_function_dump (cfun, current_pass);
> +}

I've noticed that the notice is not terribly useful.  Perhaps it's better to
mention the failing pass when not producing the dump (untested):

void
emergency_dump_function ()
{
  if (!current_pass || !cfun)
    return;
  if (dump_file)
    {
      fnotice (stderr, "dump file: %s\n", dump_file_name);
      execute_function_dump (cfun, current_pass);
    }
  else if (current_pass->name[0] != '*')
    {
      enum opt_pass_type pt = current_pass->type;
      fnotice (stderr, "during %s pass: %s\n", 
	       pt == GIMPLE_PASS ? "GIMPLE" : pt == RTL_PASS ? "RTL" : "IPA",
	       current_pass->name);
    }
}

Alexander
Richard Biener May 30, 2017, 7:13 a.m. UTC | #7
On Mon, May 29, 2017 at 8:10 PM, Alexander Monakov <amonakov@ispras.ru> wrote:
> On Mon, 29 May 2017, Alexander Monakov wrote:
>> +/* This helper function is invoked from diagnostic routines prior to aborting
>> +   due to internal compiler error.  If a dump file is set up, dump the
>> +   current function.  */
>> +
>> +void
>> +emergency_dump_function ()
>> +{
>> +  if (!dump_file || !current_pass || !cfun)
>> +    return;
>> +  fnotice (stderr, "function dumped to file %s\n", dump_file_name);
>> +  execute_function_dump (cfun, current_pass);
>> +}
>
> I've noticed that the notice is not terribly useful.  Perhaps it's better to
> mention the failing pass when not producing the dump (untested):
>
> void
> emergency_dump_function ()
> {
>   if (!current_pass || !cfun)
>     return;
>   if (dump_file)
>     {
>       fnotice (stderr, "dump file: %s\n", dump_file_name);
>       execute_function_dump (cfun, current_pass);
>     }
>   else if (current_pass->name[0] != '*')
>     {
>       enum opt_pass_type pt = current_pass->type;
>       fnotice (stderr, "during %s pass: %s\n",
>                pt == GIMPLE_PASS ? "GIMPLE" : pt == RTL_PASS ? "RTL" : "IPA",
>                current_pass->name);
>     }
> }

If you want to improve here I'd do

   if (current_pass)
     fnotice (stderr, "during %s pass: %s\n", ...
   if (dump_file && cfun)
     {
        fnotice (..);
        execute_function_dump ...
     }

and I'd print the pass name even if it starts with '*' (that just
means it won't get a dumpfile).

Generally the patch looks good to me.

Thanks,
Richard.

> Alexander
diff mbox

Patch

diff --git a/gcc/passes.c b/gcc/passes.c
index 98e05e4..e8e0322 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -60,6 +60,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-live.h"  /* For remove_unused_locals.  */
 #include "tree-cfgcleanup.h"
 #include "insn-addr.h" /* for INSN_ADDRESSES_ALLOC.  */
+#include "diagnostic-core.h" /* for fnotice */
 
 using namespace gcc;
 
@@ -1779,6 +1780,19 @@  execute_function_dump (function *fn, void *data)
     }
 }
 
+/* This helper function is invoked from diagnostic routines prior to aborting
+   due to internal compiler error.  If a dump file is set up, dump the
+   current function.  */
+
+void
+emergency_dump_function ()
+{
+  if (!dump_file || !current_pass || !cfun)
+    return;
+  fnotice (stderr, "function dumped to file %s\n", dump_file_name);
+  execute_function_dump (cfun, current_pass);
+}
+
 static struct profile_record *profile_record;
 
 /* Do profile consistency book-keeping for the pass with static number INDEX.
diff --git a/gcc/plugin.c b/gcc/plugin.c
index c6d3cdd..9892748 100644
--- a/gcc/plugin.c
+++ b/gcc/plugin.c
@@ -858,16 +858,6 @@  warn_if_plugins (void)
 
 }
 
-/* Likewise, as a callback from the diagnostics code.  */
-
-void
-plugins_internal_error_function (diagnostic_context *context ATTRIBUTE_UNUSED,
-				 const char *msgid ATTRIBUTE_UNUSED,
-				 va_list *ap ATTRIBUTE_UNUSED)
-{
-  warn_if_plugins ();
-}
-
 /* The default version check. Compares every field in VERSION. */
 
 bool
diff --git a/gcc/plugin.h b/gcc/plugin.h
index 68a673b..b96445d 100644
--- a/gcc/plugin.h
+++ b/gcc/plugin.h
@@ -167,8 +167,6 @@  extern bool plugins_active_p (void);
 extern void dump_active_plugins (FILE *);
 extern void debug_active_plugins (void);
 extern void warn_if_plugins (void);
-extern void plugins_internal_error_function (diagnostic_context *,
-					     const char *, va_list *);
 extern void print_plugins_versions (FILE *file, const char *indent);
 extern void print_plugins_help (FILE *file, const char *indent);
 extern void finalize_plugins (void);
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 425315c..23b884a 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -79,6 +79,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "omp-offload.h"
 #include "hsa-common.h"
 #include "edit-context.h"
+#include "tree-pass.h"
 
 #if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO)
 #include "dbxout.h"
@@ -1063,6 +1064,17 @@  open_auxiliary_file (const char *ext)
   return file;
 }
 
+/* Auxiliary callback for the diagnostics code.  */
+
+static void
+internal_error_function (diagnostic_context *context ATTRIBUTE_UNUSED,
+			 const char *msgid ATTRIBUTE_UNUSED,
+			 va_list *ap ATTRIBUTE_UNUSED)
+{
+  warn_if_plugins ();
+  emergency_dump_function ();
+}
+
 /* Initialization of the front end environment, before command line
    options are parsed.  Signal handlers, internationalization etc.
    ARGV0 is main's argv[0].  */
@@ -1101,7 +1113,7 @@  general_init (const char *argv0, bool init_signals)
     = global_options_init.x_flag_diagnostics_show_option;
   global_dc->show_column
     = global_options_init.x_flag_show_column;
-  global_dc->internal_error = plugins_internal_error_function;
+  global_dc->internal_error = internal_error_function;
   global_dc->option_enabled = option_enabled;
   global_dc->option_state = &global_options;
   global_dc->option_name = option_name;
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index cfa4b01..0f7d936 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -634,6 +634,7 @@  extern void execute_all_ipa_transforms (void);
 extern void execute_all_ipa_stmt_fixups (struct cgraph_node *, gimple **);
 extern bool pass_init_dump_file (opt_pass *);
 extern void pass_fini_dump_file (opt_pass *);
+extern void emergency_dump_function (void);
 
 extern void print_current_pass (FILE *);
 extern void debug_pass (void);