Subject: Fix memory leak in postmasterMain

From: Henrik TJ <[email-masked]>
Date: Sat, 21 Feb 2026 15:27:15 +0100 (CET)

Hi

This is fairly inconsequential as memory leaks goes, but if -D is used 
when starting postgres, the memory allocated by stdrup() will never be 
freed. Found with valgrind.

Technically, this also happens with output_config_variable (-C), but since 
postmaster prints and exits with that, there isn't much point in fixing 
it.

   best regards, Henrik

From 78a88ba10f8f6aea2b4ccf831ab6775bae68603c Mon Sep 17 00:00:00 2001
From: Henrik TJ <[email-masked]>
Date: Wed, 18 Feb 2026 15:28:52 +0100
Subject: [PATCH] Fix userDoption not getting freed in postmaster

---
 src/backend/postmaster/postmaster.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 3fac46c402b..7480c28f08e 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -784,6 +784,8 @@ PostmasterMain(int argc, char *argv[])
 	 */
 	if (!SelectConfigFiles(userDoption, progname))
 		ExitPostmaster(2);
+	if (userDoption != NULL)
+		free(userDoption);
 
 	if (output_config_variable != NULL)
 	{
-- 
2.53.0

---

From: Henrik TJ <[email-masked]>
Date: Tue, 21 Apr 2026 16:56:32 +0200 (CEST)

Hi

On Sat, 21 Feb 2026, Henrik TJ wrote:

> This is fairly inconsequential as memory leaks goes, but if -D is used when 
> starting postgres, the memory allocated by stdrup() will never be freed. 
> Found with valgrind.

Rebased version of this patch attached.

To see valgrind catch the leak:

1. Compile with valgrind.
2. Run postgres with valgrind:
    valgrind --leak-check=full ./pgrun/bin/postgres -D pgdata/

The -D argument is required, as it is the argument from there that does 
not get freed. This should yield:

==444240== 8 bytes in 1 blocks are definitely lost in loss record 29 of 849
==444240==    at 0x4840B26: malloc (vg_replace_malloc.c:447)
==444240==    by 0x5114A2E: strdup (strdup.c:42)
==444240==    by 0x6B7CE0: PostmasterMain (../src/backend/postmaster/postmaster.c:656)
==444240==    by 0x602555: main (../src/backend/main/main.c:231)

   best regards, Henrik

From 493a0756082acac48cb02ea4fbbe4c8f4c34b0b7 Mon Sep 17 00:00:00 2001
From: Henrik TJ <[email-masked]>
Date: Sat, 18 Apr 2026 16:20:31 +0200
Subject: [PATCH] Fix userDoption not getting freed in postmaster

---

diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 90c7c4528e8..476e87001f1 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -789,6 +789,8 @@ PostmasterMain(int argc, char *argv[])
 	 */
 	if (!SelectConfigFiles(userDoption, progname))
 		ExitPostmaster(2);
+	if (userDoption != NULL)
+		free(userDoption);

---

From: Chao Li <[email-masked]>
Date: Wed, 22 Apr 2026 14:45:29 +0800

> On Apr 21, 2026, at 22:56, Henrik TJ <[email-masked]> wrote:
> 
> Hi
> 
>> This is fairly inconsequential as memory leaks goes, but if -D is used when starting postgres, the memory allocated by stdrup() will never be freed. Found with valgrind.
> 
> The -D argument is required, as it is the argument from there that does not get freed. This should yield:
> 
>  best regards, Henrik<v2-0001-Fix-userDoption-not-getting-freed-in-postmaster.patch>

From my experience, most of the time the postmaster is started with -D. On Linux and macOS, that path can be quite long, PATH_MAX is often 4096 on many Unix-like systems, and I am not sure about Windows. So I think this leak is worth fixing.

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/

---

From: Fujii Masao <[email-masked]>
Date: Thu, 23 Apr 2026 00:29:29 +0900

> From my experience, most of the time the postmaster is started with -D. On Linux and macOS, that path can be quite long, PATH_MAX is often 4096 on many Unix-like systems, and I am not sure about Wi…

We can also free()/pfree() userDoption in postgres.c and bootstrap.c?

Since userDoption typically uses only a small amount of memory, I'm not sure
this patch provides much practical benefit from a memory-leak perspective.
So I don't think it needs to be backpatched to the stable branches.

OTOH, if it helps keep Valgrind quiet for userDoption, I may be ok with
applying it to master.

Regards,

-- 
Fujii Masao

---

From: Andres Freund <[email-masked]>
Date: Wed, 22 Apr 2026 13:55:36 -0400

Hi,

> this patch provides much practical benefit from a memory-leak perspective.

I don't think this is a leak at all. We *never* can reach the end of the scope
in which userDoption is allocated. We abort() if the end of PostmasterMain()
is ever reached.  What is the leak here supposed to actually be?

> So I don't think it needs to be backpatched to the stable branches.

Definitely not.

> OTOH, if it helps keep Valgrind quiet for userDoption, I may be ok with

I'm doubtful it makes sense to fix it this way.

If we do it, we should actually be a bit more systematic and also free
output_config_variable.

ISTM those strdup()s should actually be pstrdup()s?  I suspect changing that
would also silence valgrind.

Greetings,

Andres Freund

---

From: Chao Li <[email-masked]>
Date: Thu, 23 Apr 2026 13:22:04 +0800

> On Apr 23, 2026, at 01:55, Andres Freund <[email-masked]> wrote:
> 
> Hi,
> 

Yes, calling it “memory leak” is too strict. Usually, memory leak implies repeatedly losing memory over time, but in this case, userDoption is no longer used after feeding to SelectConfigFiles(). So calling it “unnecessary retained memory” might be more accurate.

In theory, it occupies at most PATH_MAX bytes, but in practice it should be much less than that. So, I agree the benefit of fixing is trivial.

> would also silence valgrind.

I also had the question when I read the code. But looks like startup phase all uses malloc/strdup etc. C functions, for example SelectConfigFiles() in guc.c also uses malloc/free. I am not sure what is the standard.

Best regards,

---

From: Michael Paquier <[email-masked]>
Date: Thu, 23 Apr 2026 16:44:06 +0900

> would also silence valgrind.

I don't see immediately why it would not be OK to maintain this data
in the postmaster context.  There is no need to rush this change on
HEAD, IMO, I'd suggest to leave that as a v20 item..
--
Michael