X-Recipient: archive-cygwin AT delorie DOT com X-Spam-Check-By: sourceware.org From: "Dave Korn" To: Subject: Odd behaviour of __cygwin_environ? Date: Tue, 4 Dec 2007 18:17:16 -0000 Message-ID: <042c01c836a1$e6c0d1d0$2e08a8c0@CAM.ARTIMI.COM> MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit X-Mailer: Microsoft Office Outlook 11 Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com [ Cygwin-1.5.23-2, in case it matters; I haven't yet checked if anything has changed in this area of the code in 1.5.24/1.5.25/cvs head, but it's a fairly long-standing area of the code so probably relatively stable. ] I'm trying to track down a bug where a child process doesn't inherit all the environment variables set in its parent, so I figured I'd add a bunch of strace debugging. I wrote this routine to dump an envp[]-style pointer-array environment block: void dump_env (const char * const *envp, const char *banner) { #if 01 myfault efault; if (efault.faulted ()) { dk_printf ("oops, fault - stop dumping!"); return; } int count = 0; dk_printf("%sdump environment: %p", banner, envp); dk_printf ("attempt"); dk_printf ("try to de-ref envp %p", envp); dk_printf ("de-ref envp %p", *envp); while (*envp) { dk_printf ("try to de-ref envp %p", envp); dk_printf ("de-ref envp %p", *envp); dk_printf ("#%p#%p#%s", envp, *envp, *envp); ++envp; ++count; } dk_printf ("total: %d entries", count); #endif } ... where dk_printf() is just like system_printf() only using a spare strace flag mask bit, and I call it from cur_environ() like so: extern "C" char ** __stdcall cur_environ () { if (*main_environ != __cygwin_environ) { dk_printf ("switch main environ %p for cygwin environ %p", *main_environ, __cygwin_environ); dump_env (*main_environ , "main environ: "); dump_env (__cygwin_environ, "cygwin environ: "); __cygwin_environ = *main_environ; update_envptrs (); } return __cygwin_environ; } The declaration of __cygwin_environ in environ.h says: extern char **__cygwin_environ, ***main_environ; and most of the time this works fine; I see output such as: 110 676992 [main] bash 4884 dump_env: cygwin environ: dump environment: 0x6D0090 111 677103 [main] bash 4884 dump_env: attempt 108 677211 [main] bash 4884 dump_env: try to de-ref envp 0x6D0090 -7469933 -6792722 [main] bash 4884 dump_env: de-ref envp 0x6D0238 172 -6792550 [main] bash 4884 dump_env: try to de-ref envp 0x6D0090 7484835 692285 [main] bash 4884 dump_env: de-ref envp 0x6D0238 123 692408 [main] bash 4884 dump_env: #0x6D0090#0x6D0238#!C:=C:\cygwin\bin 111 692519 [main] bash 4884 dump_env: try to de-ref envp 0x6D0094 110 692629 [main] bash 4884 dump_env: de-ref envp 0x6D0250 -7469734 -6777105 [main] bash 4884 dump_env: #0x6D0094#0x6D0250#!EXITCODE=00000000 7484815 707710 [main] bash 4884 dump_env: try to de-ref envp 0x6D0098 114 707824 [main] bash 4884 dump_env: de-ref envp 0x6D0268 113 707937 [main] bash 4884 dump_env: #0x6D0098#0x6D0268#ALLUSERSPROFILE=C:\Documents and Settings\All Users 167 708104 [main] bash 4884 dump_env: try to de-ref envp 0x6D009C 113 708217 [main] bash 4884 dump_env: de-ref envp 0x6D02A0 110 708327 [main] bash 4884 dump_env: #0x6D009C#0x6D02A0#APPDATA=C:\Documents and Settings\dk\Application Data 14904 723231 [main] bash 4884 dump_env: try to de-ref envp 0x6D00A0 115 723346 [main] bash 4884 dump_env: de-ref envp 0x6D02E0 [ ... lots of snippage here ... ] -7470630 -6448921 [main] bash 4884 dump_env: try to de-ref envp 0x6D0140 7484822 1035901 [main] bash 4884 dump_env: de-ref envp 0x6D1190 121 1036022 [main] bash 4884 dump_env: #0x6D0140#0x6D1190#WINDIR=C:\WINDOWS 122 1036144 [main] bash 4884 dump_env: try to de-ref envp 0x6D0144 116 1036260 [main] bash 4884 dump_env: de-ref envp 0x6D11A8 118 1036378 [main] bash 4884 dump_env: #0x6D0144#0x6D11A8#_NT_SYMBOL_PATH=SRV*C:\symbols*http://msdl.microsoft.com/do wnload/symbols 183 1036561 [main] bash 4884 dump_env: try to de-ref envp 0x6D0148 -7469846 -6433285 [main] bash 4884 dump_env: de-ref envp 0x6D11F8 7484822 1051537 [main] bash 4884 dump_env: #0x6D0148#0x6D11F8#__COMPAT_LAYER=EnableNXShowUI 182 1051719 [main] bash 4884 dump_env: try to de-ref envp 0x6D014C 118 1051837 [main] bash 4884 dump_env: de-ref envp 0x6D1220 118 1051955 [main] bash 4884 dump_env: #0x6D014C#0x6D1220#TERM=cygwin 119 1052074 [main] bash 4884 dump_env: try to de-ref envp 0x6D0150 -7469720 -6417646 [main] bash 4884 dump_env: de-ref envp 0x6D0160 7484832 1067186 [main] bash 4884 dump_env: #0x6D0150#0x6D0160#HOME=/home/dk 132 1067318 [main] bash 4884 dump_env: total: 49 entries But sometimes it seems as if __cygwin_environ is in fact pointing to a win32-style environment block made of contiguous concatenated strings with a double-NUL terminator, leading to exceptions: 144 2468502 [main] bash 4644 dump_env: cygwin environ: dump environment: 0x6DFC88 150 2468652 [main] bash 4644 dump_env: attempt 150 2468802 [main] bash 4644 dump_env: try to de-ref envp 0x6DFC88 151 2468953 [main] bash 4644 dump_env: de-ref envp 0x48544150 126 2469079 [main] bash 4644 dump_env: try to de-ref envp 0x6DFC88 141 2469220 [main] bash 4644 dump_env: de-ref envp 0x48544150 --- Process 4644, exception C0000005 at 610A5EE2 -7484282 -5015062 [main] bash 4644 dump_env: oops, fault - stop dumping! In that example, 0x48544150 is the ascii for "PATH". At other times, it seems to be partly there and partly not: 106 5778781 [main] bash 4664 dump_env: cygwin environ: dump environment: 0x6E1BF8 107 5778888 [main] bash 4664 dump_env: attempt 105 5778993 [main] bash 4664 dump_env: try to de-ref envp 0x6E1BF8 105 5779098 [main] bash 4664 dump_env: de-ref envp 0x6E1C08 107 5779205 [main] bash 4664 dump_env: try to de-ref envp 0x6E1BF8 107 5779312 [main] bash 4664 dump_env: de-ref envp 0x6E1C08 105 5779417 [main] bash 4664 dump_env: #0x6E1BF8#0x6E1C08#fort 107 5779524 [main] bash 4664 dump_env: try to de-ref envp 0x6E1BFC 107 5779631 [main] bash 4664 dump_env: de-ref envp 0x6E5320 106 5779737 [main] bash 4664 dump_env: #0x6E1BFC#0x6E5320#for x in monitor chiptest factorytest ; do ( echo Building "${x} ..."; time remake ARTIMI_CFLAGS="--save-temps -fverbose-asm -O2" ASIC_BUILD=1 USE_GC=1 ARTIMI_SYSTEM=${x} 2>&1 all ) ; done | tee buildb2b.log 259 5779996 [main] bash 4664 dump_env: try to de-ref envp 0x6E1C00 107 5780103 [main] bash 4664 dump_env: de-ref envp 0x20017800 --- Process 4664, exception C0000005 at 610A5EE2 295 5780398 [main] bash 4664 dump_env: oops, fault - stop dumping! Don't know exactly /what/ kind of error that is; the two strings it manages to print out are the matching variable name and definition parts of a "VAR=DEFN" for a bash alias, the first two entries look like valid pointers, but then the third entry looks like it could be ascii again (modulo the dubious 0x01 byte). I'm suspicious of the fact that it goes wrong exactly at the moment when the envp pointer crosses a page boundary, but that could just be a meaningless coincidence. Am I giving myself a race here? I thought it would be OK to dump __cygwin_environ from inside cur_environ because we're in the "if (*main_environ != __cygwin_environ)" clause, which IIUIC is switching over from the earlystartup minimal win32 environment to the full posix environment, so __cygwin_environ ought to be valid and initialised here. But perhaps I have a wrong assumption: for instance, does the __cygwin_environ get switched in before it is complete because the startup code knows it isn't going to be accessed for a while? Does __cygwin_environ deliberately sometimes point to one kind of data rather than another? My understanding of the cygwin process-startup dance is a bit sketchy here, can anyone offer a bit of insight? cheers, DaveK -- Can't think of a witty .sigline today.... -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/