Skip to content

Commit 2d92bbc

Browse files
committed
Do not access fields of pstmt after calling standard_ProcessUtility()
As a comment in pg_stat_statements warns us of pstmt can have been freed on for example ROLLBACK, so we need to copy all fields. We also copy the warning from pg_stat_statements so we do not reintroduce this issue.
1 parent a1954d1 commit 2d92bbc

1 file changed

Lines changed: 14 additions & 5 deletions

File tree

src/pg_stat_monitor.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,8 +1024,9 @@ pgsm_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
10241024
!IsA(parsetree, DeallocateStmt))
10251025
{
10261026
const char *query_text;
1027-
int location;
1028-
int query_len;
1027+
int location = pstmt->stmt_location;
1028+
int query_len = pstmt->stmt_len;
1029+
int cmd_type = pstmt->commandType;
10291030
instr_time start;
10301031
instr_time duration;
10311032
uint64 rows;
@@ -1065,6 +1066,16 @@ pgsm_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
10651066
}
10661067
PG_END_TRY();
10671068

1069+
/*
1070+
* CAUTION: do not access the *pstmt data structure again below here.
1071+
* If it was a ROLLBACK or similar, that data structure may have been
1072+
* freed. We must copy everything we still need into local variables,
1073+
* which we did above.
1074+
*
1075+
* For the same reason, we can't risk restoring pstmt->queryId to its
1076+
* former value, which'd otherwise be a good idea.
1077+
*/
1078+
10681079
getrusage(RUSAGE_SELF, &rusage_end);
10691080
sys_info.utime = time_diff(rusage_end.ru_utime, rusage_start.ru_utime);
10701081
sys_info.stime = time_diff(rusage_end.ru_stime, rusage_start.ru_stime);
@@ -1087,12 +1098,10 @@ pgsm_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
10871098
memset(&bufusage, 0, sizeof(BufferUsage));
10881099
BufferUsageAccumDiff(&bufusage, &pgBufferUsage, &bufusage_start);
10891100

1090-
location = pstmt->stmt_location;
1091-
query_len = pstmt->stmt_len;
10921101
query_text = CleanQuerytext(queryString, &location, &query_len);
10931102

10941103
entry->pgsm_query_id = get_pgsm_query_id_hash(query_text, query_len);
1095-
entry->counters.info.cmd_type = pstmt->commandType;
1104+
entry->counters.info.cmd_type = cmd_type;
10961105

10971106
pgsm_add_to_list(entry, query_text, query_len);
10981107

0 commit comments

Comments
 (0)