From 7d92b3ac59111933acaabec6a8c69269d08fd824 Mon Sep 17 00:00:00 2001 From: Diego Fronza Date: Tue, 30 Nov 2021 16:15:53 -0300 Subject: [PATCH] PG-290: Fix crash when enabling debugging log level on PostgreSQL. There were couple issues to handle, the main one was that our log hook (pgsm_emit_log_hook) was being called after the shared memory hook completed (pgss_shmem_startup) but before PostgreSQL boostraping code finished, thus triggering the following assertion during a call to LWLockAcquire(): Assert(!(proc == NULL && IsUnderPostmaster)); proc is a pointer to MyProc, a PostgreSQL's shared global variable that was not yet initalized by PostgreSQL. We must also check for a NULL pointer return in pg_get_backend_status() the pgstat_fetch_stat_local_beentry() function may return a NULL pointer during initialization, in which case we use "127.0.0.1" for the client address, and "postmaster" for application name. --- pg_stat_monitor.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/pg_stat_monitor.c b/pg_stat_monitor.c index 4042de1..ec43578 100644 --- a/pg_stat_monitor.c +++ b/pg_stat_monitor.c @@ -1123,6 +1123,9 @@ pg_get_backend_status(void) PgBackendStatus *beentry; local_beentry = pgstat_fetch_stat_local_beentry(i); + if (!local_beentry) + continue; + beentry = &local_beentry->backendStatus; if (beentry->st_procpid == MyProcPid) @@ -1135,6 +1138,8 @@ static int pg_get_application_name(char *application_name) { PgBackendStatus *beentry = pg_get_backend_status(); + if (!beentry) + return snprintf(application_name, APPLICATIONNAME_LEN, "%s", "postmaster"); snprintf(application_name, APPLICATIONNAME_LEN, "%s", beentry->st_appname); return strlen(application_name); @@ -1157,6 +1162,9 @@ pg_get_client_addr(void) char remote_host[NI_MAXHOST]; int ret; + if (!beentry) + return ntohl(inet_addr("127.0.0.1")); + memset(remote_host, 0x0, NI_MAXHOST); ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr, beentry->st_clientaddr.salen, @@ -1481,7 +1489,13 @@ pgss_store(uint64 queryid, return; Assert(query != NULL); - userid = GetUserId(); + if (kind == PGSS_ERROR) + { + int sec_ctx; + GetUserIdAndSecContext((Oid *)&userid, &sec_ctx); + } + else + userid = GetUserId(); application_name_len = pg_get_application_name(application_name); planid = plan_info ? plan_info->planid: 0; @@ -3303,6 +3317,10 @@ pgsm_emit_log_hook(ErrorData *edata) if (IsParallelWorker()) return; + /* Check if PostgreSQL has finished its own bootstraping code. */ + if (MyProc == NULL) + return; + if ((edata->elevel == ERROR || edata->elevel == WARNING || edata->elevel == INFO || edata->elevel == DEBUG1)) { uint64 queryid = 0;