mmap of large amount returns invalid pointer

Stephen Weeks sweeks@acm.org
Wed Mar 13 14:25:00 GMT 2002


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


More information about the Cygwin mailing list

AltStyle によって変換されたページ (->オリジナル) /