Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 836db92

Browse files
author
Commitfest Bot
committed
[CF 5748] v3 - Improve Valgrind support and remove some memory leaks
This branch was automatically generated by a robot using patches from an email thread registered at: https://commitfest.postgresql.org/patch/5748 The branch will be overwritten each time a new patch version is posted to the thread, and also periodically to check for bitrot caused by changes on the master branch. Patch(es): https://www.postgresql.org/message-id/2884224.1748035274@sss.pgh.pa.us Author(s): Tom Lane
2 parents b006bcd + 32fd40f commit 836db92

31 files changed

+546
-125
lines changed

src/backend/access/transam/xlog.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -703,7 +703,7 @@ static void InitControlFile(uint64 sysidentifier, uint32 data_checksum_version);
703703
static void WriteControlFile(void);
704704
static void ReadControlFile(void);
705705
static void UpdateControlFile(void);
706-
static char *str_time(pg_time_t tnow);
706+
static char *str_time(pg_time_t tnow, char *buf, size_t bufsize);
707707

708708
static int get_sync_bit(int method);
709709

@@ -5381,11 +5381,9 @@ BootStrapXLOG(uint32 data_checksum_version)
53815381
}
53825382

53835383
static char *
5384-
str_time(pg_time_t tnow)
5384+
str_time(pg_time_t tnow, char *buf, size_t bufsize)
53855385
{
5386-
char *buf = palloc(128);
5387-
5388-
pg_strftime(buf, 128,
5386+
pg_strftime(buf, bufsize,
53895387
"%Y-%m-%d %H:%M:%S %Z",
53905388
pg_localtime(&tnow, log_timezone));
53915389

@@ -5628,6 +5626,7 @@ StartupXLOG(void)
56285626
XLogRecPtr missingContrecPtr;
56295627
TransactionId oldestActiveXID;
56305628
bool promoted = false;
5629+
char timebuf[128];
56315630

56325631
/*
56335632
* We should have an aux process resource owner to use, and we should not
@@ -5656,41 +5655,47 @@ StartupXLOG(void)
56565655
*/
56575656
ereport(IsPostmasterEnvironment ? LOG : NOTICE,
56585657
(errmsg("database system was shut down at %s",
5659-
str_time(ControlFile->time))));
5658+
str_time(ControlFile->time,
5659+
timebuf, sizeof(timebuf)))));
56605660
break;
56615661

56625662
case DB_SHUTDOWNED_IN_RECOVERY:
56635663
ereport(LOG,
56645664
(errmsg("database system was shut down in recovery at %s",
5665-
str_time(ControlFile->time))));
5665+
str_time(ControlFile->time,
5666+
timebuf, sizeof(timebuf)))));
56665667
break;
56675668

56685669
case DB_SHUTDOWNING:
56695670
ereport(LOG,
56705671
(errmsg("database system shutdown was interrupted; last known up at %s",
5671-
str_time(ControlFile->time))));
5672+
str_time(ControlFile->time,
5673+
timebuf, sizeof(timebuf)))));
56725674
break;
56735675

56745676
case DB_IN_CRASH_RECOVERY:
56755677
ereport(LOG,
56765678
(errmsg("database system was interrupted while in recovery at %s",
5677-
str_time(ControlFile->time)),
5679+
str_time(ControlFile->time,
5680+
timebuf, sizeof(timebuf))),
56785681
errhint("This probably means that some data is corrupted and"
56795682
" you will have to use the last backup for recovery.")));
56805683
break;
56815684

56825685
case DB_IN_ARCHIVE_RECOVERY:
56835686
ereport(LOG,
56845687
(errmsg("database system was interrupted while in recovery at log time %s",
5685-
str_time(ControlFile->checkPointCopy.time)),
5688+
str_time(ControlFile->checkPointCopy.time,
5689+
timebuf, sizeof(timebuf))),
56865690
errhint("If this has occurred more than once some data might be corrupted"
56875691
" and you might need to choose an earlier recovery target.")));
56885692
break;
56895693

