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

Re: find(1) memory leak in cygheap


On Wed, Aug 19, 2009 at 11:04 PM, Haojun Bao<baohaojun@gmail.com> wrote:
> On Wed, Aug 19, 2009 at 10:03 PM, Christopher
> Faylor<cgf-use-the-mailinglist-please@cygwin.com> wrote:
>> On Wed, Aug 19, 2009 at 07:47:37PM +0800, Haojun Bao wrote:
>>>I found this problem when running updatedb, the find will print
>>>
>>> ? ? ?2 [main] find 2592 C:\cygwin\bin\find.exe: *** fatal error -
>>>cmalloc would have returned NULL
>>>
>>>I have dumped the cygheap using gdb to see what's in it, the size is
>>>about 25M, and I use strings.exe to examine the strings
>>>in it, all the folder names that find has looked into is in it, both
>>>native format and cygwin format of the folders names.
>>>
>>>And there are lot's of folders in my android source folder, so the
>>>cygheap is filled up. I think maybe this is a memory leak?
>>>
>>>Please use the following script to test:
>>
>> How about if you provide us with cygcheck output first?
>>
> Sorry, here's the cygcheck output attached
>
I have done some debugging, and the culprit should be dup(2) syscall.
Here's another test case, this time written in C.

Note that the cygheap_start and cygheap_max value will be very likely
different on your computer, so you should use gdb to take a peek into
cygwin1.dll to get your value. Or else you should remove the reference
to these memory location.

The test case will show cygheap is always growing, and at the end it will print
  1 [main] a 3560 Q:\a.exe: *** fatal error - cmalloc would have returned NULL

Here's the code:

#include <unistd.h>
     #include <sys/types.h>
     #include <dirent.h>
     #include <sys/types.h>
     #include <sys/stat.h>
     #include <fcntl.h>

void ** _cygheap_start = (void **)0x612076b0;
void ** cygheap_max = (void **)0x6114b104;

#include <stdio.h>

int main()
{
/*make a big buffer to fill quicker*/
	char buf[4095] = {'/'};
	int i;
	for (i=1; i<sizeof(buf)-1; i++) {
		buf[i]='x';
		if (i%200 == 0) {
			buf[i] = '/';
			if (mkdir(buf, 0777)<0) {
				printf("Error: mkdir %s", buf);
				exit(-1);
			}
		}
	}
	mkdir(buf, 0777);
	int fd = open(buf, O_RDONLY);
	while (1) {
		int fd2 = dup(fd);
		printf("fd2 is %d\n", fd2);
		close(fd2);
		printf ("heap start: 0x%08x, end: 0x%08x\n", *_cygheap_start, *cygheap_max);
	}
}

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]