RFC: [patch] launching compiler through a wrapper

Thomas Quinot quinot@adacore.com
Fri Mar 6 11:08:00 GMT 2009


I would like to propose a new feature of the gcc driver to allow
launching the underlying compiler in a debugger session. This is useful
when debugging the compiler, since this guarantees that the debugging
session is started in the exact same context (environment, temporary
files...) as for a "normal" invocation of the compiler (whereas if you
start the debugging session manually, you have to have other means to
reconstitute these conditions, which may be impractical).

There is already support in the compiler for running spawned processes
through valgrind, so a possible implementation of the above idea is to
generalize this circuitry, allowing an arbitrary "wrapper" to be
specified when executing a command.

Included below is a first implementation of this idea, where the wrapper
command is specified using environment variable GCC_WRAP_COMPILER.
A typical simple usage is to set GCC_WRAP_COMPILER="gdb --args".

This isn't a final patch, it has not received extensive testing yet,
but I would welcome comments so that the design and implementation can
be refined and made into something that can be integrated.

Thanks!
Thomas.

*** gcc/gcc.c	2009-03-05 05:15:58.000000000 +0100
--- gcc/gcc.c	2009-03-05 17:37:48.023600280 +0100
***************
*** 2861,2866 ****
--- 2861,2874 ----
      const char **argv;		/* vector of args.  */
    };
  
+ #ifdef ENABLE_VALGRIND_CHECKING
+   /* Use valgrind as default command wrapper.  */
+   const char *default_wrapper_cmd = VALGRIND_PATH " -q";
+ #else
+   const char *default_wrapper_cmd = "";
+ #endif
+   const char *wrapper_cmd = NULL;
+ 
    struct command *commands;	/* each command buffer with above info.  */
  
    gcc_assert (!processing_spec_function);
***************
*** 2962,2993 ****
  #endif /* DEBUG */
      }
  
! #ifdef ENABLE_VALGRIND_CHECKING
!   /* Run the each command through valgrind.  To simplify prepending the
!      path to valgrind and the option "-q" (for quiet operation unless
!      something triggers), we allocate a separate argv array.  */
  
!   for (i = 0; i < n_commands; i++)
!     {
!       const char **argv;
!       int argc;
!       int j;
  
!       for (argc = 0; commands[i].argv[argc] != NULL; argc++)
! 	;
  
!       argv = alloca ((argc + 3) * sizeof (char *));
  
!       argv[0] = VALGRIND_PATH;
!       argv[1] = "-q";
!       for (j = 2; j < argc + 2; j++)
! 	argv[j] = commands[i].argv[j - 2];
!       argv[j] = NULL;
  
!       commands[i].argv = argv;
!       commands[i].prog = argv[0];
      }
- #endif
  
    /* Run each piped subprocess.  */
  
--- 2970,3027 ----
  #endif /* DEBUG */
      }
  
!   /* Optionally run each command through a user specified wrapper.  */
  
!   wrapper_cmd = getenv ("GCC_WRAP_COMPILER");
!   if (!wrapper_cmd)
!     wrapper_cmd = default_wrapper_cmd;
  
!   if (*wrapper_cmd)
!     {
!       int wrapper_argc = 1;
!       const char **wrapper_argv;
!       const char *wstart, *wend;
  
!       for (wstart = wrapper_cmd; *wstart; wstart++)
!         {
!           if (*wstart == ' ')
!             wrapper_argc++;
!         }
!       wrapper_argv = alloca (wrapper_argc * sizeof (char*));
!       wstart = wrapper_cmd;
!       i = 0;
!       while (*wstart) {
!         wend = wstart;
!         while (*(wend + 1) && *(wend + 1) != ' ')
!           wend++;
!         wrapper_argv[i++] = xstrndup (wstart, wend - wstart + 1);
!         wstart = wend + 1;
!         while (*wstart == ' ')
!           wstart++;
!       }
!       wrapper_argc = i;
  
!       for (i = 0; i < n_commands; i++)
!         {
!           const char **argv;
!           int argc;
!           int j;
! 
!           for (argc = 0; commands[i].argv[argc] != NULL; argc++)
!             ;
!           argv = alloca ((argc + wrapper_argc + 1) * sizeof (char *));
! 
!           for (j = 0; j < wrapper_argc;j++)
!             argv[j] = wrapper_argv[j];
! 
!           for (; j < wrapper_argc + argc; j++)
!             argv[j] = commands[i].argv[j - wrapper_argc];
!           argv[j] = NULL;
  
!           commands[i].argv = argv;
!           commands[i].prog = argv[0];
!         }
      }
  
    /* Run each piped subprocess.  */
  
-- 
Thomas Quinot, Ph.D. ** quinot@adacore.com ** Senior Software Engineer
               AdaCore -- Paris, France -- New York, USA



More information about the Gcc-patches mailing list