56905694
case DB_IN_PRODUCTION:
56915695
ereport(LOG,
56925696
(errmsg("database system was interrupted; last known up at %s",
5693-
str_time(ControlFile->time))));
5697+
str_time(ControlFile->time,
5698+
timebuf, sizeof(timebuf)))));
56945699
break;
56955700

56965701
default:
@@ -6336,6 +6341,12 @@ StartupXLOG(void)
63366341
*/
63376342
CompleteCommitTsInitialization();
63386343

6344+
/* Clean up EndOfWalRecoveryInfo data to appease Valgrind leak checking */
6345+
if (endOfRecoveryInfo->lastPage)
6346+
pfree(endOfRecoveryInfo->lastPage);
6347+
pfree(endOfRecoveryInfo->recoveryStopReason);
6348+
pfree(endOfRecoveryInfo);
6349+
63396350
/*
63406351
* All done with end-of-recovery actions.
63416352
*

src/backend/access/transam/xlogrecovery.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1626,6 +1626,7 @@ ShutdownWalRecovery(void)
16261626
close(readFile);
16271627
readFile = -1;
16281628
}
1629+
pfree(xlogreader->private_data);
16291630
XLogReaderFree(xlogreader);
16301631
XLogPrefetcherFree(xlogprefetcher);
16311632

src/backend/libpq/pqcomm.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -858,7 +858,6 @@ RemoveSocketFiles(void)
858858
(void) unlink(sock_path);
859859
}
860860
/* Since we're about to exit, no need to reclaim storage */
861-
sock_paths = NIL;
862861
}
863862

864863

src/backend/libpq/pqmq.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include "tcop/tcopprot.h"
2424
#include "utils/builtins.h"
2525

26-
static shm_mq_handle *pq_mq_handle;
26+
static shm_mq_handle *pq_mq_handle = NULL;
2727
static bool pq_mq_busy = false;
2828
static pid_t pq_mq_parallel_leader_pid = 0;
2929
static ProcNumber pq_mq_parallel_leader_proc_number = INVALID_PROC_NUMBER;
@@ -66,6 +66,8 @@ pq_redirect_to_shm_mq(dsm_segment *seg, shm_mq_handle *mqh)
6666
static void
6767
pq_cleanup_redirect_to_shm_mq(dsm_segment *seg, Datum arg)
6868
{
69+
if (pq_mq_handle != NULL)
70+
pfree(pq_mq_handle);
6971
pq_mq_handle = NULL;
7072
whereToSendOutput = DestNone;
7173
}
@@ -131,7 +133,10 @@ mq_putmessage(char msgtype, const char *s, size_t len)
131133
if (pq_mq_busy)
132134
{
133135
if (pq_mq_handle != NULL)
136+
{
134137
shm_mq_detach(pq_mq_handle);
138+
pfree(pq_mq_handle);
139+
}
135140
pq_mq_handle = NULL;
136141
return EOF;
137142
}
@@ -152,15 +157,14 @@ mq_putmessage(char msgtype, const char *s, size_t len)
152157
iov[1].data = s;
153158
iov[1].len = len;
154159

