diff --git a/src/backend/Makefile b/src/backend/Makefile index 7a0bbb2..498bdc9 100644 --- a/src/backend/Makefile +++ b/src/backend/Makefile @@ -80,7 +80,7 @@ libpostgres.a: postgres ; endif # cygwin ifeq ($(PORTNAME), win32) -LIBS += -lsecur32 +LIBS += -lsecur32 -lpsapi postgres: $(OBJS) $(WIN32RES) $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_EX) -Wl,--stack=$(WIN32_STACK_RLIMIT) -Wl,--export-all-symbols -Wl,--out-implib=libpostgres.a $(call expand_subsys,$(OBJS)) $(WIN32RES) $(LIBS) -o $@$(X) diff --git a/src/backend/port/win32_shmem.c b/src/backend/port/win32_shmem.c index 31489fc..1e35278 100644 --- a/src/backend/port/win32_shmem.c +++ b/src/backend/port/win32_shmem.c @@ -17,12 +17,85 @@ #include "storage/ipc.h" #include "storage/pg_shmem.h" +#include + HANDLE UsedShmemSegID = INVALID_HANDLE_VALUE; void *UsedShmemSegAddr = NULL; static Size UsedShmemSegSize = 0; static void pgwin32_SharedMemoryDelete(int status, Datum shmId); +static void +dumpdlls(HANDLE *proc) +{ + HMODULE dll[512]; + DWORD size_used = 1; + int i; + + if (!EnumProcessModules(proc, dll, sizeof(dll), &size_used)) + { + elog(LOG, "EnumProcessModules failed: %lu", GetLastError()); + return; + } + if (size_used == 0) + elog(LOG, "EnumProcessModules: no modules"); + + for (i = 0; i < size_used / sizeof(*dll); i++) + { + char name[MAXPGPATH]; + + if (!GetModuleFileNameEx(proc, dll[i], name, sizeof(name))) + sprintf(name, "GetModuleFileNameEx failed: %lu", GetLastError()); + elog(LOG, "0x%p %s", dll[i], name); + } +} + +static const char * +mi_type(DWORD code) +{ + switch (code) { + case MEM_IMAGE: return "img"; + case MEM_MAPPED: return "map"; + case MEM_PRIVATE: return "prv"; + } + return "???"; +} + +static const char * +mi_state(DWORD code) +{ + switch (code) { + case MEM_COMMIT: return "commit"; + case MEM_FREE: return "free "; + case MEM_RESERVE: return "reserv"; + } + return "???"; +} + +static void +dumpmem(const char *reason, HANDLE *proc) +{ + char *addr = 0; + MEMORY_BASIC_INFORMATION mi; + + elog(LOG, "%s memory map", reason); + do { + if (0 == VirtualQueryEx(proc, addr, &mi, sizeof(mi))) + { + if (GetLastError() == ERROR_INVALID_PARAMETER) + break; + elog(LOG, "VirtualQueryEx failed: %lu", GetLastError()); + return; + } + elog(LOG, "0x%p+0x%p %s (alloc 0x%p) %s", + mi.BaseAddress, (void *) mi.RegionSize, + mi_type(mi.Type), mi.AllocationBase, mi_state(mi.State)); + addr += mi.RegionSize; + } while (addr > 0); + + dumpdlls(proc); +} + /* * Generate shared memory segment name. Expand the data directory, to generate * an identifier unique for this data directory. Then replace all backslashes @@ -276,6 +349,8 @@ PGSharedMemoryReAttach(void) Assert(UsedShmemSegAddr != NULL); Assert(IsUnderPostmaster); + dumpmem("before reattach", GetCurrentProcess()); + /* * Release memory region reservation that was made by the postmaster */ @@ -408,6 +483,7 @@ pgwin32_ReserveSharedMemoryRegion(HANDLE hChild) address = VirtualAllocEx(hChild, UsedShmemSegAddr, UsedShmemSegSize, MEM_RESERVE, PAGE_READWRITE); + dumpmem("after reserve", hChild); if (address == NULL) { /* Don't use FATAL since we're running in the postmaster */ diff --git a/src/makefiles/Makefile.win32 b/src/makefiles/Makefile.win32 index 7abbd01..678371d 100644 --- a/src/makefiles/Makefile.win32 +++ b/src/makefiles/Makefile.win32 @@ -1,5 +1,7 @@ # src/makefiles/Makefile.win32 +override CPPFLAGS+= -DPSAPI_VERSION=1 + ifdef PGXS BE_DLLLIBS= -L$(libdir) -lpostgres override CPPFLAGS+= -I$(includedir_server)/port/win32 diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm index 12f73f3..4c39f33 100644 --- a/src/tools/msvc/Mkvcbuild.pm +++ b/src/tools/msvc/Mkvcbuild.pm @@ -172,8 +172,10 @@ sub mkvcbuild 'repl_gram.y', 'syncrep_scanner.l', 'syncrep_gram.y'); $postgres->AddDefine('BUILDING_DLL'); + $postgres->AddDefine('PSAPI_VERSION=1'); $postgres->AddLibrary('secur32.lib'); $postgres->AddLibrary('ws2_32.lib'); + $postgres->AddLibrary('psapi.lib'); $postgres->AddLibrary('wldap32.lib') if ($solution->{options}->{ldap}); $postgres->FullExportDLL('postgres.lib');