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)
5455return "???" ;
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{
6065char * addr = 0 ;
6166MEMORY_BASIC_INFORMATION mi ;
6267
63- elog ( LOG ,"%s memory map" ,reason );
68+ appendStringInfo ( buf ,"%s memory map: " ,reason );
6469do
6570{
6671memset (& mi ,0 ,sizeof (mi ));
6772if (!VirtualQuery (addr ,& mi ,sizeof (mi )))
6873{
6974if (GetLastError ()== ERROR_INVALID_PARAMETER )
7075break ;
71- elog ( LOG ,"VirtualQuery failed: %lu" ,GetLastError ());
76+ appendStringInfo ( buf ,"\nVirtualQuery failed: %lu" ,GetLastError ());
7277break ;
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 ));
7783addr += mi .RegionSize ;
7884}while (addr > 0 );
7985}
@@ -442,11 +448,16 @@ PGSharedMemoryReAttach(void)
442448{
443449PGShmemHeader * hdr ;
444450void * origUsedShmemSegAddr = UsedShmemSegAddr ;
451+ StringInfoData buf ;
445452
446453Assert (UsedShmemSegAddr != NULL );
447454Assert (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)
455466elog (FATAL ,"failed to release reserved memory region (addr=%p): error code %lu" ,
456467UsedShmemSegAddr ,GetLastError ());
457468
458- dumpmem ("after VirtualFree" );
469+ dumpmem (& buf , "after VirtualFree" );
459470
460471hdr = (PGShmemHeader * )MapViewOfFileEx (UsedShmemSegID ,FILE_MAP_READ |FILE_MAP_WRITE ,0 ,0 ,0 ,UsedShmemSegAddr );
461472if (!hdr )
462473{
463474DWORD maperr = GetLastError ();
464475
465- dumpmem ("after failed MapViewOfFileEx" );
476+ dumpmem (& buf ,"after failed MapViewOfFileEx" );
477+ elog (LOG ,"%s" ,buf .data );
466478
467479elog (FATAL ,"could not reattach to shared memory (key=%p, addr=%p): error code %lu" ,
468480UsedShmemSegID ,UsedShmemSegAddr ,maperr );
469481}
470- else
471- dumpmem ("after MapViewOfFileEx" );
472482if (hdr != origUsedShmemSegAddr )
473483elog (FATAL ,"reattaching to shared memory returned unexpected address (got %p, expected %p)" ,
474484hdr ,origUsedShmemSegAddr );
475485if (hdr -> magic != PGShmemMagic )
476486elog (FATAL ,"reattaching to shared memory returned non-PostgreSQL memory" );
477487dsm_set_control_handle (hdr -> dsm_control );
478488
489+ pfree (buf .data );
490+
479491UsedShmemSegAddr = hdr ;/* probably redundant */
480492}
481493