[Bug 24018] Cygwin 1.7.6 installer crashes at start of postinstall

wine-bugs at winehq.org wine-bugs at winehq.org
Sun May 5 07:49:57 CDT 2013


http://bugs.winehq.org/show_bug.cgi?id=24018

Anastasius Focht <focht at gmx.net> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |focht at gmx.net

--- Comment #7 from Anastasius Focht <focht at gmx.net> 2013-05-05 07:49:57 CDT ---
Hello folks,

from comment #5 console log you can reproduce it manually by running:

--- snip ---
$ wine "C:\\cygwin\\bin\\bash.exe" --norc --noprofile
"/etc/postinstall/000-cygwin-post-install.sh"
--- snip ---

Trace of child "bash" process with +virtual:

--- snip ---
...
0027:trace:virtual:map_view got mem in reserved area 0x490000-0x690000
0027:trace:virtual:VIRTUAL_DumpView View: 0x490000 - 0x68ffff (valloc)
0027:trace:virtual:VIRTUAL_DumpView       0x490000 - 0x68ffff c-rw-
0027:trace:virtual:create_view forcing exec permission on 0x490000-0x68ffff
0027:trace:virtual:VIRTUAL_SetProt 0x490000-0x490fff c----
0027:trace:virtual:VIRTUAL_DumpView View: 0x490000 - 0x68ffff (valloc)
0027:trace:virtual:VIRTUAL_DumpView       0x490000 - 0x490fff c----
0027:trace:virtual:VIRTUAL_DumpView       0x491000 - 0x68ffff c-rw-
0027:trace:virtual:VIRTUAL_SetProt 0x491000-0x491fff cgrw-
0027:trace:virtual:VIRTUAL_DumpView View: 0x490000 - 0x68ffff (valloc)
0027:trace:virtual:VIRTUAL_DumpView       0x490000 - 0x490fff c----
0027:trace:virtual:VIRTUAL_DumpView       0x491000 - 0x491fff cgrw-
0027:trace:virtual:VIRTUAL_DumpView       0x492000 - 0x68ffff c-rw-
0024:Ret  KERNEL32.CreateProcessW() retval=00000001 ret=61077c03 
...
0027:Starting process L"C:\\cygwin\\bin\\bash.exe" (entryproc=0x401000)
0027:Call KERNEL32.GetModuleHandleA(00000000) ret=00465ab6
0027:Ret  KERNEL32.GetModuleHandleA() retval=00400000 ret=00465ab6
0027:trace:virtual:VIRTUAL_SetProt 0x491000-0x491fff c-rw-
0027:trace:virtual:VIRTUAL_SetProt forcing exec permission on 0x491000-0x491fff
0027:trace:virtual:VIRTUAL_DumpView View: 0x490000 - 0x68ffff (valloc)
0027:trace:virtual:VIRTUAL_DumpView       0x490000 - 0x490fff c----
0027:trace:virtual:VIRTUAL_DumpView       0x491000 - 0x68ffff c-rw-
0027:trace:seh:raise_exception code=c00000fd flags=0 addr=0x61006b93
ip=61006b93 tid=0027
0027:trace:seh:raise_exception  eax=00491d90 ebx=0022063a ecx=00491000
edx=00000000 esi=0068feb0 edi=00000027
0027:trace:seh:raise_exception  ebp=0068fdb8 esp=0068fd90 cs=0023 ds=002b
es=002b fs=0063 gs=006b flags=00010287
0027:trace:seh:call_stack_handlers calling handler at 0x7bc98301 code=c00000fd
flags=0
0027:Call KERNEL32.UnhandledExceptionFilter(0068f854) ret=7bc9833b
wine: Unhandled stack overflow at address 0x61006b93 (thread 0027), starting
debugger... 
--- snip ---

The corresponding source code to the crash is here:
http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/cygwin/dcrt0.cc?rev=1.445&content-type=text/x-cvsweb-markup&cvsroot=src

--- snip ---
void *getstack (void *) __attribute__ ((noinline));
volatile char *
getstack (volatile char * volatile p)
{
  *p ^= 1;
  *p ^= 1;
  return p - 4096;
}

/* extend the stack prior to fork longjmp */

void
child_info_fork::alloc_stack ()
{
  volatile char * volatile stackp;
#ifdef __x86_64__
  __asm__ volatile ("movq %%rsp,%0": "=r" (stackp));
#else
  __asm__ volatile ("movl %%esp,%0": "=r" (stackp));
#endif
  /* Make sure not to try a hard allocation if we have been forked off from
     the main thread of a Cygwin process which has been started from a 64 bit
     parent.  In that case the _tlsbase of the forked child is not the same
     as the _tlsbase of the parent (== stackbottom), but only because the
     stack of the parent has been slightly rearranged.  See comment in
     wow64_revert_to_original_stack for details. We check here if the
     parent stack fits into the child stack. */
  if (_tlsbase != stackbottom
      && (!wincap.is_wow64 ()
          || stacktop < (char *) NtCurrentTeb ()->DeallocationStack
          || stackbottom > _tlsbase))
    alloc_stack_hard_way (stackp);
  else
    {
      char *st = (char *) stacktop - 4096;
      while (_tlstop >= st)
        stackp = getstack (stackp);
      stackaddr = 0;
      /* This only affects forked children of a process started from a native
         64 bit process, but it doesn't hurt to do it unconditionally.  Fix
         StackBase in the child to be the same as in the parent, so that the
         computation of _my_tls is correct. */
      _tlsbase = (PVOID) stackbottom;
    }
}

...

/* Take over from libc's crt0.o and start the application. Note the
   various special cases when Cygwin DLL is being runtime loaded (as
   opposed to being link-time loaded by Cygwin apps) from a non
   cygwin app via LoadLibrary.  */
void
dll_crt0_1 (void *)
{
  extern void initial_setlocale ();
...
  cygbench ("pre-forkee");
  if (in_forkee)
    {
      /* If we've played with the stack, stacksize != 0.  That means that
         fork() was invoked from other than the main thread.  Make sure that
         frame pointer is referencing the new stack so that the OS knows what
         to do when it needs to increase the size of the stack.

         NOTE: Don't do anything that involves the stack until you've completed
         this step. */
      if (fork_info->stackaddr)
        {
          _tlsbase = (PVOID) fork_info->stackbottom;
          _tlstop = (PVOID) fork_info->stacktop;
        }

      /* Not resetting _my_tls.incyg here because presumably fork will
overwrite
         it with the value of the forker and all will be good.   */
      longjmp (fork_info->jmp, true);
    }

  main_thread_sinit ();
...
--- snip ---

The stack overflow happens in this code part in spawned "bash.exe" child
process (forkee):

--- snip ---
      char *st = (char *) stacktop - 4096;
      while (_tlstop >= st)
        stackp = getstack (stackp);
--- snip ---

Since the main thread stack is already committed there will be no further TIB
StackLimit updates (guard page moved) which is what getstack() function (touch
next stack page) implies.
The expression "while (_tlstop >= st)" seems to be always true (equal).

$ wine --version
wine-1.5.29-122-g865d53d

Regards

-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
Do not reply to this email, post in Bugzilla using the
above URL to reply.
------- You are receiving this mail because: -------
You are watching all bug changes.



More information about the wine-bugs mailing list