* cygheap.h (mini_cygheap): New struct.
(init_cygheap): Inherit locale field via mini_cygheap. * cygheap.cc (cygheap_at_start): Define new variable. (cygheap): Initialize as cygheap_at_start so that locale information is always available. (cygheap_init): Initialize cygheap iff it is set to cygheap_at_start. * shared_info.h (memory_init): Accommodate argument change. * memory.cc (memory_init): Accept an argument indicating whether cygheap should be initialized or not. * dcrt0.cc (child_info_fork::handle_fork): Pass false to memory_init(). (child_info_spawn::handle_spawn): Ditto. (dll_crt0_0): Pass true to memory_init when not forking or execing. * cygheap.h (cygheap_types::HEAP_2_DLL): New enum. * dll_init.h (dll): Remove unused namelen field. (dll_list::load_after_fork): Accommodate change in arguments. * dll_init.cc (dll_list::alloc): Allocate dll information in the cygwin heap. (dll_list::detach): Free dll information from the cygwin heap. (dll_list::load_after_fork): Use dll information in the cygwin heap directly rather than querying parent. * fork.cc (frok::first_dll): Delete. (frok::child): Don't report on first_dll. Don't pass it to load_on_fork. (frok::parent): Don't set first_dll. (fork): Ditto.
This commit is contained in:
parent
1866410bb8
commit
71f53a2f62
|
@ -1,3 +1,32 @@
|
||||||
|
2009-06-07 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
|
* cygheap.h (mini_cygheap): New struct.
|
||||||
|
(init_cygheap): Inherit locale field via mini_cygheap.
|
||||||
|
* cygheap.cc (cygheap_at_start): Define new variable.
|
||||||
|
(cygheap): Initialize as cygheap_at_start so that locale information is
|
||||||
|
always available.
|
||||||
|
(cygheap_init): Initialize cygheap iff it is set to cygheap_at_start.
|
||||||
|
* shared_info.h (memory_init): Accommodate argument change.
|
||||||
|
* memory.cc (memory_init): Accept an argument indicating whether
|
||||||
|
cygheap should be initialized or not.
|
||||||
|
* dcrt0.cc (child_info_fork::handle_fork): Pass false to memory_init().
|
||||||
|
(child_info_spawn::handle_spawn): Ditto.
|
||||||
|
(dll_crt0_0): Pass true to memory_init when not forking or execing.
|
||||||
|
|
||||||
|
* cygheap.h (cygheap_types::HEAP_2_DLL): New enum.
|
||||||
|
* dll_init.h (dll): Remove unused namelen field.
|
||||||
|
(dll_list::load_after_fork): Accommodate change in arguments.
|
||||||
|
* dll_init.cc (dll_list::alloc): Allocate dll information in the cygwin
|
||||||
|
heap.
|
||||||
|
(dll_list::detach): Free dll information from the cygwin heap.
|
||||||
|
(dll_list::load_after_fork): Use dll information in the cygwin heap
|
||||||
|
directly rather than querying parent.
|
||||||
|
* fork.cc (frok::first_dll): Delete.
|
||||||
|
(frok::child): Don't report on first_dll. Don't pass it to
|
||||||
|
load_on_fork.
|
||||||
|
(frok::parent): Don't set first_dll.
|
||||||
|
(fork): Ditto.
|
||||||
|
|
||||||
2009-06-06 Corinna Vinschen <corinna@vinschen.de>
|
2009-06-06 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* dll_init.cc (dll_list::alloc): Allocate memory using a section
|
* dll_init.cc (dll_list::alloc): Allocate memory using a section
|
||||||
|
|
|
@ -24,7 +24,12 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
|
||||||
init_cygheap NO_COPY *cygheap;
|
static mini_cygheap NO_COPY cygheap_at_start =
|
||||||
|
{
|
||||||
|
{__utf8_mbtowc, __utf8_wctomb}
|
||||||
|
};
|
||||||
|
|
||||||
|
init_cygheap NO_COPY *cygheap = (init_cygheap *) &cygheap_at_start;
|
||||||
void NO_COPY *cygheap_max;
|
void NO_COPY *cygheap_max;
|
||||||
|
|
||||||
extern "C" char _cygheap_mid[] __attribute__((section(".cygheap")));
|
extern "C" char _cygheap_mid[] __attribute__((section(".cygheap")));
|
||||||
|
@ -33,11 +38,11 @@ extern "C" char _cygheap_end[];
|
||||||
static NO_COPY muto cygheap_protect;
|
static NO_COPY muto cygheap_protect;
|
||||||
|
|
||||||
struct cygheap_entry
|
struct cygheap_entry
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
struct cygheap_entry *next;
|
struct cygheap_entry *next;
|
||||||
char data[0];
|
char data[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NBUCKETS (sizeof (cygheap->buckets) / sizeof (cygheap->buckets[0]))
|
#define NBUCKETS (sizeof (cygheap->buckets) / sizeof (cygheap->buckets[0]))
|
||||||
#define N0 ((_cmalloc_entry *) NULL)
|
#define N0 ((_cmalloc_entry *) NULL)
|
||||||
|
@ -150,7 +155,7 @@ extern "C" void __stdcall
|
||||||
cygheap_init ()
|
cygheap_init ()
|
||||||
{
|
{
|
||||||
cygheap_protect.init ("cygheap_protect");
|
cygheap_protect.init ("cygheap_protect");
|
||||||
if (!cygheap)
|
if (cygheap == &cygheap_at_start)
|
||||||
{
|
{
|
||||||
cygheap = (init_cygheap *) memset (_cygheap_start, 0,
|
cygheap = (init_cygheap *) memset (_cygheap_start, 0,
|
||||||
_cygheap_mid - _cygheap_start);
|
_cygheap_mid - _cygheap_start);
|
||||||
|
|
|
@ -31,6 +31,7 @@ enum cygheap_types
|
||||||
HEAP_1_EXEC,
|
HEAP_1_EXEC,
|
||||||
HEAP_1_MAX = 100,
|
HEAP_1_MAX = 100,
|
||||||
HEAP_2_STR,
|
HEAP_2_STR,
|
||||||
|
HEAP_2_DLL,
|
||||||
HEAP_MMAP = 200
|
HEAP_MMAP = 200
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -282,13 +283,17 @@ struct hook_chain
|
||||||
struct hook_chain *next;
|
struct hook_chain *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct init_cygheap
|
struct mini_cygheap
|
||||||
|
{
|
||||||
|
cygheap_locale locale;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct init_cygheap: public mini_cygheap
|
||||||
{
|
{
|
||||||
_cmalloc_entry *chain;
|
_cmalloc_entry *chain;
|
||||||
char *buckets[32];
|
char *buckets[32];
|
||||||
cygheap_root root;
|
cygheap_root root;
|
||||||
cygheap_user user;
|
cygheap_user user;
|
||||||
cygheap_locale locale;
|
|
||||||
user_heap_info user_heap;
|
user_heap_info user_heap;
|
||||||
mode_t umask;
|
mode_t umask;
|
||||||
HANDLE console_h;
|
HANDLE console_h;
|
||||||
|
|
|
@ -571,7 +571,7 @@ void
|
||||||
child_info_fork::handle_fork ()
|
child_info_fork::handle_fork ()
|
||||||
{
|
{
|
||||||
cygheap_fixup_in_child (false);
|
cygheap_fixup_in_child (false);
|
||||||
memory_init ();
|
memory_init (false);
|
||||||
myself.thisproc (NULL);
|
myself.thisproc (NULL);
|
||||||
myself->uid = cygheap->user.real_uid;
|
myself->uid = cygheap->user.real_uid;
|
||||||
myself->gid = cygheap->user.real_gid;
|
myself->gid = cygheap->user.real_gid;
|
||||||
|
@ -598,7 +598,7 @@ child_info_spawn::handle_spawn ()
|
||||||
extern void fixup_lockf_after_exec ();
|
extern void fixup_lockf_after_exec ();
|
||||||
HANDLE h;
|
HANDLE h;
|
||||||
cygheap_fixup_in_child (true);
|
cygheap_fixup_in_child (true);
|
||||||
memory_init ();
|
memory_init (false);
|
||||||
if (!moreinfo->myself_pinfo ||
|
if (!moreinfo->myself_pinfo ||
|
||||||
!DuplicateHandle (hMainProc, moreinfo->myself_pinfo, hMainProc, &h, 0,
|
!DuplicateHandle (hMainProc, moreinfo->myself_pinfo, hMainProc, &h, 0,
|
||||||
FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
|
FALSE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))
|
||||||
|
@ -702,7 +702,7 @@ dll_crt0_0 ()
|
||||||
|
|
||||||
child_proc_info = get_cygwin_startup_info ();
|
child_proc_info = get_cygwin_startup_info ();
|
||||||
if (!child_proc_info)
|
if (!child_proc_info)
|
||||||
memory_init ();
|
memory_init (true);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cygwin_user_h = child_proc_info->user_h;
|
cygwin_user_h = child_proc_info->user_h;
|
||||||
|
|
|
@ -20,14 +20,10 @@ details. */
|
||||||
#include "pinfo.h"
|
#include "pinfo.h"
|
||||||
#include "cygtls.h"
|
#include "cygtls.h"
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <alloca.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/param.h>
|
|
||||||
#include "ntdll.h"
|
|
||||||
|
|
||||||
extern void __stdcall check_sanity_and_sync (per_process *);
|
extern void __stdcall check_sanity_and_sync (per_process *);
|
||||||
|
|
||||||
dll_list NO_COPY dlls;
|
dll_list dlls;
|
||||||
|
|
||||||
static bool dll_global_dtors_recorded;
|
static bool dll_global_dtors_recorded;
|
||||||
|
|
||||||
|
@ -107,7 +103,7 @@ dll_list::operator[] (const PWCHAR name)
|
||||||
|
|
||||||
#define RETRIES 1000
|
#define RETRIES 1000
|
||||||
|
|
||||||
/* Allocate space for a dll struct contiguous with the just-loaded dll. */
|
/* Allocate space for a dll struct. */
|
||||||
dll *
|
dll *
|
||||||
dll_list::alloc (HINSTANCE h, per_process *p, dll_type type)
|
dll_list::alloc (HINSTANCE h, per_process *p, dll_type type)
|
||||||
{
|
{
|
||||||
|
@ -118,96 +114,16 @@ dll_list::alloc (HINSTANCE h, per_process *p, dll_type type)
|
||||||
dll *d = dlls[name];
|
dll *d = dlls[name];
|
||||||
if (d)
|
if (d)
|
||||||
{
|
{
|
||||||
d->count++; /* Yes. Bump the usage count. */
|
if (!in_forkee)
|
||||||
|
d->count++; /* Yes. Bump the usage count. */
|
||||||
return d; /* Return previously allocated pointer. */
|
return d; /* Return previously allocated pointer. */
|
||||||
}
|
}
|
||||||
|
|
||||||
void *s = p->bss_end;
|
d = (dll *) cmalloc (HEAP_2_DLL, sizeof (*d) + (namelen * sizeof (*name)));
|
||||||
size_t d_size = sizeof (dll) + namelen * sizeof (WCHAR);
|
|
||||||
|
|
||||||
MEMORY_BASIC_INFORMATION m;
|
|
||||||
NTSTATUS status = 0;
|
|
||||||
HANDLE sect_h;
|
|
||||||
OBJECT_ATTRIBUTES oa;
|
|
||||||
InitializeObjectAttributes (&oa, NULL, 0, NULL,
|
|
||||||
sec_none.lpSecurityDescriptor);
|
|
||||||
|
|
||||||
/* Search for space after the DLL */
|
|
||||||
for (int i = 0; i <= RETRIES; i++, s = (char *) m.BaseAddress + m.RegionSize)
|
|
||||||
{
|
|
||||||
if (!VirtualQuery (s, &m, sizeof (m)))
|
|
||||||
return NULL; /* Can't do it. */
|
|
||||||
if (m.State == MEM_FREE)
|
|
||||||
{
|
|
||||||
/* Couldn't find any. Uh oh. FIXME: Issue an error? */
|
|
||||||
if (i == RETRIES)
|
|
||||||
return NULL; /* Oh well. Couldn't locate free space. */
|
|
||||||
|
|
||||||
d = (dll *) m.BaseAddress;
|
|
||||||
/* Instead of calling VirtualAlloc, which always allocates memory
|
|
||||||
on a 64K boundary, we allocate the memory using a section
|
|
||||||
object. The disadvantage of the 64K boundary in this case is
|
|
||||||
the fact that that boundary could be easily the start address
|
|
||||||
of another DLL yet to load into memory.
|
|
||||||
|
|
||||||
On x86, using a section object allows us to allocate the struct
|
|
||||||
dll into a memory slot in the remainder of the last 64K slot of
|
|
||||||
the DLL. This memory slot will never be used for anything
|
|
||||||
else. Given that the struct dll will fit into a single page
|
|
||||||
99.99% of the time anyway, this is a neat way to avoid DLL load
|
|
||||||
address collisions in most cases.
|
|
||||||
|
|
||||||
Of course, this doesn't help if the DLL needs all of the 64K
|
|
||||||
memory slot but there's only a 1 in 16 chance for that.
|
|
||||||
|
|
||||||
And, alas, it won't work on 64 bit systems because the
|
|
||||||
AT_ROUND_TO_PAGE flag required to make a page-aligned allocation
|
|
||||||
isn't supported under WOW64. So, as with VirtualAlloc, ensure
|
|
||||||
that address is rounded up to next 64K allocation boundary if
|
|
||||||
running under WOW64. */
|
|
||||||
if (wincap.is_wow64 ())
|
|
||||||
d = (dll *) roundup2 ((uintptr_t) d, getpagesize ());
|
|
||||||
|
|
||||||
LARGE_INTEGER so = { QuadPart: d_size };
|
|
||||||
status = NtCreateSection (§_h, SECTION_ALL_ACCESS, &oa, &so,
|
|
||||||
PAGE_READWRITE, SEC_COMMIT, NULL);
|
|
||||||
if (NT_SUCCESS (status))
|
|
||||||
{
|
|
||||||
ULONG viewsize = 0;
|
|
||||||
so.QuadPart = 0;
|
|
||||||
status = NtMapViewOfSection (sect_h, GetCurrentProcess (),
|
|
||||||
(void **) &d, 0, d_size, &so,
|
|
||||||
&viewsize, ViewUnmap,
|
|
||||||
wincap.is_wow64 ()
|
|
||||||
? 0 : AT_ROUND_TO_PAGE,
|
|
||||||
PAGE_READWRITE);
|
|
||||||
#ifdef DEBUGGING
|
|
||||||
if (!NT_SUCCESS (status))
|
|
||||||
system_printf ("NtMapViewOfSection failed, %p", status);
|
|
||||||
#endif
|
|
||||||
NtClose (sect_h);
|
|
||||||
}
|
|
||||||
#ifdef DEBUGGING
|
|
||||||
else
|
|
||||||
system_printf ("NtCreateSection failed, %p", status);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (NT_SUCCESS (status))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Did we succeed? */
|
|
||||||
if (!NT_SUCCESS (status))
|
|
||||||
{ /* Nope. */
|
|
||||||
__seterrno_from_nt_status (status);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now we've allocated a block of information. Fill it in with the supplied
|
/* Now we've allocated a block of information. Fill it in with the supplied
|
||||||
info about this DLL. */
|
info about this DLL. */
|
||||||
d->count = 1;
|
d->count = 1;
|
||||||
d->namelen = namelen;
|
|
||||||
wcscpy (d->name, name);
|
wcscpy (d->name, name);
|
||||||
d->handle = h;
|
d->handle = h;
|
||||||
d->p = p;
|
d->p = p;
|
||||||
|
@ -251,7 +167,7 @@ dll_list::detach (void *retaddr)
|
||||||
loaded_dlls--;
|
loaded_dlls--;
|
||||||
if (end == d)
|
if (end == d)
|
||||||
end = d->prev;
|
end = d->prev;
|
||||||
NtUnmapViewOfSection (GetCurrentProcess (), d);
|
cfree (d);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -321,82 +237,51 @@ release_upto (const PWCHAR name, DWORD here)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reload DLLs after a fork. Iterates over the list of dynamically loaded
|
/* Reload DLLs after a fork. Iterates over the list of dynamically loaded
|
||||||
DLLs and attempts to load them in the same place as they were loaded in
|
DLLs and attempts to load them in the same place as they were loaded in the
|
||||||
the parent. */
|
parent. */
|
||||||
void
|
void
|
||||||
dll_list::load_after_fork (HANDLE parent, dll *first)
|
dll_list::load_after_fork (HANDLE parent)
|
||||||
{
|
{
|
||||||
int try2 = 0;
|
for (dll *d = &dlls.start; (d = d->next) != NULL; )
|
||||||
dll *d = (dll *) alloca (sizeof (dll) + (NT_MAX_PATH - 1) * sizeof (WCHAR));
|
if (d->type == DLL_LOAD)
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
void *next = first;
|
|
||||||
while (next)
|
|
||||||
{
|
|
||||||
DWORD nb;
|
|
||||||
/* Read 4K of the dll structure from the parent. A full page has
|
|
||||||
been allocated anyway and this covers most, if not all DLL paths.
|
|
||||||
Only if d->namelen indicates that more than 4K are required,
|
|
||||||
read them in a second step. */
|
|
||||||
if (!ReadProcessMemory (parent, next, d, getsystempagesize (), &nb)
|
|
||||||
|| nb != getsystempagesize ())
|
|
||||||
return;
|
|
||||||
size_t namelen = d->namelen * sizeof (WCHAR);
|
|
||||||
if (namelen >= getsystempagesize () - sizeof (dll)
|
|
||||||
&& (!ReadProcessMemory (parent, next, d->name, namelen, &nb)
|
|
||||||
|| nb != namelen))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* We're only interested in dynamically loaded dlls.
|
|
||||||
Hopefully, this function wouldn't even have been called unless
|
|
||||||
the parent had some of those. */
|
|
||||||
if (d->type == DLL_LOAD)
|
|
||||||
{
|
{
|
||||||
bool unload = true;
|
|
||||||
HMODULE h = LoadLibraryExW (d->name, NULL,
|
|
||||||
DONT_RESOLVE_DLL_REFERENCES);
|
|
||||||
|
|
||||||
if (!h)
|
|
||||||
system_printf ("can't reload %W", d->name);
|
|
||||||
/* See if DLL will load in proper place. If so, free it and reload
|
/* See if DLL will load in proper place. If so, free it and reload
|
||||||
it the right way.
|
it the right way.
|
||||||
It sort of stinks that we can't invert the order of the
|
It stinks that we can't invert the order of the initial LoadLibrary
|
||||||
FreeLibrary and LoadLibrary since Microsoft documentation seems
|
and FreeLibrar since Microsoft documentation seems to imply that
|
||||||
to imply that that should do what we want. However, since the
|
should do what we want. However, once a library is loaded as
|
||||||
library was loaded above, the second LoadLibrary does not execute
|
above, the second LoadLibrary will not execute its startup code
|
||||||
it's startup code unless it is first unloaded. */
|
unless it is first unloaded. */
|
||||||
else if (h == d->handle)
|
HMODULE h = LoadLibraryExW (d->name, NULL, DONT_RESOLVE_DLL_REFERENCES);
|
||||||
{
|
|
||||||
if (unload)
|
if (!h)
|
||||||
{
|
system_printf ("can't reload %W, %E", d->name);
|
||||||
FreeLibrary (h);
|
|
||||||
LoadLibraryW (d->name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (try2)
|
|
||||||
api_fatal ("unable to remap %W to same address as parent(%p) != %p",
|
|
||||||
d->name, d->handle, h);
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* It loaded in the wrong place. Dunno why this happens but it
|
|
||||||
always seems to happen when there are multiple DLLs attempting
|
|
||||||
to load into the same address space. In the "forked" process,
|
|
||||||
the second DLL always loads into a different location. */
|
|
||||||
FreeLibrary (h);
|
FreeLibrary (h);
|
||||||
/* Block all of the memory up to the new load address. */
|
if (h == d->handle)
|
||||||
reserve_upto (d->name, (DWORD) d->handle);
|
h = LoadLibraryW (d->name);
|
||||||
try2 = 1; /* And try */
|
|
||||||
continue; /* again. */
|
|
||||||
}
|
|
||||||
/* If we reached here, and try2 is set, then there is a lot of
|
|
||||||
memory to release. */
|
|
||||||
if (try2)
|
|
||||||
{
|
|
||||||
release_upto (d->name, (DWORD) d->handle);
|
|
||||||
try2 = 0;
|
|
||||||
}
|
}
|
||||||
|
/* If we reached here on the second iteration of the for loop
|
||||||
|
then there is a lot of memory to release. */
|
||||||
|
if (i > 0)
|
||||||
|
release_upto (d->name, (DWORD) d->handle);
|
||||||
|
if (h == d->handle)
|
||||||
|
break; /* Success */
|
||||||
|
|
||||||
|
if (i > 0)
|
||||||
|
/* We tried once to relocate the dll and it failed. */
|
||||||
|
api_fatal ("unable to remap %W to same address as parent: %p != %p",
|
||||||
|
d->name, d->handle, h);
|
||||||
|
|
||||||
|
/* Dll loaded in the wrong place. Dunno why this happens but it
|
||||||
|
always seems to happen when there are multiple DLLs attempting to
|
||||||
|
load into the same address space. In the "forked" process, the
|
||||||
|
second DLL always loads into a different location. So, block all
|
||||||
|
of the memory up to the new load address and try again. */
|
||||||
|
reserve_upto (d->name, (DWORD) d->handle);
|
||||||
}
|
}
|
||||||
next = d->next; /* Get the address of the next DLL. */
|
|
||||||
}
|
|
||||||
in_forkee = false;
|
in_forkee = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,8 +51,7 @@ struct dll
|
||||||
HMODULE handle;
|
HMODULE handle;
|
||||||
int count;
|
int count;
|
||||||
dll_type type;
|
dll_type type;
|
||||||
int namelen;
|
WCHAR name[1];
|
||||||
WCHAR name[ANYSIZE_ARRAY];
|
|
||||||
void detach ();
|
void detach ();
|
||||||
int init ();
|
int init ();
|
||||||
};
|
};
|
||||||
|
@ -73,7 +72,7 @@ public:
|
||||||
dll *alloc (HINSTANCE, per_process *, dll_type);
|
dll *alloc (HINSTANCE, per_process *, dll_type);
|
||||||
void detach (void *);
|
void detach (void *);
|
||||||
void init ();
|
void init ();
|
||||||
void load_after_fork (HANDLE, dll *);
|
void load_after_fork (HANDLE);
|
||||||
dll *inext ()
|
dll *inext ()
|
||||||
{
|
{
|
||||||
while ((hold = hold->next))
|
while ((hold = hold->next))
|
||||||
|
|
|
@ -34,7 +34,6 @@ details. */
|
||||||
|
|
||||||
class frok
|
class frok
|
||||||
{
|
{
|
||||||
dll *first_dll;
|
|
||||||
bool load_dlls;
|
bool load_dlls;
|
||||||
child_info_fork ch;
|
child_info_fork ch;
|
||||||
const char *error;
|
const char *error;
|
||||||
|
@ -174,8 +173,7 @@ frok::child (volatile char * volatile here)
|
||||||
myself->pid, myself->ppid, __builtin_frame_address (0));
|
myself->pid, myself->ppid, __builtin_frame_address (0));
|
||||||
|
|
||||||
sync_with_parent ("after longjmp", true);
|
sync_with_parent ("after longjmp", true);
|
||||||
sigproc_printf ("hParent %p, child 1 first_dll %p, load_dlls %d", hParent,
|
sigproc_printf ("hParent %p, load_dlls %d", hParent, load_dlls);
|
||||||
first_dll, load_dlls);
|
|
||||||
|
|
||||||
/* If we've played with the stack, stacksize != 0. That means that
|
/* If we've played with the stack, stacksize != 0. That means that
|
||||||
fork() was invoked from other than the main thread. Make sure that
|
fork() was invoked from other than the main thread. Make sure that
|
||||||
|
@ -230,7 +228,7 @@ frok::child (volatile char * volatile here)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dlls.load_after_fork (hParent, first_dll);
|
dlls.load_after_fork (hParent);
|
||||||
cygheap->fdtab.fixup_after_fork (hParent);
|
cygheap->fdtab.fixup_after_fork (hParent);
|
||||||
sync_with_parent ("loaded dlls", true);
|
sync_with_parent ("loaded dlls", true);
|
||||||
}
|
}
|
||||||
|
@ -304,14 +302,13 @@ frok::parent (volatile char * volatile stack_here)
|
||||||
else
|
else
|
||||||
c_flags |= DETACHED_PROCESS;
|
c_flags |= DETACHED_PROCESS;
|
||||||
|
|
||||||
/* Remember the address of the first loaded dll and decide
|
/* Remember if we need to load dynamically linked dlls.
|
||||||
if we need to load dlls. We do this here so that this
|
We do this here so that this information will be available
|
||||||
information will be available in the parent and, when
|
in the parent and, when the stack is copied, in the child. */
|
||||||
the stack is copied, in the child. */
|
|
||||||
first_dll = dlls.start.next;
|
|
||||||
load_dlls = dlls.reload_on_fork && dlls.loaded_dlls;
|
load_dlls = dlls.reload_on_fork && dlls.loaded_dlls;
|
||||||
|
|
||||||
/* This will help some of the confusion. */
|
/* This will help some of the confusion. */
|
||||||
|
/* FIXME: Is this really appropriate? What if stdout is closed? */
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
|
|
||||||
forker_finished = CreateEvent (&sec_all, FALSE, FALSE, NULL);
|
forker_finished = CreateEvent (&sec_all, FALSE, FALSE, NULL);
|
||||||
|
@ -570,7 +567,6 @@ fork ()
|
||||||
frok grouped;
|
frok grouped;
|
||||||
|
|
||||||
debug_printf ("entering");
|
debug_printf ("entering");
|
||||||
grouped.first_dll = NULL;
|
|
||||||
grouped.load_dlls = 0;
|
grouped.load_dlls = 0;
|
||||||
|
|
||||||
int res;
|
int res;
|
||||||
|
|
|
@ -361,13 +361,13 @@ shared_info::initialize ()
|
||||||
SHARED_INFO_CB, cb);
|
SHARED_INFO_CB, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __stdcall
|
void
|
||||||
memory_init ()
|
memory_init (bool init_cygheap)
|
||||||
{
|
{
|
||||||
getpagesize ();
|
getpagesize ();
|
||||||
|
|
||||||
/* Initialize the Cygwin heap, if necessary */
|
/* Initialize the Cygwin heap, if necessary */
|
||||||
if (!cygheap)
|
if (init_cygheap)
|
||||||
{
|
{
|
||||||
cygheap_init ();
|
cygheap_init ();
|
||||||
cygheap->user.init ();
|
cygheap->user.init ();
|
||||||
|
|
|
@ -79,7 +79,7 @@ enum shared_locations
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void __stdcall memory_init ();
|
void memory_init (bool) __attribute__ ((regparm(1)));
|
||||||
void __stdcall shared_destroy ();
|
void __stdcall shared_destroy ();
|
||||||
|
|
||||||
#define shared_align_past(p) \
|
#define shared_align_past(p) \
|
||||||
|
|
Loading…
Reference in New Issue