[PATCH] Large processes shared.cc fix
Eizenberg Ariel
arielez@cs.huji.ac.il
Sat Jan 1 08:49:00 GMT 2005
In addition to the last letter, I forgot to write that the first
open_shared() is executed with m==SH_CYGWIN_SHARED.
This sets offsets[SH_MYSELF] to an invalid address, and then when
pinfo::init() runs, open_shared(0, SH_MYSELF) returns offsets[SH_MYSELF]
without checking since size == 0;
On Fri, 31 Dec 2004, Eizenberg Ariel wrote:
| The original code in open_shared() runs as follows:
|
| shared = (shared_info*)MapViewOfFileEx(shared_h, ..., addr);
| -> this fails
|
| if(!shared)
| {
| shared = (shared_info*)MapViewOfFileEx(shared_h, ..., NULL);
| -> this returns 0x3d0000
| }
|
| if(m == SH_CYGWIN_SHARED && ...)
| {
| unsigned delta = ...;
| ...
| for(int i = SH_CYGWIN_SHARED + 1 ; i < SH_TOTAL_SIZE; i ++)
| {
| unsigned size = ...;
| offsets[i] += delta;
| -> for i >= 3, offsets[i] >= 0x400000, which is the image base address
| if(!VirtualAlloc(offsets[i], size, ...))
| continue;
| -> so for i >= 3, this fails
| }
|
| now, when pinfo::init() requests
| mapaddr = open_shared(NULL, 0, hdummy, 0, SH_MYSELF)
|
| open_shared() returns and address at 0x420000 because of:
| addr = offsets[m];
| if(!size)
| return addr;
|
| altough addr might be illegal.
|
| Now when pinfo::init() continues,
| procinfo = (_pinfo *)MapViewOfFileEx(h, ...., mapaddr);
|
| which fails, and we get an api_fatal().
|
| So the purpose of my patch is to make sure offsets[i] is always a
| valid address for allocation.
|
| Hope this clears it up.
|
| Thanks.
|
|
| On Fri, 31 Dec 2004, Christopher Faylor wrote:
|
| | On Fri, Dec 31, 2004 at 03:58:20PM +0200, Eizenberg Ariel wrote:
| | >Hi,
| | >
| | >This patch fixes a problem I have with running large fortran programs
| | >(actually most programs with a very large image size in memory). The
| | >problem occurs on Windows 2000, XP and 2003.
| | >
| | >The problem occurs when a process is large enough so when open_shared()
| | >tries to map the shared memory section to 0x0A000000, it fails, since
| | >0x0A000000 is occupied by the program. Since the
| | >MapViewOfFileEx(h,...,NULL) is preformed on a region smaller than the full
| | >region required for offsets[SH_TOTAL_SIZE], MapViewOfFileEx might allocate
| | >a region at a location which does not have enough free space after it,
| | >so the VirtualAlloc's at the end of open_shared() silently fail
| | >(in my case MapViewOfFileEx() returns 0x3d0000).
| |
| | So, why is this a problem? Why doesn't the "if (!shared)" immediately after
| | the first MapViewOfFileEx just avoid allocating the other non SH_CYGWIN_SHARED
| | shared memory regions at a fixed location? That is what that code is there
| | to handle.
| |
| | cgf
| |
| |
|
|
More information about the Cygwin-patches
mailing list