Bug in cmalloc? Was: Re: Problems with: Improvements to fork handling (2/5)

Christopher Faylor cgf-use-the-mailinglist-please@cygwin.com
Mon May 30 06:25:00 GMT 2011

On Sun, May 29, 2011 at 12:27:45PM -0400, Christopher Faylor wrote:
>On Sun, May 29, 2011 at 01:51:35AM -0400, Ryan Johnson wrote:
>>So, I defined this small function:
>>static void break_cmalloc(int depth, int maxdepth) {
>>     void* x = cmalloc (HEAP_2_DLL, 32);
>>     cfree(x);
>>     if (depth < maxdepth)
>>         break_cmalloc(depth+1, maxdepth);
>>and called it during fork instead of dlls.topsort(), with maxdepth=5. No 
>>bug (as expected).
>>Then I moved the call to cfree below the recursion, so memory gets freed 
>>in reverse order. Bang. Bash goes down and takes mintty with it after 
>>briefly flashing 'bad address.' Calling bash from cmd.exe hangs the 
>>latter so badly Windows can't kill it (I guess I'll have to reboot).
>Thanks for the test case.  I'll investigate later today.

As it turns out, this is not a bug in cmalloc.  fork() was not designed
to allow calling cmalloc() after the "frok grouped" definition at the
beginning of the function.  That records the bounds of the cygheap which
is passed to the child.  If you call cmalloc and friends after that then
the child process will never know that the heap has been extended.  Then
when the heap is copied from the parent by cygheap_fixup_in_child(),
you'll likely be missing pieces of the parent's cygheap and pieces of
the freed pool will end up pointing into blocks of memory which are not
properly initialized.

So, anyway, the problem can likely be fixed by moving the call to
topsort earlier.  I'll try that tomorrow.


More information about the Cygwin-patches mailing list