Get still more info about Windows can't-reattach-to-shared-memory errors.
After some thought about the info captured so far, it seems possible that MapViewOfFileEx is itself causing some DLL to get loaded into the space just freed by VirtualFree. The previous commit here didn't capture enough info to really prove the case for that, so let's add one more VirtualQuery in between those steps. Also, be sure to capture the post-Map state before we emit any log entries, just in case elog() is invoking some code not previously loaded. Discussion: https://postgr.es/m/25495.1524517820@sss.pgh.pa.us
This commit is contained in:
parent
6bdf1303b3
commit
eb16011f4c
@ -389,16 +389,18 @@ PGSharedMemoryReAttach(void)
|
|||||||
PGShmemHeader *hdr;
|
PGShmemHeader *hdr;
|
||||||
void *origUsedShmemSegAddr = UsedShmemSegAddr;
|
void *origUsedShmemSegAddr = UsedShmemSegAddr;
|
||||||
MEMORY_BASIC_INFORMATION previnfo;
|
MEMORY_BASIC_INFORMATION previnfo;
|
||||||
DWORD queryerr;
|
MEMORY_BASIC_INFORMATION afterinfo;
|
||||||
|
DWORD preverr;
|
||||||
|
DWORD aftererr;
|
||||||
|
|
||||||
Assert(UsedShmemSegAddr != NULL);
|
Assert(UsedShmemSegAddr != NULL);
|
||||||
Assert(IsUnderPostmaster);
|
Assert(IsUnderPostmaster);
|
||||||
|
|
||||||
/* Preliminary probe of region we intend to release */
|
/* Preliminary probe of region we intend to release */
|
||||||
if (VirtualQuery(UsedShmemSegAddr, &previnfo, sizeof(previnfo)) != 0)
|
if (VirtualQuery(UsedShmemSegAddr, &previnfo, sizeof(previnfo)) != 0)
|
||||||
queryerr = 0;
|
preverr = 0;
|
||||||
else
|
else
|
||||||
queryerr = GetLastError();
|
preverr = GetLastError();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Release memory region reservation that was made by the postmaster
|
* Release memory region reservation that was made by the postmaster
|
||||||
@ -407,27 +409,48 @@ PGSharedMemoryReAttach(void)
|
|||||||
elog(FATAL, "failed to release reserved memory region (addr=%p): error code %lu",
|
elog(FATAL, "failed to release reserved memory region (addr=%p): error code %lu",
|
||||||
UsedShmemSegAddr, GetLastError());
|
UsedShmemSegAddr, GetLastError());
|
||||||
|
|
||||||
|
/* Verify post-release state */
|
||||||
|
if (VirtualQuery(UsedShmemSegAddr, &afterinfo, sizeof(afterinfo)) != 0)
|
||||||
|
aftererr = 0;
|
||||||
|
else
|
||||||
|
aftererr = GetLastError();
|
||||||
|
|
||||||
hdr = (PGShmemHeader *) MapViewOfFileEx(UsedShmemSegID, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0, UsedShmemSegAddr);
|
hdr = (PGShmemHeader *) MapViewOfFileEx(UsedShmemSegID, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0, UsedShmemSegAddr);
|
||||||
if (!hdr)
|
if (!hdr)
|
||||||
{
|
{
|
||||||
DWORD maperr = GetLastError();
|
DWORD maperr = GetLastError();
|
||||||
MEMORY_BASIC_INFORMATION info;
|
MEMORY_BASIC_INFORMATION postinfo;
|
||||||
|
DWORD posterr;
|
||||||
|
|
||||||
if (queryerr == 0)
|
/* Capture post-failure state */
|
||||||
|
if (VirtualQuery(UsedShmemSegAddr, &postinfo, sizeof(postinfo)) != 0)
|
||||||
|
posterr = 0;
|
||||||
|
else
|
||||||
|
posterr = GetLastError();
|
||||||
|
|
||||||
|
if (preverr == 0)
|
||||||
elog(LOG, "VirtualQuery(%p) before free reports region of size %zu, base %p, has state 0x%lx",
|
elog(LOG, "VirtualQuery(%p) before free reports region of size %zu, base %p, has state 0x%lx",
|
||||||
UsedShmemSegAddr, previnfo.RegionSize,
|
UsedShmemSegAddr, previnfo.RegionSize,
|
||||||
previnfo.AllocationBase, previnfo.State);
|
previnfo.AllocationBase, previnfo.State);
|
||||||
else
|
else
|
||||||
elog(LOG, "VirtualQuery(%p) before free failed: error code %lu",
|
elog(LOG, "VirtualQuery(%p) before free failed: error code %lu",
|
||||||
UsedShmemSegAddr, queryerr);
|
UsedShmemSegAddr, preverr);
|
||||||
|
|
||||||
if (VirtualQuery(UsedShmemSegAddr, &info, sizeof(info)) != 0)
|
if (aftererr == 0)
|
||||||
elog(LOG, "VirtualQuery(%p) after free reports region of size %zu, base %p, has state 0x%lx",
|
elog(LOG, "VirtualQuery(%p) after free reports region of size %zu, base %p, has state 0x%lx",
|
||||||
UsedShmemSegAddr, info.RegionSize,
|
UsedShmemSegAddr, afterinfo.RegionSize,
|
||||||
info.AllocationBase, info.State);
|
afterinfo.AllocationBase, afterinfo.State);
|
||||||
else
|
else
|
||||||
elog(LOG, "VirtualQuery(%p) after free failed: error code %lu",
|
elog(LOG, "VirtualQuery(%p) after free failed: error code %lu",
|
||||||
UsedShmemSegAddr, GetLastError());
|
UsedShmemSegAddr, aftererr);
|
||||||
|
|
||||||
|
if (posterr == 0)
|
||||||
|
elog(LOG, "VirtualQuery(%p) after map reports region of size %zu, base %p, has state 0x%lx",
|
||||||
|
UsedShmemSegAddr, postinfo.RegionSize,
|
||||||
|
postinfo.AllocationBase, postinfo.State);
|
||||||
|
else
|
||||||
|
elog(LOG, "VirtualQuery(%p) after map failed: error code %lu",
|
||||||
|
UsedShmemSegAddr, posterr);
|
||||||
|
|
||||||
elog(FATAL, "could not reattach to shared memory (key=%p, addr=%p): error code %lu",
|
elog(FATAL, "could not reattach to shared memory (key=%p, addr=%p): error code %lu",
|
||||||
UsedShmemSegID, UsedShmemSegAddr, maperr);
|
UsedShmemSegID, UsedShmemSegAddr, maperr);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user