Re: Add errdetail() with PID and UID about source of termination signal

Jakub Wartak <jakub.wartak@enterprisedb.com>

From: Jakub Wartak <jakub.wartak@enterprisedb.com>
To: Chao Li <li.evan.chao@gmail.com>
Cc: Andrew Dunstan <andrew@dunslane.net>, Jim Jones <jim.jones@uni-muenster.de>, PostgreSQL Hackers <pgsql-hackers@lists.postgresql.org>
Date: 2026-02-25T10:45:12Z
Lists: pgsql-hackers

Attachments

On Wed, Feb 25, 2026 at 10:15 AM Chao Li <li.evan.chao@gmail.com> wrote:

Hi Chao, thanks for review.

> A few comments for v3:
>
> 1 - syncrep.c
[..]
> +                                               proc_die_sender_pid == 0 ? 0 :
> +                                                       errdetail("Signal sent by PID %lld, UID %lld.",
> +                                                               (long long)proc_die_sender_pid, (long long)proc_die_sender_uid)
> +                                               ));
> ```
>
> Here errdetail is used twice. I guess the second conditional one should be errhint.
>
> 2 - syncrep.c
[..]
> Same as comment 1.

You are right, apparently I copy/pasted code from src/backend/tcop/postgres.c
way too fast... fixed.

> 3
> ```
> +volatile uint32 proc_die_sender_pid = 0;
> +volatile uint32 proc_die_sender_uid = 0;
> ```
>
> These two globals are only written in the signal handler, I think they should be sig_atomic_t to ensure atomic writes.

Well the problem that sig_atomic_t is int and we need at least uint32 and
I couldn't find better way. I think that 4 bytes writes will be mostly
always atomic (for 64-bits it would depend on
PG_HAVE_8BYTE_SINGLE_COPY_ATOMICITY)

Yet I moved those little below, so it's more aligned to the other uses.

> 4
> ```
> -                                        errmsg("terminating walreceiver process due to administrator command")));
> +                                        errmsg("terminating walreceiver process due to administrator command"),
> +                                        proc_die_sender_pid == 0 ? 0 :
> +                                               errdetail("Signal sent by PID %lld, UID %lld.",
> +                                                       (long long)proc_die_sender_pid, (long long)proc_die_sender_uid)
> +                                       ));
> ```
>
> Why do we need to format pid and uid in “long long” format? I searched over the source tree, the current postmaster.c just formats pid as int (%d):
> ```
>         /* in parent, successful fork */
>         ereport(DEBUG2,
>                         (errmsg_internal("forked new %s, pid=%d socket=%d",
>                                                          GetBackendTypeDesc(bn->bkend_type),
>                                                          (int) pid, (int) client_sock->sock)));
> ```

Yes, I think I was kind of lost when thinking about it (v1 had sig_atomic_t,
later had pid_t, I read somewhere about 64-bit pids, and so on) vs
platform-agnostic hell of putting that into printf). Possible I was
overthinking it
and I have reverted it to just using %d with that uint32. BTW I've also found:
   elog(DEBUG3, "kill(%ld,%d) failed: %m", (long) pid, signal);

v4 attached. Thanks again for the review.

-J.

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Only show signal-sender PID/UID detail in server log

  2. Make psql DETAIL line test unconditionally optional.

  3. Rework signal handler infrastructure to pass sender info as argument.

  4. Add errdetail() with PID and UID about source of termination signal.