Checks in RegisterBackgroundWorker.() - Mailing list pgsql-hackers

From Heikki Linnakangas
Subject Checks in RegisterBackgroundWorker.()
Date
Msg-id 4f95c1fc-ad3c-7974-3a8c-6faa3931804c@iki.fi
Whole thread Raw
Responses Re: Checks in RegisterBackgroundWorker.()
List pgsql-hackers
The first patch on my "Refactoring backend fork+exec code" thread [0] 
changes the allocations of BackgroundWorkerList from plain malloc() to 
MemoryContextAlloc(PostmasterContext). However, that actually caused a 
segfault in worker_spi tests in EXEC_BACKEND mode.

BackgroundWorkerList is a postmaster-private data structure and should 
not be accessed in backends. That assumption failed in 
RegisterBackgroundWorker(). When you put worker_spi in 
shared_preload_libraries, its _PG_init() function calls 
RegisterBackgroundWorker(), as expected. But in EXEC_BACKEND mode, the 
library is loaded *again* in each backend process, and each of those 
loads also call RegisterBackgroundWorker(). It's too late to correctly 
register any static background workers at that stage, but 
RegisterBackgroundWorker() still goes through the motions and adds the 
element to BackgroundWorkerList. If you change the malloc() to 
MemoryContextAlloc(PostmasterContext), it segfaults because 
PostmasterContext == NULL in a backend process.

In summary, RegisterBackgroundWorker() is doing some questionable and 
useless work, when a shared preload library is loaded to a backend 
process in EXEC_BACKEND mode.

Attached patches:

1. Tighten/clarify those checks. See also commit message for details.
2. The patch from the other thread to switch to 
MemoryContextAlloc(PostmasterContext)
3. A fix for a highly misleading comment in the same file.

Any comments?

[0] 
https://www.postgresql.org/message-id/flat/7a59b073-5b5b-151e-7ed3-8b01ff7ce9ef%40iki.fi

P.S. In addition to those, I also considered these changes but didn't 
implement them yet:

- Change RegisterBackgroundWorker() to return true/false to indicate 
whether the registration succeeded. Currently, the caller has no way of 
knowing. In many cases, I think even an ERROR and refusing to start up 
the server would be appropriate. But at least we should let the caller 
know and decide.

- Add "Assert(am_postmaster)" assertions to the functions in bgworker.c 
that are only supposed to be called in postmaster process. The functions 
have good explicit comments on that, but wouldn't hurt to also assert. 
(There is no 'am_postmaster' flag, the equivalent is actually 
(IsPostmasterEnvironment && !IsUnderPostmaster), but perhaps we should 
define a macro or flag for that)

-- 
Heikki Linnakangas
Neon (https://neon.tech)
Attachment

pgsql-hackers by date:

Previous
From: "Jonathan S. Katz"
Date:
Subject: Re: PostgreSQL 16 release announcement draft
Next
From: jian he
Date:
Subject: Re: PostgreSQL 16 release announcement draft