]> granicus.if.org Git - postgresql/commitdiff
Map and unmap the shared memory block before risking VirtualFree.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 30 Apr 2018 21:07:14 +0000 (17:07 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 30 Apr 2018 21:07:14 +0000 (17:07 -0400)
The idea here is to get Windows' userspace infrastructure to allocate
whatever space it needs for MapViewOfFileEx() before we release the
locked-down space that we want to map the shared memory block into.

This is a fairly brute-force attempt, and would likely (for example)
fail with large shared memory on 32-bit Windows.  We could perhaps
ameliorate that by mapping only part of the shared memory block in
this way, but for the moment I just want to see if this approach
will fix dory's problem.

Discussion: https://postgr.es/m/25495.1524517820@sss.pgh.pa.us

src/backend/port/win32_shmem.c

index dd66756b99129cad82726b8cd5c538ae01089c23..0f140e7a36987754bae8d86ff287ce801a1b69c7 100644 (file)
@@ -65,7 +65,7 @@ dumpmem(StringInfo buf, const char *reason)
        char       *addr = 0;
        MEMORY_BASIC_INFORMATION mi;
 
-       appendStringInfo(buf, "%s memory map:", reason);
+       appendStringInfo(buf, "%s memory map:\n", reason);
        do
        {
                memset(&mi, 0, sizeof(mi));
@@ -73,10 +73,10 @@ dumpmem(StringInfo buf, const char *reason)
                {
                        if (GetLastError() == ERROR_INVALID_PARAMETER)
                                break;
-                       appendStringInfo(buf, "\nVirtualQuery failed: %lu", GetLastError());
+                       appendStringInfo(buf, "VirtualQuery failed: %lu\n", GetLastError());
                        break;
                }
-               appendStringInfo(buf, "\n0x%p+0x%p %s (alloc 0x%p) %s",
+               appendStringInfo(buf, "0x%p+0x%p %s (alloc 0x%p) %s\n",
                                                 mi.BaseAddress, (void *) mi.RegionSize,
                                                 mi_type(mi.Type), mi.AllocationBase,
                                                 mi_state(mi.State));
@@ -457,6 +457,22 @@ PGSharedMemoryReAttach(void)
        initStringInfo(&buf);
        enlargeStringInfo(&buf, 128 * 1024);
 
+       dumpmem(&buf, "beginning PGSharedMemoryReAttach");
+
+       hdr = (PGShmemHeader *) MapViewOfFileEx(UsedShmemSegID, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0, NULL);
+       if (hdr)
+       {
+               if (!UnmapViewOfFile(hdr))
+                       elog(LOG, "could not unmap temporary view of shared memory: error code %lu",
+                                GetLastError());
+       }
+       else
+       {
+               /* This isn't fatal, just unpromising ... */
+               elog(LOG, "could not attach to shared memory (key=%p) at any address: error code %lu",
+                        UsedShmemSegID, GetLastError());
+       }
+
        dumpmem(&buf, "before VirtualFree");
 
        /*
@@ -479,6 +495,10 @@ PGSharedMemoryReAttach(void)
                elog(FATAL, "could not reattach to shared memory (key=%p, addr=%p): error code %lu",
                         UsedShmemSegID, UsedShmemSegAddr, maperr);
        }
+
+       dumpmem(&buf, "after MapViewOfFileEx");
+       elog(LOG, "%s", buf.data);
+
        if (hdr != origUsedShmemSegAddr)
                elog(FATAL, "reattaching to shared memory returned unexpected address (got %p, expected %p)",
                         hdr, origUsedShmemSegAddr);