static pid_t
internal_forkexec(int argc, char *argv[], Port *port)
{
+ int retry_count = 0;
STARTUPINFO si;
PROCESS_INFORMATION pi;
int i;
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);
/*
* 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;
}
/*