Address space clobbers during fork() (was Re: Extending /proc/*/maps)

Christopher Faylor
Thu Apr 21 14:24:00 GMT 2011

On Thu, Apr 21, 2011 at 10:53:41AM +0200, Corinna Vinschen wrote:
>On Apr 19 14:16, Ryan Johnson wrote:
>> On 19/04/2011 12:01 PM, Corinna Vinschen wrote:
>> >On Apr 19 11:38, Ryan Johnson wrote:
>> >>BTW, /cygdrive/c/Windows/System32/locale.nls seems to be the reason
>> >>that even statically linked dlls don't always load in the same place
>> >>twice in a row.
>> >How so?  And then, when is it loaded?  I assume that this file is
>> >fetched as soon as the GetLocaleInfo function is called.  What OS
>> >are you using?  If it's Vista or later, there's a chance that the
>> >LocaleNameToLCID function is the culprit as well.  But the real
>> >problem is, how can that be worked around?  For the locale stuff
>> >we need these functions.
>> (subject changed to reflect what we're actually discussing)
>> I'm using Win7-x64.
>> When locale.nls gets mapped in, Windows doesn't always put it in the
>> same place. As a result, fork() can run into all the usual problems
>> with DLL base addresses, except it can bite even statically-linked
>> dlls.
>> [...]
>> Recall that cygfoo.dll and cygbar.dll both want to load at 00660000.
>> The latter always gets the coveted base address because it always
>> loads first (last in link order? luck?). In the parent, locale.nls
>> maps to 002B0000, while cygfoo.dll loads at 00320000. The child, on
>> the other hand, puts cygfoo.dll at 002B0000, and maps locale.nls to
>> 00380000. That latter address is reserved for some sort of anonymous
>> memory in the parent (most likely a thread stack,*** since there are
>> some guarded pages at 003B9000 and it's not a heap). My best guess
>> is that this stack lives at 00410000 in the child, which is free
>> space in the parent.
>Unfortunately there's no way set the thread stack address manually.
>If we want to have that under control we would have to create a thread,
>then create a new stack and free the original one.  That's kind of
>tricky.  Or slow.

Actually that's what alloc_stack_hard_way does but we surely don't want
to use this for every thread or every fork.


More information about the Cygwin-developers mailing list