This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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
     {

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]