332 lines
8.5 KiB
Plaintext
332 lines
8.5 KiB
Plaintext
#! /bin/sh -e
|
||
|
||
# DP: Retry the build on an ice, save the calling options and preprocessed
|
||
# DP: source when the ice is reproducible.
|
||
|
||
dir=
|
||
if [ $# -eq 3 -a "$2" = '-d' ]; then
|
||
pdir="-d $3"
|
||
dir="$3/"
|
||
elif [ $# -ne 1 ]; then
|
||
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
|
||
exit 1
|
||
fi
|
||
case "$1" in
|
||
-patch)
|
||
patch $pdir -f --no-backup-if-mismatch -p0 < $0
|
||
;;
|
||
-unpatch)
|
||
patch $pdir -f --no-backup-if-mismatch -R -p0 < $0
|
||
;;
|
||
*)
|
||
echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
|
||
exit 1
|
||
esac
|
||
exit 0
|
||
|
||
2004-01-23 Jakub Jelinek <jakub@redhat.com>
|
||
|
||
* system.h (ICE_EXIT_CODE): Define.
|
||
* 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.
|
||
|
||
--- gcc/diagnostic.c.orig 2007-09-30 10:48:13.000000000 +0000
|
||
+++ gcc/diagnostic.c 2007-09-30 10:49:57.000000000 +0000
|
||
@@ -244,7 +244,7 @@
|
||
fnotice (stderr, "Please submit a full bug report,\n"
|
||
"with preprocessed source if appropriate.\n"
|
||
"See %s for instructions.\n", bug_report_url);
|
||
- exit (ICE_EXIT_CODE);
|
||
+ exit (FATAL_EXIT_CODE);
|
||
|
||
case DK_FATAL:
|
||
if (context->abort_on_error)
|
||
--- gcc/gcc.c.orig 2007-09-30 10:48:13.000000000 +0000
|
||
+++ gcc/gcc.c 2007-09-30 10:48:39.000000000 +0000
|
||
@@ -357,6 +357,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 **);
|
||
@@ -2999,7 +3002,7 @@
|
||
}
|
||
}
|
||
|
||
- if (string != commands[i].prog)
|
||
+ if (i && string != commands[i].prog)
|
||
free (CONST_CAST (char *, string));
|
||
}
|
||
|
||
@@ -3056,6 +3059,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. */
|
||
+ 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;
|
||
@@ -3076,6 +3089,9 @@
|
||
}
|
||
}
|
||
|
||
+ if (commands[0].argv[0] != commands[0].prog)
|
||
+ free ((PTR) commands[0].argv[0]);
|
||
+
|
||
return ret_code;
|
||
}
|
||
}
|
||
@@ -6016,6 +6032,224 @@
|
||
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 (input_filename == NULL || ! strcmp (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 vary 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 = alloca ((nargs + 3) * sizeof (const char *));
|
||
+ 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 = xmalloc (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)
|
||
+ {
|
||
+ notice ("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, (char *const *) new_argv);
|
||
+ else
|
||
+ execv (new_argv[0], (char *const *) new_argv);
|
||
+ exit (-1);
|
||
+ }
|
||
+
|
||
+ if (waitpid (pid, &status, 0) < 0)
|
||
+ break;
|
||
+
|
||
+ if (attempt < RETRY_ICE_ATTEMPTS
|
||
+ && (! WIFEXITED (status) || WEXITSTATUS (status) != ICE_EXIT_CODE))
|
||
+ {
|
||
+ notice ("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)
|
||
+ {
|
||
+ notice ("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. */
|
||
--- gcc/Makefile.in.orig 2007-09-30 10:48:13.000000000 +0000
|
||
+++ gcc/Makefile.in 2007-09-30 10:48:39.000000000 +0000
|
||
@@ -192,6 +192,7 @@
|
||
build/gengtype-lex.o-warn = -Wno-error
|
||
# SYSCALLS.c misses prototypes
|
||
SYSCALLS.c.X-warn = -Wno-strict-prototypes -Wno-error
|
||
+build/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
|