Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Message-ID: <20040314142804.95562.qmail@web13005.mail.yahoo.com> Date: Sun, 14 Mar 2004 06:28:04 -0800 (PST) From: Scott Duplichan Subject: fork problem with msys and cygwin binaries on Win64: solved! To: cygwin AT cygwin DOT com MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Note-from-DJ: This may be spam I would like to see if I can use msys or cygwin to build 64-bit binaries for Win64. The first problem encountered is a fork problem with the 32-bit tools when run on Win64. I get this error message: *** fork: can't reserve memory for stack 0x480000 - 0x680000 The problem seems to originate with the way Win64 arranges the virtual address space in the new process created by fork. In Win32, the virtual address layout created by CreateProcess matches the virtual address layout from the parent process created by Windows. But in Win64, they differ. For example, the initial sh.exe address space looks like this: 0x10000-0x010fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0x20000-0x020fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0x30000-0x228fff MEM_RESERVE MEM_PRIVATE 0x229000-0x229fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE PAGE_GUARD 0x22a000-0x22ffff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0x230000-0x233fff MEM_COMMIT MEM_MAPPED PAGE_READONLY 0x240000-0x244fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0x245000-0x2bffff MEM_RESERVE MEM_PRIVATE 0x2c0000-0x2c5fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0x2c6000-0x2cffff MEM_RESERVE MEM_PRIVATE 0x2d0000-0x2d0fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0x2e0000-0x2e9fff MEM_COMMIT MEM_PRIVATE PAGE_EXECUTE_READWRITE 0x2ea000-0x3dffff MEM_RESERVE MEM_PRIVATE 0x3e0000-0x3e5fff MEM_COMMIT MEM_PRIVATE PAGE_EXECUTE_READWRITE 0x3e6000-0x3effff MEM_RESERVE MEM_PRIVATE 0x3f0000-0x3f3fff MEM_COMMIT MEM_MAPPED PAGE_READWRITE 0x3f4000-0x3fffff MEM_RESERVE MEM_MAPPED 0x400000-0x400fff MEM_COMMIT MEM_IMAGE PAGE_READONLY 0x401000-0x46efff MEM_COMMIT MEM_IMAGE PAGE_EXECUTE_READ 0x46f000-0x477fff MEM_COMMIT MEM_IMAGE PAGE_READWRITE 0x478000-0x478fff MEM_COMMIT MEM_IMAGE PAGE_WRITECOPY 0x479000-0x479fff MEM_COMMIT MEM_IMAGE PAGE_READWRITE 0x480000-0x679fff MEM_RESERVE MEM_PRIVATE 0x67a000-0x67afff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE PAGE_GUARD 0x67b000-0x67ffff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE <===== stack 0x680000-0x695fff MEM_COMMIT MEM_MAPPED PAGE_READONLY 0x6a0000-0x6d3fff MEM_COMMIT MEM_MAPPED PAGE_READONLY 0x6e0000-0x720fff MEM_COMMIT MEM_MAPPED PAGE_READONLY 0x730000-0x735fff MEM_COMMIT MEM_MAPPED PAGE_READONLY 0x740000-0x746fff MEM_COMMIT MEM_MAPPED PAGE_EXECUTE_READ 0x747000-0x8bffff MEM_RESERVE MEM_MAPPED 0x8c0000-0x8c2fff MEM_COMMIT MEM_MAPPED PAGE_EXECUTE_READ 0x8c3000-0x8c7fff MEM_RESERVE MEM_MAPPED 0x8d0000-0xa52fff MEM_COMMIT MEM_MAPPED PAGE_READONLY 0xa60000-0xaf2fff MEM_COMMIT MEM_MAPPED PAGE_EXECUTE_READ 0xaf3000-0xedffff MEM_RESERVE MEM_MAPPED 0xee0000-0xee0fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0xef0000-0xef0fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0xf00000-0xf11fff MEM_COMMIT MEM_MAPPED PAGE_READWRITE 0xf20000-0x111dfff MEM_RESERVE MEM_PRIVATE 0x111e000-0x111efff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE PAGE_GUARD 0x111f000-0x111ffff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0x1120000-0x1176fff MEM_RESERVE MEM_PRIVATE 0x1177000-0x1177fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE PAGE_GUARD 0x1178000-0x117ffff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0x1180000-0x1180fff MEM_COMMIT MEM_MAPPED PAGE_READWRITE 0x1190000-0x1193fff MEM_COMMIT MEM_PRIVATE PAGE_EXECUTE_READWRITE 0x1194000-0x119ffff MEM_RESERVE MEM_PRIVATE 0x11a0000-0x11a2fff MEM_COMMIT MEM_MAPPED PAGE_READONLY 0x11b0000-0x13adfff MEM_RESERVE MEM_PRIVATE 0x13ae000-0x13aefff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE PAGE_GUARD 0x13af000-0x13affff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0x13b0000-0x1406fff MEM_RESERVE MEM_PRIVATE 0x1407000-0x1407fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE PAGE_GUARD 0x1408000-0x140ffff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0x1410000-0x1410fff MEM_COMMIT MEM_MAPPED PAGE_READWRITE 0x1420000-0x161dfff MEM_RESERVE MEM_PRIVATE 0x161e000-0x161efff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE PAGE_GUARD 0x161f000-0x161ffff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0x1620000-0x1676fff MEM_RESERVE MEM_PRIVATE 0x1677000-0x1677fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE PAGE_GUARD 0x1678000-0x167ffff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0xa000000-0xa00bfff MEM_COMMIT MEM_MAPPED PAGE_READWRITE 0xa010000-0xa030fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0xa031000-0x1a00ffff MEM_RESERVE MEM_PRIVATE 0x5ccf0000-0x5ccf0fff MEM_COMMIT MEM_IMAGE PAGE_READONLY 0x5ccf1000-0x5ccfcfff MEM_COMMIT MEM_IMAGE PAGE_EXECUTE_READ 0x5ccfd000-0x5ccfdfff MEM_COMMIT MEM_IMAGE PAGE_READWRITE 0x5ccfe000-0x5ccfffff MEM_COMMIT MEM_IMAGE PAGE_READONLY But the address space for sh.exe created by fork looks like this: 0x10000-0x010fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0x20000-0x020fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0x30000-0x225fff MEM_RESERVE MEM_PRIVATE 0x226000-0x226fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE PAGE_GUARD 0x227000-0x22ffff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE <===== stack 0x230000-0x286fff MEM_RESERVE MEM_PRIVATE 0x287000-0x287fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE PAGE_GUARD 0x288000-0x28ffff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0x290000-0x290fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0x2a0000-0x2a3fff MEM_COMMIT MEM_MAPPED PAGE_READONLY 0x2b0000-0x2b4fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0x2b5000-0x32ffff MEM_RESERVE MEM_PRIVATE 0x330000-0x335fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0x336000-0x33ffff MEM_RESERVE MEM_PRIVATE 0x340000-0x345fff MEM_COMMIT MEM_PRIVATE PAGE_EXECUTE_READWRITE 0x346000-0x34ffff MEM_RESERVE MEM_PRIVATE 0x350000-0x353fff MEM_COMMIT MEM_MAPPED PAGE_READWRITE 0x354000-0x35ffff MEM_RESERVE MEM_MAPPED 0x360000-0x375fff MEM_COMMIT MEM_MAPPED PAGE_READONLY 0x380000-0x3b3fff MEM_COMMIT MEM_MAPPED PAGE_READONLY 0x3c0000-0x3c5fff MEM_COMMIT MEM_MAPPED PAGE_READONLY 0x3d0000-0x3d0fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0x3e0000-0x3e0fff MEM_COMMIT MEM_PRIVATE PAGE_READWRITE 0x400000-0x400fff MEM_COMMIT MEM_IMAGE PAGE_READONLY 0x401000-0x46efff MEM_COMMIT MEM_IMAGE PAGE_EXECUTE_READ 0x46f000-0x476fff MEM_COMMIT MEM_IMAGE PAGE_WRITECOPY 0x477000-0x477fff MEM_COMMIT MEM_IMAGE PAGE_READWRITE 0x478000-0x478fff MEM_COMMIT MEM_IMAGE PAGE_WRITECOPY 0x479000-0x479fff MEM_COMMIT MEM_IMAGE PAGE_READWRITE 0x480000-0x483fff MEM_COMMIT MEM_PRIVATE PAGE_EXECUTE_READWRITE 0x484000-0x57ffff MEM_RESERVE MEM_PRIVATE 0x580000-0x5c0fff MEM_COMMIT MEM_MAPPED PAGE_READONLY 0x5d0000-0x5d6fff MEM_COMMIT MEM_MAPPED PAGE_EXECUTE_READ 0x5d7000-0x74ffff MEM_RESERVE MEM_MAPPED 0x750000-0x752fff MEM_COMMIT MEM_MAPPED PAGE_EXECUTE_READ 0x753000-0x757fff MEM_RESERVE MEM_MAPPED 0x760000-0x8e2fff MEM_COMMIT MEM_MAPPED PAGE_READONLY 0x8f0000-0x982fff MEM_COMMIT MEM_MAPPED PAGE_EXECUTE_READ 0x983000-0xd6ffff MEM_RESERVE MEM_MAPPED The stacks are in different places, which is not the case on Win32. At first, I thought the fork child process creation would have to be modified so that the resulting child address layout would match that of the parent process created by Windows. But there is a better (and easier) way. The solution is to make the address layout of the initial parent process match the address layout that results when fork calls CreateProcess. All that is required is the initial msys rxvt.exe or cygwin bash.exe originate from a CreateProcess invocation similar to the one used by those executables. Rxvt and bash could be modified to re-launch themselves using CreateProcess. But for now, I am using a stand-alone launcher to solve the problem: http://users2.ev1.net/~sduplichan/amd64/createprocess.c http://users2.ev1.net/~sduplichan/amd64/createprocess.exe For msys.bat, createprocess rxvt -backspacekey  -sl 2500 -fg %FGCOLOR% -bg %BGCOLOR% -sr -fn Courier-20 -geometry 90x40 -tn msys -e /bin/sh --login -i For cygwin.bat, createprocess bash --login -i My testing is with Windows for AMD64, but this probably works on Win64 for Itanium, too. The fix seems solid. A clean make of the msys dll completes without error, in 98 seconds. -- Scott __________________________________ Do you Yahoo!? Yahoo! Mail - More reliable, more storage, less spam http://mail.yahoo.com -- 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/