diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 5f4dd68941..95180b2ef5 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -4510,6 +4510,7 @@ internal_forkexec(int argc, char *argv[], Port *port) static pid_t internal_forkexec(int argc, char *argv[], Port *port) { + int retry_count = 0; STARTUPINFO si; PROCESS_INFORMATION pi; int i; @@ -4527,6 +4528,9 @@ internal_forkexec(int argc, char *argv[], Port *port) Assert(strncmp(argv[1], "--fork", 6) == 0); Assert(argv[2] == NULL); + /* Resume here if we need to retry */ +retry: + /* Set up shared memory for parameter passing */ ZeroMemory(&sa, sizeof(sa)); sa.nLength = sizeof(sa); @@ -4618,22 +4622,26 @@ internal_forkexec(int argc, char *argv[], Port *port) /* * Reserve the memory region used by our main shared memory segment before - * we resume the child process. + * we resume the child process. Normally this should succeed, but if ASLR + * is active then it might sometimes fail due to the stack or heap having + * gotten mapped into that range. In that case, just terminate the + * process and retry. */ if (!pgwin32_ReserveSharedMemoryRegion(pi.hProcess)) { - /* - * Failed to reserve the memory, so terminate the newly created - * process and give up. - */ + /* pgwin32_ReserveSharedMemoryRegion already made a log entry */ if (!TerminateProcess(pi.hProcess, 255)) ereport(LOG, (errmsg_internal("could not terminate process that failed to reserve memory: error code %lu", GetLastError()))); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); - return -1; /* logging done made by - * pgwin32_ReserveSharedMemoryRegion() */ + if (++retry_count < 100) + goto retry; + ereport(LOG, + (errmsg("giving up after too many tries to reserve shared memory"), + errhint("This might be caused by ASLR or antivirus software."))); + return -1; } /*