From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 534 invoked by alias); 5 Oct 2011 11:40:24 -0000 Received: (qmail 390 invoked by uid 22791); 5 Oct 2011 11:39:59 -0000 X-Spam-Check-By: sourceware.org Received: from aquarius.hirmke.de (HELO calimero.vinschen.de) (217.91.18.234) by sourceware.org (qpsmtpd/0.83/v0.83-20-g38e4449) with ESMTP; Wed, 05 Oct 2011 11:39:44 +0000 Received: by calimero.vinschen.de (Postfix, from userid 500) id C0D8C2C00DB; Wed, 5 Oct 2011 13:39:41 +0200 (CEST) Date: Wed, 05 Oct 2011 11:40:00 -0000 From: Corinna Vinschen To: gdb-patches@sourceware.org Subject: Re: [RFA] testsuite: Add a test for passing of environment variables to inferior Message-ID: <20111005113941.GA13366@calimero.vinschen.de> Reply-To: gdb-patches@sourceware.org Mail-Followup-To: gdb-patches@sourceware.org References: <006301cc8292$367539b0$a35fad10$@muller@ics-cnrs.unistra.fr> <20111004134506.GB24369@calimero.vinschen.de> <000901cc82a4$dfba7cd0$9f2f7670$@muller@ics-cnrs.unistra.fr> <20111004151236.GC15757@calimero.vinschen.de> <003901cc82b0$471e3a00$d55aae00$@muller@ics-cnrs.unistra.fr> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <003901cc82b0$471e3a00$d55aae00$@muller@ics-cnrs.unistra.fr> User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-10/txt/msg00128.txt.bz2 On Oct 4 18:11, Pierre Muller wrote: > here is an update that unsets all environment > variables both in environ list before calling > CreateProcess and in in_env list after... > > This passes the new updated test I just sent. Oh boy, I guess there's no way around that for now. I will create a new cygwin_internal call for just such a scenario, as proposed in http://sourceware.org/ml/gdb-patches/2011-10/msg00079.html and add a patch to GDB to use it if it's available. That way, we can limit this complicated method to current and older versions of Cygwin. > + /* Reset all environment variables to avoid leftover on next run. */ > + for (i = 0; environ[i] && *environ[i]; i++) > + { > + char *equalpos; > + char *copy = alloca (strlen(environ[i]) + 1); If the environment is very large, using alloca here in a loop might result in a stack overflow. Pretty unlikely, I assume, but possible. > + strcpy (copy, environ[i]); > + equalpos = strchr (copy, '='); > + if (equalpos) > + *equalpos = '\0'; > + SetEnvironmentVariableA (copy, NULL); Since Cygwin 1.7, the Cygwin multibyte charset does not correspond with the current Windows ANSI codepage. Cygwin's default multibyte charset is UTF-8, for instance, while the ANSI Windows functions will use some arbitrary Windows codepage depending on system and user language. So we should convert the variables to UNICODE and use the corresponding Win32 function. Here's my proposal, based on your patch. I'll work on using the yet-to-be-created new cygwin_internal call after I implemented it in Cygwin. * windows-nat.c: Include wchar.h to avoid compiler warnings. (clear_win32_environment): New function for Cygwin to clear out Win32 environment. (windows_create_inferior): Prepare new environment from in_env for Cygwin, too. Index: windows-nat.c =================================================================== RCS file: /cvs/src/src/gdb/windows-nat.c,v retrieving revision 1.219 diff -u -p -r1.219 windows-nat.c --- windows-nat.c 28 Sep 2011 09:07:54 -0000 1.219 +++ windows-nat.c 5 Oct 2011 11:36:10 -0000 @@ -40,6 +40,7 @@ #include #include #ifdef __CYGWIN__ +#include #include #endif #include @@ -1963,6 +1964,28 @@ envvar_cmp (const void *a, const void *b } #endif +#ifdef __CYGWIN__ +static void +clear_win32_environment (char **env) +{ + int i; + size_t len; + wchar_t *copy = NULL, *equalpos; + + for (i = 0; env[i] && *env[i]; i++) + { + len = mbstowcs (NULL, env[i], 0) + 1; + copy = (wchar_t *) xrealloc (copy, len * sizeof (wchar_t)); + mbstowcs (copy, env[i], len); + equalpos = wcschr (copy, L'='); + if (equalpos) + *equalpos = L'\0'; + SetEnvironmentVariableW (copy, NULL); + } + xfree (copy); +} +#endif + /* Start an inferior windows child process and sets inferior_ptid to its pid. EXEC_FILE is the file to run. ALLARGS is a string containing the arguments to the program. @@ -1980,6 +2003,7 @@ windows_create_inferior (struct target_o cygwin_buf_t *toexec; cygwin_buf_t *cygallargs; cygwin_buf_t *args; + char **old_env; size_t len; int tty; int ostdin, ostdout, ostderr; @@ -2066,7 +2090,11 @@ windows_create_inferior (struct target_o strcat (args, cygallargs); #endif + /* Reset all Win32 environment variables to avoid leftover on next run. */ + clear_win32_environment (environ); /* Prepare the environment vars for CreateProcess. */ + old_env = environ; + environ = in_env; cygwin_internal (CW_SYNC_WINENV); if (!inferior_io_terminal) @@ -2101,6 +2129,12 @@ windows_create_inferior (struct target_o NULL, /* current directory */ &si, &pi); + /* Reset all environment variables to avoid leftover on next run. */ + clear_win32_environment (in_env); + /* Restore normal GDB environment variables. */ + environ = old_env; + cygwin_internal (CW_SYNC_WINENV); + if (tty >= 0) { close (tty); Corinna -- Corinna Vinschen Cygwin Project Co-Leader Red Hat