155-
Assert(pq_mq_handle != NULL);
156-
157160
for (;;)
158161
{
159162
/*
160163
* Immediately notify the receiver by passing force_flush as true so
161164
* that the shared memory value is updated before we send the parallel
162165
* message signal right after this.
163166
*/
167+
Assert(pq_mq_handle != NULL);
164168
result = shm_mq_sendv(pq_mq_handle, iov, 2, true, true);
165169

166170
if (pq_mq_parallel_leader_pid != 0)

src/backend/postmaster/autovacuum.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,16 @@ static AutoVacuumShmemStruct *AutoVacuumShmem;
310310
static dlist_head DatabaseList = DLIST_STATIC_INIT(DatabaseList);
311311
static MemoryContext DatabaseListCxt = NULL;
312312

313+
/*
314+
* Dummy pointer to persuade Valgrind that we've not leaked the array of
315+
* avl_dbase structs. Make it global to ensure the compiler doesn't
316+
* optimize it away.
317+
*/
318+
#ifdef USE_VALGRIND
319+
extern avl_dbase *avl_dbase_array;
320+
avl_dbase *avl_dbase_array;
321+
#endif
322+
313323
/* Pointer to my own WorkerInfo, valid on each worker */
314324
static WorkerInfo MyWorkerInfo = NULL;
315325

@@ -1020,6 +1030,10 @@ rebuild_database_list(Oid newdb)
10201030

10211031
/* put all the hash elements into an array */
10221032
dbary = palloc(nelems * sizeof(avl_dbase));
1033+
/* keep Valgrind quiet */
1034+
#ifdef USE_VALGRIND
1035+
avl_dbase_array = dbary;
1036+
#endif
10231037

10241038
i = 0;
10251039
hash_seq_init(&seq, dbhash);
@@ -2565,8 +2579,18 @@ do_autovacuum(void)
25652579

25662580
/*
25672581
* We leak table_toast_map here (among other things), but since we're
2568-
* going away soon, it's not a problem.
2582+
* going away soon, it's not a problem normally. But when using Valgrind,
2583+
* release some stuff to reduce complaints about leaked storage.
25692584
*/
2585+
#ifdef USE_VALGRIND
2586+
hash_destroy(table_toast_map);
2587+
FreeTupleDesc(pg_class_desc);
2588+
if (bstrategy)
2589+
pfree(bstrategy);
2590+
#endif
2591+
2592+
/* Run the rest in xact context, mainly to avoid Valgrind leak warnings */
2593+
MemoryContextSwitchTo(TopTransactionContext);
25702594

25712595
/*
25722596
* Update pg_database.datfrozenxid, and truncate pg_xact if possible. We

src/backend/postmaster/pmchild.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,17 @@ NON_EXEC_STATIC int num_pmchild_slots = 0;
5959
*/
6060
dlist_head ActiveChildList;
6161

62+
/*
63+
* Dummy pointer to persuade Valgrind that we've not leaked the array of
64+
* PMChild structs. Make it global to ensure the compiler doesn't
65+
* optimize it away.
66+
*/
67+
#ifdef USE_VALGRIND
68+
extern PMChild *pmchild_array;
69+
PMChild *pmchild_array;
70+
#endif
71+
72+
6273
/*
6374
* MaxLivePostmasterChildren
6475
*
@@ -125,8 +136,13 @@ InitPostmasterChildSlots(void)
125136
for (int i = 0; i < BACKEND_NUM_TYPES; i++)
126137
num_pmchild_slots += pmchild_pools[i].size;
127138

128-
/* Initialize them */
139+
/* Allocate enough slots, and make sure Valgrind doesn't complain */
129140
slots = palloc(num_pmchild_slots * sizeof(PMChild));
141+
#ifdef USE_VALGRIND
142+
pmchild_array = slots;
143+
#endif
144+
145+
/* Initialize them */
130146
slotno = 0;
131147
for (int btype = 0; btype < BACKEND_NUM_TYPES; btype++)
132148
{

src/backend/replication/logical/launcher.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,8 @@ logicalrep_worker_detach(void)
766766
}
767767

768768
LWLockRelease(LogicalRepWorkerLock);
769+
770+
list_free(workers);
769771
}
770772

771773
/* Block concurrent access. */

src/backend/storage/buffer/localbuf.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -925,10 +925,11 @@ GetLocalBufferStorage(void)
925925
num_bufs = Min(num_bufs, MaxAllocSize / BLCKSZ);
926926

927927
/* Buffers should be I/O aligned. */
928-
cur_block = (char *)
929-
TYPEALIGN(PG_IO_ALIGN_SIZE,
930-
MemoryContextAlloc(LocalBufferContext,
931-
num_bufs * BLCKSZ + PG_IO_ALIGN_SIZE));
928+
cur_block = MemoryContextAllocAligned(LocalBufferContext,
929+
num_bufs * BLCKSZ,
930+
PG_IO_ALIGN_SIZE,
931+
0);
932+
932933
next_buf_in_block = 0;
933934
num_bufs_in_block = num_bufs;
934935
}

