1212 */
1313#include "postgres.h"
1414
15+ #include "lib/stringinfo.h"
1516#include "miscadmin.h"
1617#include "storage/dsm.h"
1718#include "storage/ipc.h"
@@ -54,26 +55,31 @@ mi_state(DWORD code)
5455 return "???" ;
5556}
5657
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+ */
5762static void
58- dumpmem (const char * reason )
63+ dumpmem (StringInfo buf , const char * reason )
5964{
6065 char * addr = 0 ;
6166 MEMORY_BASIC_INFORMATION mi ;
6267
63- elog ( LOG , "%s memory map" , reason );
68+ appendStringInfo ( buf , "%s memory map: " , reason );
6469 do
6570 {
6671 memset (& mi , 0 , sizeof (mi ));
6772 if (!VirtualQuery (addr , & mi , sizeof (mi )))
6873 {
6974 if (GetLastError () == ERROR_INVALID_PARAMETER )
7075 break ;
71- elog ( LOG , "VirtualQuery failed: %lu" , GetLastError ());
76+ appendStringInfo ( buf , "\nVirtualQuery failed: %lu" , GetLastError ());
7277 break ;
7378 }
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 ));
7783 addr += mi .RegionSize ;
7884 } while (addr > 0 );
7985}
@@ -442,11 +448,16 @@ PGSharedMemoryReAttach(void)
442448{
443449 PGShmemHeader * hdr ;
444450 void * origUsedShmemSegAddr = UsedShmemSegAddr ;
451+ StringInfoData buf ;
445452
446453 Assert (UsedShmemSegAddr != NULL );
447454 Assert (IsUnderPostmaster );
448455
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" );
450461
451462 /*
452463 * Release memory region reservation that was made by the postmaster
@@ -455,27 +466,28 @@ PGSharedMemoryReAttach(void)
455466 elog (FATAL , "failed to release reserved memory region (addr=%p): error code %lu" ,
456467 UsedShmemSegAddr , GetLastError ());
457468
458- dumpmem ("after VirtualFree" );
469+ dumpmem (& buf , "after VirtualFree" );
459470
460471 hdr = (PGShmemHeader * ) MapViewOfFileEx (UsedShmemSegID , FILE_MAP_READ | FILE_MAP_WRITE , 0 , 0 , 0 , UsedShmemSegAddr );
461472 if (!hdr )
462473 {
463474 DWORD maperr = GetLastError ();
464475
465- dumpmem ("after failed MapViewOfFileEx" );
476+ dumpmem (& buf , "after failed MapViewOfFileEx" );
477+ elog (LOG , "%s" , buf .data );
466478
467479 elog (FATAL , "could not reattach to shared memory (key=%p, addr=%p): error code %lu" ,
468480 UsedShmemSegID , UsedShmemSegAddr , maperr );
469481 }
470- else
471- dumpmem ("after MapViewOfFileEx" );
472482 if (hdr != origUsedShmemSegAddr )
473483 elog (FATAL , "reattaching to shared memory returned unexpected address (got %p, expected %p)" ,
474484 hdr , origUsedShmemSegAddr );
475485 if (hdr -> magic != PGShmemMagic )
476486 elog (FATAL , "reattaching to shared memory returned non-PostgreSQL memory" );
477487 dsm_set_control_handle (hdr -> dsm_control );
478488
489+ pfree (buf .data );
490+
479491 UsedShmemSegAddr = hdr ; /* probably redundant */
480492}
481493
0 commit comments