This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix bootstrap on cygwin
- From: Dave Korn <dave dot korn dot cygwin at gmail dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 28 May 2010 19:18:18 +0100
- Subject: [PATCH] Fix bootstrap on cygwin
Hi,
Bootstrapping on i686-pc-cygwin at r.159959 failed for me during stage3
target libobjc. xgcc was crashing with a segfault which didn't reproduce
under gdb.
After a bit of tricky debugging, I worked out that it was crashing in the
cygwin GCC_DRIVER_HOST_INITIALIZATION hook, in a "while (*++argv)" loop. It's
sometimes overlooked that the argv[] array is actually one larger than argc
would seem to suggest, as it always has a trailing NULL pointer that isn't
counted in argc; it's easy to unconsciously assume that argc is the size of
the array and argv[argc] would be an overflow, but it's not; this crash was
happening precisely when accessing the argc'th member of argv.
The problem was caused by prune_options, which (if it has to remove any
options) returns a replacement argv, in which only the elements [0] ...
[argc-1] have been initialised. It cropped up where it did for the first time
during bootstrap because libobjc has "-fexceptions" twice in its CFLAGS, which
triggered prune_options to actually prune options for the first time. When
not running under a debugger, this led to an uninitialised and non-zero value
in the [argc]'th element of argv[], which (fortuitously, otherwise I might
never have noticed it) caused a segfault in the target hook.
The attached patch trivially adds the terminating NULL entry to the new argv
array just past the final valid option.
gcc/ChangeLog:
* opts-common.c (prune_options): Ensure replacement argv array
is correctly terminated by a NULL entry.
It fixed the crash case I was testing from the libobjc build, so I'm giving
it a full bootstrap cycle now. OK assuming it completes and nothing abnormal
shows up in the testsuite?
cheers,
DaveK
Index: opts-common.c
===================================================================
--- opts-common.c (revision 158982)
+++ opts-common.c (working copy)
@@ -132,6 +132,10 @@ prune_options (int *argcp, char ***argvp)
{
int argc = *argcp;
int *options = XNEWVEC (int, argc);
+ /* We will only return this replacement argv if we remove at least
+ one argument, so it does not need to be size (argc + 1) to
+ make room for the terminating NULL because we will always have
+ freed up at least one slot when we end up using it at all. */
char **argv = XNEWVEC (char *, argc);
int i, arg_count, need_prune = 0;
const struct cl_option *option;
@@ -225,6 +229,9 @@ keep:
{
*argcp = arg_count;
*argvp = argv;
+ /* Add NULL-termination. Guaranteed not to overflow because
+ arg_count here can only be less than argc. */
+ argv[arg_count] = 0;
}
else
{