On Mon, May 26, 2014 at 11:54:04AM +0400, Maxim Ostapenko wrote:
> Hi,
> 
> A years ago there was a discussion (
> https://gcc.gnu.org/ml/gcc-patches/2004-01/msg02437.html) about debugging
> compiler ICEs that resulted in a patch from Jakub, which dumps useful
> information into temporary file, but for some reasons this patch wasn't
> applied to trunk.
> 
> Is this still considered a useful feature for 4.10? If yes, we can resurrect
> and submit this patch.

definitely! bonus points if you handle building with FDO enabled.

thanks!

Trev

> 
> -Maxim

> # DP: Retry the build on an ice, save the calling options and preprocessed
> # DP: source when the ice is reproducible.
> 
> 2004-01-23  Jakub Jelinek  <ja...@redhat.com>
> 
>       * gcc.c (execute): Don't free first string early, but at the end
>       of the function.  Call retry_ice if compiler exited with
>       ICE_EXIT_CODE.
>       (retry_ice): New function.
>       * diagnostic.c (diagnostic_count_diagnostic,
>       diagnostic_action_after_output, error_recursion): Exit with
>       ICE_EXIT_CODE instead of FATAL_EXIT_CODE.
> 
> #--- a/src/gcc/Makefile.in
> #+++ b/src/gcc/Makefile.in
> #@@ -181,6 +181,8 @@ SYSCALLS.c.X-warn = -Wno-strict-prototypes -Wno-error
> # dfp.o-warn = -Wno-error
> # # mips-tfile.c contains -Wcast-qual warnings.
> # mips-tfile.o-warn = -Wno-error
> #+# gcc-ice-hack
> #+gcc.o-warn = -Wno-error
> # 
> # # All warnings have to be shut off in stage1 if the compiler used then
> # # isn't gcc; configure determines that.  WARN_CFLAGS will be either
> --- a/src/gcc/gcc.c
> +++ b/src/gcc/gcc.c
> @@ -250,6 +250,9 @@
>  #if defined(HAVE_TARGET_OBJECT_SUFFIX) || 
> defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
>  static const char *convert_filename (const char *, int, int);
>  #endif
> +#if !(defined (__MSDOS__) || defined (OS2) || defined (VMS))
> +static void retry_ice (const char *prog, const char **argv);
> +#endif
>  
>  static const char *getenv_spec_function (int, const char **);
>  static const char *if_exists_spec_function (int, const char **);
> @@ -2638,7 +2643,7 @@
>           }
>       }
>  
> -      if (string != commands[i].prog)
> +      if (i && string != commands[i].prog)
>       free (CONST_CAST (char *, string));
>      }
>  
> @@ -2691,6 +2696,16 @@
>       else if (WIFEXITED (status)
>                && WEXITSTATUS (status) >= MIN_FATAL_STATUS)
>         {
> +#if !(defined (__MSDOS__) || defined (OS2) || defined (VMS))
> +         /* For ICEs in cc1, cc1obj, cc1plus see if it is
> +            reproducible or not.  */
> +         const char *p;
> +         if (WEXITSTATUS (status) == ICE_EXIT_CODE
> +             && i == 0
> +             && (p = strrchr (commands[0].argv[0], DIR_SEPARATOR))
> +             && ! strncmp (p + 1, "cc1", 3))
> +           retry_ice (commands[0].prog, commands[0].argv);
> +#endif
>           if (WEXITSTATUS (status) > greatest_status)
>             greatest_status = WEXITSTATUS (status);
>           ret_code = -1;
> @@ -2748,6 +2763,9 @@
>         }
>        }
>  
> +    if (commands[0].argv[0] != commands[0].prog)
> +      free (CONST_CAST (char *, commands[0].argv[0]));
> +
>      return ret_code;
>    }
>  }
> @@ -5874,6 +5892,227 @@
>    switches[switchnum].validated = 1;
>  }
>  
> +#if !(defined (__MSDOS__) || defined (OS2) || defined (VMS))
> +#define RETRY_ICE_ATTEMPTS 2
> +
> +static void
> +retry_ice (const char *prog, const char **argv)
> +{
> +  int nargs, out_arg = -1, quiet = 0, attempt;
> +  int pid, retries, sleep_interval;
> +  const char **new_argv;
> +  char *temp_filenames[RETRY_ICE_ATTEMPTS * 2 + 2];
> +
> +  if (gcc_input_filename == NULL || ! strcmp (gcc_input_filename, "-"))
> +    return;
> +
> +  for (nargs = 0; argv[nargs] != NULL; ++nargs)
> +    /* Only retry compiler ICEs, not preprocessor ones.  */
> +    if (! strcmp (argv[nargs], "-E"))
> +      return;
> +    else if (argv[nargs][0] == '-' && argv[nargs][1] == 'o')
> +      {
> +     if (out_arg == -1)
> +       out_arg = nargs;
> +     else
> +       return;
> +      }
> +    /* If the compiler is going to output any time information,
> +       it might varry between invocations.  */
> +    else if (! strcmp (argv[nargs], "-quiet"))
> +      quiet = 1;
> +    else if (! strcmp (argv[nargs], "-ftime-report"))
> +      return;
> +
> +  if (out_arg == -1 || !quiet)
> +    return;
> +
> +  memset (temp_filenames, '\0', sizeof (temp_filenames));
> +  new_argv = XALLOCAVEC (const char *, nargs + 3);
> +  memcpy (new_argv, argv, (nargs + 1) * sizeof (const char *));
> +  new_argv[nargs++] = "-frandom-seed=0";
> +  new_argv[nargs] = NULL;
> +  if (new_argv[out_arg][2] == '\0')
> +    new_argv[out_arg + 1] = "-";
> +  else
> +    new_argv[out_arg] = "-o-";
> +
> +  for (attempt = 0; attempt < RETRY_ICE_ATTEMPTS + 1; ++attempt)
> +    {
> +      int fd = -1;
> +      int status;
> +
> +      temp_filenames[attempt * 2] = make_temp_file (".out");
> +      temp_filenames[attempt * 2 + 1] = make_temp_file (".err");
> +
> +      if (attempt == RETRY_ICE_ATTEMPTS)
> +        {
> +       int i;
> +       int fd1, fd2;
> +       struct stat st1, st2;
> +       size_t n, len;
> +       char *buf;
> +
> +       buf = XNEWVEC (char, 8192);
> +
> +       for (i = 0; i < 2; ++i)
> +         {
> +           fd1 = open (temp_filenames[i], O_RDONLY);
> +           fd2 = open (temp_filenames[2 + i], O_RDONLY);
> +
> +           if (fd1 < 0 || fd2 < 0)
> +             {
> +               i = -1;
> +               close (fd1);
> +               close (fd2);
> +               break;
> +             }
> +
> +           if (fstat (fd1, &st1) < 0 || fstat (fd2, &st2) < 0)
> +             {
> +               i = -1;
> +               close (fd1);
> +               close (fd2);
> +               break;
> +             }
> +
> +           if (st1.st_size != st2.st_size)
> +             {
> +               close (fd1);
> +               close (fd2);
> +               break;
> +             }
> +
> +           len = 0;
> +           for (n = st1.st_size; n; n -= len)
> +             {
> +               len = n;
> +               if (len > 4096)
> +                 len = 4096;
> +
> +               if (read (fd1, buf, len) != (int) len
> +                   || read (fd2, buf + 4096, len) != (int) len)
> +                 {
> +                   i = -1;
> +                   break;
> +                 }
> +
> +               if (memcmp (buf, buf + 4096, len) != 0)
> +                 break;
> +             }
> +
> +           close (fd1);
> +           close (fd2);
> +
> +           if (n)
> +             break;
> +         }
> +
> +       free (buf);
> +       if (i == -1)
> +         break;
> +
> +       if (i != 2)
> +         {
> +           fnotice (stderr, "The bug is not reproducible, so it is"
> +                            " likely a hardware or OS problem.\n");
> +           break;
> +         }
> +
> +          fd = open (temp_filenames[attempt * 2], O_RDWR);
> +       if (fd < 0)
> +         break;
> +       write (fd, "//", 2);
> +       for (i = 0; i < nargs; i++)
> +         {
> +           write (fd, " ", 1);
> +           write (fd, new_argv[i], strlen (new_argv[i]));
> +         }
> +       write (fd, "\n", 1);
> +       new_argv[nargs] = "-E";
> +       new_argv[nargs + 1] = NULL;
> +        }
> +
> +      /* Fork a subprocess; wait and retry if it fails.  */
> +      sleep_interval = 1;
> +      pid = -1;
> +      for (retries = 0; retries < 4; retries++)
> +     {
> +       pid = fork ();
> +       if (pid >= 0)
> +         break;
> +       sleep (sleep_interval);
> +       sleep_interval *= 2;
> +     }
> +
> +      if (pid < 0)
> +     break;
> +      else if (pid == 0)
> +     {
> +       if (attempt != RETRY_ICE_ATTEMPTS)
> +         fd = open (temp_filenames[attempt * 2], O_RDWR);
> +       if (fd < 0)
> +         exit (-1);
> +       if (fd != 1)
> +         {
> +           close (1);
> +           dup (fd);
> +           close (fd);
> +         }
> +
> +       fd = open (temp_filenames[attempt * 2 + 1], O_RDWR);
> +       if (fd < 0)
> +         exit (-1);
> +       if (fd != 2)
> +         {
> +           close (2);
> +           dup (fd);
> +           close (fd);
> +         }
> +
> +       if (prog == new_argv[0])
> +         execvp (prog, CONST_CAST2 (char *const *, const char **, new_argv));
> +       else
> +         execv (new_argv[0], CONST_CAST2 (char *const *, const char **, 
> new_argv));
> +       exit (-1);
> +     }
> +
> +      if (waitpid (pid, &status, 0) < 0)
> +     break;
> +
> +      if (attempt < RETRY_ICE_ATTEMPTS
> +       && (! WIFEXITED (status) || WEXITSTATUS (status) != ICE_EXIT_CODE))
> +     {
> +       fnotice (stderr, "The bug is not reproducible, so it is"
> +                        " likely a hardware or OS problem.\n");
> +       break;
> +     }
> +      else if (attempt == RETRY_ICE_ATTEMPTS)
> +     {
> +       close (fd);
> +       if (WIFEXITED (status)
> +           && WEXITSTATUS (status) == SUCCESS_EXIT_CODE)
> +         {
> +           fnotice (stderr, "Preprocessed source stored into %s file,"
> +                            " please attach this to your bugreport.\n",
> +                    temp_filenames[attempt * 2]);
> +           /* Make sure it is not deleted.  */
> +           free (temp_filenames[attempt * 2]);
> +           temp_filenames[attempt * 2] = NULL;
> +           break;
> +         }
> +     }
> +    }
> +
> +  for (attempt = 0; attempt < RETRY_ICE_ATTEMPTS * 2 + 2; attempt++)
> +    if (temp_filenames[attempt])
> +      {
> +     unlink (temp_filenames[attempt]);
> +     free (temp_filenames[attempt]);
> +      }
> +}
> +#endif
> +
>  /* Search for a file named NAME trying various prefixes including the
>     user's -B prefix and some standard ones.
>     Return the absolute file name found.  If nothing is found, return NAME.  
> */
> --- a/src/gcc/diagnostic.c
> +++ b/src/gcc/diagnostic.c
> @@ -247,7 +247,7 @@
>       real_abort ();
>        diagnostic_finish (context);
>        fnotice (stderr, "compilation terminated.\n");
> -      exit (FATAL_EXIT_CODE);
> +      exit (ICE_EXIT_CODE);
>  
>      default:
>        gcc_unreachable ();

Attachment: signature.asc
Description: Digital signature

Reply via email to