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]

Re: mmap of large amount returns invalid pointer



> If you look into the strace you'll see that MapViewOfFileEx()
> returns a valid memory area.  And no, it does *not* return an
> error code.  MapViewOfFileEx() is reliable enough to not return
> a memory area and an error code.
>
> The failing function is a following VirtualProtect() which job
> is to set the memory protection on the allocated memory area
> correctly.  And that's actually surprising.  VirtualProtect()
> shouldn't have problems with memory since it doesn't allocate
> any.  At least it shouldn't.

Having now read mmap.cc, this is how I interpret the strace as well.
I'm afraid I know almost nothing about Windows and have no explanation
as to why the VirtualProtect fails.

> But the real problem is that the page file is, well, full after
> the mmap() call.  A following printf is trying to allocate a
> small amount of memory but allocation fails apparently and at
> one point a check for a failed malloc() is missing.
> So the SEGV is actually a followup of the fact that there isn't
> any memory left to allocate.

I don't think this explanation is correct.  I still think that mmap is
returning a pointer to an invalid chunk of memory.  To demonstrate
this, here is a program that does an mmap, fprintf, and then attempts
to write to the first byte of the mmap'ed memory.

--------------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
#include <windows.h>

void
die(char *fmt, ...)
{
	va_list	args;

	fflush(stdout);
	va_start(args, fmt);
	vfprintf(stderr, fmt, args);
	va_end(args);
	fprintf(stderr, "\n");
	exit(1);
}

int main (int argc, char **argv) {
	uint length;
	void *p;

	length = 130000000;
	p = mmap (NULL, length, 
			PROT_READ | PROT_WRITE, 
			MAP_PRIVATE | MAP_ANON, -1, 0);
	if ((void*)-1 == p)
		die("mmap failed\n");
	fprintf(stderr, "mmap succeeded\n");
	((char*)p)[0] = 'a';
	if (-1 == munmap(p, length))
		die("munmap failed\n");
	return 0;
}
--------------------------------------------------------------------------------

When I run this program, the mmap and fprintf succeed, and then there
is a segfault, presumably in the store to p[0].  Here is a snippet of
the strace to corroborate.

 1546  597904 [main] bug 161 mmap: addr 0, len 130000000, prot 3, flags 22, fd -1, off 0
 5208  603112 [main] bug 161 fhandler_disk_file::mmap: 2A230000 = MapViewOfFileEx (h:144, access:1, 0, off:0, len:130023424, addr:0)
 7918  611030 [main] bug 161 mmap_record::map_map: -1 = map_map (): Win32 error 1455
 1380  612410 [main] bug 161 mmap: 2A230000 = mmap() succeeded
 1076  613486 [main] bug 161 _write: write (2, 0x22F758, 15)
 1050  614536 [main] bug 161 fhandler_base::write: binary write
mmap succeeded
 1060  615596 [main] bug 161 fhandler_base::write: 15 = write (0x22F758, 15)
 1005  616601 [main] bug 161 _write: 15 = write (2, 0x22F758, 15)
 2225  618826 [main] bug 161 handle_exceptions: In cygwin_except_handler exc 0xC0000005 at 0x401140 sp 0x22FE80
 1043  619869 [main] bug 161 handle_exceptions: In cygwin_except_handler sig = 11 at 0x401140
 1236  621105 [main] bug 161 handle_exceptions: In cygwin_except_handler calling 0x0
 622178 [main] bug 161 handle_exceptions: Exception: STATUS_ACCESS_VIOLATION
 1073  622178 [main] bug 161 handle_exceptions: Exception: STATUS_ACCESS_VIOLATION

On the other hand, if I decrease the length from 130,000,000 to
13,000,000, then the VirtualProtect does not complain, and the store
to p[0] and munmap both succeed.  Here is the strace snippet.

 1140  594523 [main] bug 68 mmap: addr 0, len 13000000, prot 3, flags 22, fd -1, off 0
 7013  601536 [main] bug 68 fhandler_disk_file::mmap: 2A230000 = MapViewOfFileEx (h:144, access:1, 0, off:0, len:13041664, addr:0)
 4912  606448 [main] bug 68 mmap: 2A230000 = mmap() succeeded
 1185  607633 [main] bug 68 _write: write (2, 0x22F758, 15)
 1614  609247 [main] bug 68 fhandler_base::write: binary write
mmap succeeded
 1150  610397 [main] bug 68 fhandler_base::write: 15 = write (0x22F758, 15)
 1024  611421 [main] bug 68 _write: 15 = write (2, 0x22F758, 15)
 1141  612562 [main] bug 68 munmap: munmap (addr 2A230000, len 13000000)
 3703  616265 [main] bug 68 munmap: 0 = munmap(): 2A230000

My conclusion remains that the mmap(130,000,000) is returning a
pointer to invalid memory.  I don't know if the problem is connected
to the failure of VirtualProtect or not.  I will continue to
investigate, but would still appreciate any assistance.

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.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]