12
12
*/
13
13
#include "postgres.h"
14
14
15
+ #include "lib/stringinfo.h"
15
16
#include "miscadmin.h"
16
17
#include "storage/dsm.h"
17
18
#include "storage/ipc.h"
@@ -54,26 +55,31 @@ mi_state(DWORD code)
54
55
return "???" ;
55
56
}
56
57
58
+ /*
59
+ * Append memory dump to buf. To avoid affecting the memory map mid-run,
60
+ * buf should be preallocated to be bigger than needed.
61
+ */
57
62
static void
58
- dumpmem (const char * reason )
63
+ dumpmem (StringInfo buf , const char * reason )
59
64
{
60
65
char * addr = 0 ;
61
66
MEMORY_BASIC_INFORMATION mi ;
62
67
63
- elog ( LOG , "%s memory map" , reason );
68
+ appendStringInfo ( buf , "%s memory map: " , reason );
64
69
do
65
70
{
66
71
memset (& mi , 0 , sizeof (mi ));
67
72
if (!VirtualQuery (addr , & mi , sizeof (mi )))
68
73
{
69
74
if (GetLastError () == ERROR_INVALID_PARAMETER )
70
75
break ;
71
- elog ( LOG , "VirtualQuery failed: %lu" , GetLastError ());
76
+ appendStringInfo ( buf , "\nVirtualQuery failed: %lu" , GetLastError ());
72
77
break ;
73
78
}
74
- elog (LOG , "0x%p+0x%p %s (alloc 0x%p) %s" ,
75
- mi .BaseAddress , (void * ) mi .RegionSize ,
76
- mi_type (mi .Type ), mi .AllocationBase , mi_state (mi .State ));
79
+ appendStringInfo (buf , "\n0x%p+0x%p %s (alloc 0x%p) %s" ,
80
+ mi .BaseAddress , (void * ) mi .RegionSize ,
81
+ mi_type (mi .Type ), mi .AllocationBase ,
82
+ mi_state (mi .State ));
77
83
addr += mi .RegionSize ;
78
84
} while (addr > 0 );
79
85
}
@@ -442,11 +448,16 @@ PGSharedMemoryReAttach(void)
442
448
{
443
449
PGShmemHeader * hdr ;
444
450
void * origUsedShmemSegAddr = UsedShmemSegAddr ;
451
+ StringInfoData buf ;
445
452
446
453
Assert (UsedShmemSegAddr != NULL );
447
454
Assert (IsUnderPostmaster );
448
455
449
- dumpmem ("before VirtualFree" );
456
+ /* Ensure buf is big enough that it won't grow mid-operation */
457
+ initStringInfo (& buf );
458
+ enlargeStringInfo (& buf , 128 * 1024 );
459
+
460
+ dumpmem (& buf , "before VirtualFree" );
450
461
451
462
/*
452
463
* Release memory region reservation that was made by the postmaster
@@ -455,27 +466,28 @@ PGSharedMemoryReAttach(void)
455
466
elog (FATAL , "failed to release reserved memory region (addr=%p): error code %lu" ,
456
467
UsedShmemSegAddr , GetLastError ());
457
468
458
- dumpmem ("after VirtualFree" );
469
+ dumpmem (& buf , "after VirtualFree" );
459
470
460
471
hdr = (PGShmemHeader * ) MapViewOfFileEx (UsedShmemSegID , FILE_MAP_READ | FILE_MAP_WRITE , 0 , 0 , 0 , UsedShmemSegAddr );
461
472
if (!hdr )
462
473
{
463
474
DWORD maperr = GetLastError ();
464
475
465
- dumpmem ("after failed MapViewOfFileEx" );
476
+ dumpmem (& buf , "after failed MapViewOfFileEx" );
477
+ elog (LOG , "%s" , buf .data );
466
478
467
479
elog (FATAL , "could not reattach to shared memory (key=%p, addr=%p): error code %lu" ,
468
480
UsedShmemSegID , UsedShmemSegAddr , maperr );
469
481
}
470
- else
471
- dumpmem ("after MapViewOfFileEx" );
472
482
if (hdr != origUsedShmemSegAddr )
473
483
elog (FATAL , "reattaching to shared memory returned unexpected address (got %p, expected %p)" ,
474
484
hdr , origUsedShmemSegAddr );
475
485
if (hdr -> magic != PGShmemMagic )
476
486
elog (FATAL , "reattaching to shared memory returned non-PostgreSQL memory" );
477
487
dsm_set_control_handle (hdr -> dsm_control );
478
488
489
+ pfree (buf .data );
490
+
479
491
UsedShmemSegAddr = hdr ; /* probably redundant */
480
492
}
481
493
0 commit comments