This is the mail archive of the cygwin@cygwin.com 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]

1.3.22-1 on XP: malloc returns overlapping buffers


I am finding that under some circumstances a buffer returned by malloc
will overlap with a buffer returned by a previous call to malloc that
has not been freed.  I was able to reduce it to the following test
case.  Running under cygwin 1.3.22-1 on Windows XP Professional
Version 2002 SP1 it reports an overlap of 4824 bytes on two different
machines, as well as on a third machine running Windows 2000 5.00.2195
SP4.  On Windows NT 4.0.1381, it finds no overlap.

Am I doing something wrong or is there a bug in malloc or XP?  More
details below.

------------------------------------------------------------------------

#include <stdio.h>
#include <stdlib.h>

int
main (int argc, char **argv)
{
  char *mm = 0, *p;
  int size = 8000, overlap;

  p = malloc (1);

  while (mm < p) {
    mm = malloc (16777216);
    if (mm == 0) {
      printf ("not enough memory to run test\n");
      exit (0);
    }
    printf ("malloc (16777216) = %d\n", (int)mm);
  }

  while ((p = malloc (size))) {
    overlap = (int)p + size - (int)mm;
    if (p < mm && overlap > 0) {
      printf ("overlap = %d\n", overlap);
      exit (1);
    }
  }
  return 0;
}

------------------------------------------------------------------------

The 16MB malloc's are large enough to get malloc to mmap the memory
for the buffer.  Initially, the pointers returned are below the 1-byte
buffer, but eventually one will be returned that is above it.  Then
the 8436 byte malloc's fill up the space between the 1 byte buffer and
the last mmap'ed buffer until either the buffer returned overlaps the
mmap'ed buffer, or it runs out of memory.

The printf that prints out the 16MB buffer pointers seems to be
required in order for the code to exhibit the problem.

If I use sizes much larger than 8000 for the last malloc's, it will
segfault, and this is the traceback I get from gdb:

#0  0x610404be in mktime () from /usr/bin/cygwin1.dll
#1  0x61040e55 in mktime () from /usr/bin/cygwin1.dll
#2  0x610415e8 in cygwin1!calloc () from /usr/bin/cygwin1.dll
#3  0x61041f7d in strdup () from /usr/bin/cygwin1.dll
#4  0x61042a1d in strdup () from /usr/bin/cygwin1.dll
#5  0x61043444 in mmap64 () from /usr/bin/cygwin1.dll
#6  0x61043849 in mmap () from /usr/bin/cygwin1.dll
#7  0x610401bc in mktime () from /usr/bin/cygwin1.dll
#8  0x61040413 in mktime () from /usr/bin/cygwin1.dll
#9  0x610413e6 in malloc () from /usr/bin/cygwin1.dll
#10 0x00401169 in main (argc=1, argv=0xa041418) at malloc_bug.c:21

I notice that malloc calls mmap which then calls calloc.  Is the
malloc code sufficiently re-entrant for that to work?

-- 
Russell O'Connor
roconnor@hsc.usf.edu

Attachment: cygcheck.out
Description: Text document

--
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]