src/backend/tcop/backend_startup.c

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ static int
492492
ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done)
493493
{
494494
int32 len;
495-
char *buf;
495+
char *buf = NULL;
496496
ProtocolVersion proto;
497497
MemoryContext oldcontext;
498498

@@ -516,7 +516,7 @@ ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done)
516516
* scanners, which may be less benign, but it's not really our job to
517517
* notice those.)
518518
*/
519-
return STATUS_ERROR;
519+
goto fail;
520520
}
521521

522522
if (pq_getbytes(((char *) &len) + 1, 3) == EOF)
@@ -526,7 +526,7 @@ ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done)
526526
ereport(COMMERROR,
527527
(errcode(ERRCODE_PROTOCOL_VIOLATION),
528528
errmsg("incomplete startup packet")));
529-
return STATUS_ERROR;
529+
goto fail;
530530
}
531531

532532
len = pg_ntoh32(len);
@@ -538,7 +538,7 @@ ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done)
538538
ereport(COMMERROR,
539539
(errcode(ERRCODE_PROTOCOL_VIOLATION),
540540
errmsg("invalid length of startup packet")));
541-
return STATUS_ERROR;
541+
goto fail;
542542
}
543543

544544
/*
@@ -554,7 +554,7 @@ ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done)
554554
ereport(COMMERROR,
555555
(errcode(ERRCODE_PROTOCOL_VIOLATION),
556556
errmsg("incomplete startup packet")));
557-
return STATUS_ERROR;
557+
goto fail;
558558
}
559559
pq_endmsgread();
560560

@@ -568,7 +568,7 @@ ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done)
568568
{
569569
ProcessCancelRequestPacket(port, buf, len);
570570
/* Not really an error, but we don't want to proceed further */
571-
return STATUS_ERROR;
571+
goto fail;
572572
}
573573

574574
if (proto == NEGOTIATE_SSL_CODE && !ssl_done)
@@ -607,14 +607,16 @@ ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done)
607607
ereport(COMMERROR,
608608
(errcode_for_socket_access(),
609609
errmsg("failed to send SSL negotiation response: %m")));
610-
return STATUS_ERROR; /* close the connection */
610+
goto fail; /* close the connection */
611611
}
612612

613613
#ifdef USE_SSL
614614
if (SSLok == 'S' && secure_open_server(port) == -1)
615-
return STATUS_ERROR;
615+
goto fail;
616616
#endif
617617

618+
pfree(buf);
619+
618620
/*
619621
* At this point we should have no data already buffered. If we do,
620622
* it was received before we performed the SSL handshake, so it wasn't
@@ -661,14 +663,16 @@ ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done)
661663
ereport(COMMERROR,
662664
(errcode_for_socket_access(),
663665
errmsg("failed to send GSSAPI negotiation response: %m")));
664-
return STATUS_ERROR; /* close the connection */
666+
goto fail; /* close the connection */
665667
}
666668

667669
#ifdef ENABLE_GSS
668670
if (GSSok == 'G' && secure_open_gssapi(port) == -1)
669-
return STATUS_ERROR;
671+
goto fail;
670672
#endif
671673

674+
pfree(buf);
675+
672676
/*
673677
* At this point we should have no data already buffered. If we do,
674678
* it was received before we performed the GSS handshake, so it wasn't
@@ -863,7 +867,16 @@ ProcessStartupPacket(Port *port, bool ssl_done, bool gss_done)
863867
*/
864868
MemoryContextSwitchTo(oldcontext);
865869

870+
pfree(buf);
871+
866872
return STATUS_OK;
873+
874+
fail:
875+
/* be tidy, just to avoid Valgrind complaints */
876+
if (buf)
877+
pfree(buf);
878+
879+
return STATUS_ERROR;
867880
}
868881

869882
/*

0 commit comments

Comments
 (0)