--- /tmp/port/win32_shmem.c 2012-09-04 22:36:08.000000000 -0400 +++ third-party/postgresql/src/backend/port/win32_shmem.c 2012-09-04 23:18:47.000000000 -0400 @@ -120,6 +120,7 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port) { void *memAddress; + void *preferredAddress; PGShmemHeader *hdr; HANDLE hmap, hmap2; @@ -224,6 +225,65 @@ (errmsg("could not create shared memory segment: %lu", GetLastError()), errdetail("Failed system call was MapViewOfFileEx."))); + /* + * Now try to allocate memory at an address that is less + * contentious in newborn child processes. Because of ASLR, + * Windows can memory map images (like postgres.exe) such that + * they conflict with memAddress as we have selected it above. + * Microsoft provides no assurance that MapViewOfFileEx(..., + * NULL) returns addresses disjoint from those in use in a + * newborn process. They have been observed to intersect from + * time to time on Windows 8. See email to pg-bugs from + * Dave Vitek on September 4 2012. + * + * Now we set preferredAddress to a hardcoded address that + * newborn processes never seem to be using (in available + * versions of Windows). I have selected the addresses + * somewhat randomly in order to minimize the probability that + * some other library doing something similar conflicts with + * us. That is, using conspicuous addresses like 0x20000000 + * might not be good if someone else does it. + * + * GRAMMATECH: See internal tracker BZ:9250. + */ +#ifdef _WIN64 + /* + * There is typically a giant hole (almost 8TB): + * 00000000 7fff0000 + * ... + * 000007f6 8e8b0000 + */ + preferredAddress = (void*)0x0000047047e00000ULL; +#else + /* + * This is more dicey. However, even with ASLR there still + * seems to be a big hole: + * 10000000 + * ... + * 70000000 + */ + preferredAddress = 0x2efe0000; +#endif + /* + * In order to be faithful to ASLR, we maintain any entropy + * from the bottom bits of memAddress when selecting the + * preferredAddress. I'm not sure MapViewOfFile attempts to + * be unpredictable, but better to be future-proof even if it + * doesn't. + */ + preferredAddress = (void*)(((UINT_PTR)preferredAddress) + (((UINT_PTR)memAddress) & ((UINT_PTR)0x0fffffff))); + preferredAddress = MapViewOfFileEx(hmap2, FILE_MAP_WRITE | FILE_MAP_READ, 0, 0, 0, preferredAddress); + if( preferredAddress ) + { + if (!UnmapViewOfFile(memAddress)) + elog(LOG, "could not unmap view of unwanted shared memory: %lu", GetLastError()); + memAddress = preferredAddress; + } + else + { + elog(LOG, "could not create shared memory segment at preferred address (%p): %lu", + preferredAddress, GetLastError()); + } /*