From patchwork Mon May 26 07:54:04 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: max X-Patchwork-Id: 352378 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4EFFE140082 for ; Mon, 26 May 2014 17:54:20 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; q=dns; s=default; b=exZef/LTCz4i6T0EO vbDwROeAgxelDwcYIxfWMYErXg2hvFyXF8P956emjU/BZHoKhtFDiaU0u5qc8NRL VUbAEW8rHjdaTNgC/NX48baPDSAH/vC08Mjz3eNEaxNr5UJYiSY6NZ0l2sDfjEMy RHKavy1k7yGGBuPnLESC+hNbtk= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; s=default; bh=fnrfutCbLpafJQ4TiN6gg0F 5cTw=; b=ikuLM5Ok+UQLQJ6ZTP2FBRuXeKYg6SsvBLt+mmgQqM3YYP8izXslPzT fd3YgbtI2RMZziki8AGUg9FXCkR5M795i0IxuRA4rAxDHFneIJEG9bNppO3ERmJU ERZytEvWQ6EusWkP2MryEjfBbZ8mi/zEttlULi0QCVhgu8Tl0Wjw= Received: (qmail 13337 invoked by alias); 26 May 2014 07:54:13 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 13324 invoked by uid 89); 26 May 2014 07:54:12 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 X-HELO: mailout1.w1.samsung.com Received: from mailout1.w1.samsung.com (HELO mailout1.w1.samsung.com) (210.118.77.11) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (DES-CBC3-SHA encrypted) ESMTPS; Mon, 26 May 2014 07:54:10 +0000 Received: from eucpsbgm1.samsung.com (unknown [203.254.199.244]) by mailout1.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0N66004FK8M36430@mailout1.w1.samsung.com> for gcc-patches@gcc.gnu.org; Mon, 26 May 2014 08:54:03 +0100 (BST) Received: from eusync4.samsung.com ( [203.254.199.214]) by eucpsbgm1.samsung.com (EUCPMTA) with SMTP id CA.F3.27902.D13F2835; Mon, 26 May 2014 08:54:05 +0100 (BST) Received: from [106.109.9.72] by eusync4.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0N6600DLU8M48S40@eusync4.samsung.com>; Mon, 26 May 2014 08:54:05 +0100 (BST) Message-id: <5382F31C.3080302@partner.samsung.com> Date: Mon, 26 May 2014 11:54:04 +0400 From: Maxim Ostapenko User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.1.0 MIME-version: 1.0 To: GCC Patches Cc: Yury Gribov , Slava Garbuzov , Jakub Jelinek Subject: [RFC] Add patch for debugging compiler ICEs References: <5382E99C.5070601@partner.samsung.com> <5382F05F.8090909@samsung.com> In-reply-to: <5382F05F.8090909@samsung.com> Content-type: multipart/mixed; boundary=------------000708040801030606020509 X-IsSubscribed: yes 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. -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 * 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 ();