This is the mail archive of the cygwin mailing list for the Cygwin 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]

Odd behaviour of __cygwin_environ?



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


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