12
12
*/
13
13
#include "postgres.h"
14
14
15
+ #include <psapi.h>
16
+
15
17
#include "miscadmin.h"
16
18
#include "storage/dsm.h"
17
19
#include "storage/ipc.h"
@@ -24,6 +26,88 @@ static Size UsedShmemSegSize = 0;
24
26
static bool EnableLockPagesPrivilege (int elevel );
25
27
static void pgwin32_SharedMemoryDelete (int status , Datum shmId );
26
28
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
+
27
111
/*
28
112
* Generate shared memory segment name. Expand the data directory, to generate
29
113
* an identifier unique for this data directory. Then replace all backslashes
@@ -388,19 +472,11 @@ PGSharedMemoryReAttach(void)
388
472
{
389
473
PGShmemHeader * hdr ;
390
474
void * origUsedShmemSegAddr = UsedShmemSegAddr ;
391
- MEMORY_BASIC_INFORMATION previnfo ;
392
- MEMORY_BASIC_INFORMATION afterinfo ;
393
- DWORD preverr ;
394
- DWORD aftererr ;
395
475
396
476
Assert (UsedShmemSegAddr != NULL );
397
477
Assert (IsUnderPostmaster );
398
478
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 ());
404
480
405
481
/*
406
482
* Release memory region reservation that was made by the postmaster
@@ -409,48 +485,14 @@ PGSharedMemoryReAttach(void)
409
485
elog (FATAL , "failed to release reserved memory region (addr=%p): error code %lu" ,
410
486
UsedShmemSegAddr , GetLastError ());
411
487
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 ());
417
489
418
490
hdr = (PGShmemHeader * ) MapViewOfFileEx (UsedShmemSegID , FILE_MAP_READ | FILE_MAP_WRITE , 0 , 0 , 0 , UsedShmemSegAddr );
419
491
if (!hdr )
420
492
{
421
493
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 );
438
494
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 ());
454
496
455
497
elog (FATAL , "could not reattach to shared memory (key=%p, addr=%p): error code %lu" ,
456
498
UsedShmemSegID , UsedShmemSegAddr , maperr );
@@ -597,5 +639,7 @@ pgwin32_ReserveSharedMemoryRegion(HANDLE hChild)
597
639
return false;
598
640
}
599
641
642
+ dumpmem ("after reserve" , hChild );
643
+
600
644
return true;
601
645
}
0 commit comments