1212 */
1313#include "postgres.h"
1414
15+ #include <psapi.h>
16+
1517#include "miscadmin.h"
1618#include "storage/dsm.h"
1719#include "storage/ipc.h"
@@ -24,6 +26,88 @@ static Size UsedShmemSegSize = 0;
2426static bool EnableLockPagesPrivilege (int elevel );
2527static void pgwin32_SharedMemoryDelete (int status , Datum shmId );
2628
29+ /* Dump all modules loaded into proc */
30+ static void
31+ dumpdlls (HANDLE proc )
32+ {
33+ HMODULE dll [1024 ];
34+ DWORD size_used = 1 ;
35+ int i ,
36+ n ;
37+
38+ if (!EnumProcessModules (proc , dll , sizeof (dll ), & size_used ))
39+ {
40+ elog (LOG , "EnumProcessModules failed: %lu" , GetLastError ());
41+ return ;
42+ }
43+ n = (int ) (size_used / sizeof (* dll ));
44+ elog (LOG , "EnumProcessModules: %d modules in process 0x%p" , n , proc );
45+ for (i = 0 ; i < n ; i ++ )
46+ {
47+ char name [MAXPGPATH ];
48+
49+ if (!GetModuleFileNameEx (proc , dll [i ], name , sizeof (name )))
50+ sprintf (name , "GetModuleFileNameEx failed: %lu" , GetLastError ());
51+ elog (LOG , "%d: 0x%p %s" , i + 1 , dll [i ], name );
52+ }
53+ }
54+
55+ static const char *
56+ mi_type (DWORD code )
57+ {
58+ switch (code )
59+ {
60+ case MEM_IMAGE :
61+ return "img" ;
62+ case MEM_MAPPED :
63+ return "map" ;
64+ case MEM_PRIVATE :
65+ return "prv" ;
66+ }
67+ return "???" ;
68+ }
69+
70+ static const char *
71+ mi_state (DWORD code )
72+ {
73+ switch (code )
74+ {
75+ case MEM_COMMIT :
76+ return "commit" ;
77+ case MEM_FREE :
78+ return "free " ;
79+ case MEM_RESERVE :
80+ return "reserv" ;
81+ }
82+ return "???" ;
83+ }
84+
85+ static void
86+ dumpmem (const char * reason , HANDLE proc )
87+ {
88+ char * addr = 0 ;
89+ MEMORY_BASIC_INFORMATION mi ;
90+
91+ elog (LOG , "%s memory map" , reason );
92+ do
93+ {
94+ memset (& mi , 0 , sizeof (mi ));
95+ if (!VirtualQueryEx (proc , addr , & mi , sizeof (mi )))
96+ {
97+ if (GetLastError () == ERROR_INVALID_PARAMETER )
98+ break ;
99+ elog (LOG , "VirtualQueryEx failed: %lu" , GetLastError ());
100+ break ;
101+ }
102+ elog (LOG , "0x%p+0x%p %s (alloc 0x%p) %s" ,
103+ mi .BaseAddress , (void * ) mi .RegionSize ,
104+ mi_type (mi .Type ), mi .AllocationBase , mi_state (mi .State ));
105+ addr += mi .RegionSize ;
106+ } while (addr > 0 );
107+
108+ dumpdlls (proc );
109+ }
110+
27111/*
28112 * Generate shared memory segment name. Expand the data directory, to generate
29113 * an identifier unique for this data directory. Then replace all backslashes
@@ -388,19 +472,11 @@ PGSharedMemoryReAttach(void)
388472{
389473 PGShmemHeader * hdr ;
390474 void * origUsedShmemSegAddr = UsedShmemSegAddr ;
391- MEMORY_BASIC_INFORMATION previnfo ;
392- MEMORY_BASIC_INFORMATION afterinfo ;
393- DWORD preverr ;
394- DWORD aftererr ;
395475
396476 Assert (UsedShmemSegAddr != NULL );
397477 Assert (IsUnderPostmaster );
398478
399- /* Preliminary probe of region we intend to release */
400- if (VirtualQuery (UsedShmemSegAddr , & previnfo , sizeof (previnfo )) != 0 )
401- preverr = 0 ;
402- else
403- preverr = GetLastError ();
479+ dumpmem ("before VirtualFree" , GetCurrentProcess ());
404480
405481 /*
406482 * Release memory region reservation that was made by the postmaster
@@ -409,48 +485,14 @@ PGSharedMemoryReAttach(void)
409485 elog (FATAL , "failed to release reserved memory region (addr=%p): error code %lu" ,
410486 UsedShmemSegAddr , GetLastError ());
411487
412- /* Verify post-release state */
413- if (VirtualQuery (UsedShmemSegAddr , & afterinfo , sizeof (afterinfo )) != 0 )
414- aftererr = 0 ;
415- else
416- aftererr = GetLastError ();
488+ dumpmem ("after VirtualFree" , GetCurrentProcess ());
417489
418490 hdr = (PGShmemHeader * ) MapViewOfFileEx (UsedShmemSegID , FILE_MAP_READ | FILE_MAP_WRITE , 0 , 0 , 0 , UsedShmemSegAddr );
419491 if (!hdr )
420492 {
421493 DWORD maperr = GetLastError ();
422- MEMORY_BASIC_INFORMATION postinfo ;
423- DWORD posterr ;
424-
425- /* Capture post-failure state */
426- if (VirtualQuery (UsedShmemSegAddr , & postinfo , sizeof (postinfo )) != 0 )
427- posterr = 0 ;
428- else
429- posterr = GetLastError ();
430-
431- if (preverr == 0 )
432- elog (LOG , "VirtualQuery(%p) before free reports region of size %zu, base %p, has state 0x%lx" ,
433- UsedShmemSegAddr , previnfo .RegionSize ,
434- previnfo .AllocationBase , previnfo .State );
435- else
436- elog (LOG , "VirtualQuery(%p) before free failed: error code %lu" ,
437- UsedShmemSegAddr , preverr );
438494
439- if (aftererr == 0 )
440- elog (LOG , "VirtualQuery(%p) after free reports region of size %zu, base %p, has state 0x%lx" ,
441- UsedShmemSegAddr , afterinfo .RegionSize ,
442- afterinfo .AllocationBase , afterinfo .State );
443- else
444- elog (LOG , "VirtualQuery(%p) after free failed: error code %lu" ,
445- UsedShmemSegAddr , aftererr );
446-
447- if (posterr == 0 )
448- elog (LOG , "VirtualQuery(%p) after map reports region of size %zu, base %p, has state 0x%lx" ,
449- UsedShmemSegAddr , postinfo .RegionSize ,
450- postinfo .AllocationBase , postinfo .State );
451- else
452- elog (LOG , "VirtualQuery(%p) after map failed: error code %lu" ,
453- UsedShmemSegAddr , posterr );
495+ dumpmem ("after MapViewOfFileEx" , GetCurrentProcess ());
454496
455497 elog (FATAL , "could not reattach to shared memory (key=%p, addr=%p): error code %lu" ,
456498 UsedShmemSegID , UsedShmemSegAddr , maperr );
@@ -597,5 +639,7 @@ pgwin32_ReserveSharedMemoryRegion(HANDLE hChild)
597639 return false;
598640 }
599641
642+ dumpmem ("after reserve" , hChild );
643+
600644 return true;
601645}
0 commit comments