Hi,

I noticed sporadic segfaults when selecting from pg_stat_activity on current HEAD.


The culprit is the 53be0b1add7064ca5db3cd884302dfc3268d884e commit which added more wait info into the pg_stat_get_activity(). More specifically, the following code is broken:

+                       proc = BackendPidGetProc(beentry->st_procpid);
+ wait_event_type = pgstat_get_wait_event_type(proc->wait_event_info);

This needs to check if proc is NULL. When reading the code I noticed that the new functions pg_stat_get_backend_wait_event_type() and pg_stat_get_backend_wait_event() suffer from the same problem.

Here is PoC patch which fixes the problem. I am wondering if we should raise warning in the pg_stat_get_backend_wait_event_type() and pg_stat_get_backend_wait_event() like the pg_signal_backend() does when proc is NULL instead of just returning NULL which is what this patch does though.

--
  Petr Jelinek                  http://www.2ndQuadrant.com/
  PostgreSQL Development, 24x7 Support, Training & Services
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index 64c4cc4..355e58c 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -783,13 +783,23 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
 			values[5] = CStringGetTextDatum(beentry->st_activity);
 
 			proc = BackendPidGetProc(beentry->st_procpid);
-			wait_event_type = pgstat_get_wait_event_type(proc->wait_event_info);
+			if (proc != NULL)
+			{
+				wait_event_type = pgstat_get_wait_event_type(proc->wait_event_info);
+				wait_event = pgstat_get_wait_event(proc->wait_event_info);
+
+			}
+			else
+			{
+				wait_event_type = NULL;
+				wait_event = NULL;
+			}
+
 			if (wait_event_type)
 				values[6] = CStringGetTextDatum(wait_event_type);
 			else
 				nulls[6] = true;
 
-			wait_event = pgstat_get_wait_event(proc->wait_event_info);
 			if (wait_event)
 				values[7] = CStringGetTextDatum(wait_event);
 			else
@@ -990,11 +1000,8 @@ pg_stat_get_backend_wait_event_type(PG_FUNCTION_ARGS)
 		wait_event_type = "<backend information not available>";
 	else if (!has_privs_of_role(GetUserId(), beentry->st_userid))
 		wait_event_type = "<insufficient privilege>";
-	else
-	{
-		proc = BackendPidGetProc(beentry->st_procpid);
+	else if ((proc = BackendPidGetProc(beentry->st_procpid)) != NULL)
 		wait_event_type = pgstat_get_wait_event_type(proc->wait_event_info);
-	}
 
 	if (!wait_event_type)
 		PG_RETURN_NULL();
@@ -1014,11 +1021,8 @@ pg_stat_get_backend_wait_event(PG_FUNCTION_ARGS)
 		wait_event = "<backend information not available>";
 	else if (!has_privs_of_role(GetUserId(), beentry->st_userid))
 		wait_event = "<insufficient privilege>";
-	else
-	{
-		proc = BackendPidGetProc(beentry->st_procpid);
+	else if ((proc = BackendPidGetProc(beentry->st_procpid)) != NULL)
 		wait_event = pgstat_get_wait_event(proc->wait_event_info);
-	}
 
 	if (!wait_event)
 		PG_RETURN_NULL();
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to