-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replace the Postgres patch related to valgrind testing with the one m…
…erged to upstream (#271) See postgres/postgres@a8a0012. After PostgreSQL 16.0 is released, we will remove this patching work from this repo altogether.
- Loading branch information
1 parent
f74ae88
commit 8d9c1ff
Showing
1 changed file
with
154 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,168 @@ | ||
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c | ||
index 470b734e9e..0798dff410 100644 | ||
index 2fc49e3445..82bd080826 100644 | ||
--- a/src/backend/tcop/postgres.c | ||
+++ b/src/backend/tcop/postgres.c | ||
@@ -73,6 +73,9 @@ | ||
#include "utils/snapmgr.h" | ||
#include "utils/timeout.h" | ||
#include "utils/timestamp.h" | ||
@@ -36,6 +36,10 @@ | ||
#include "rusagestub.h" | ||
#endif | ||
|
||
+#ifdef USE_VALGRIND | ||
+#include <valgrind/valgrind.h> | ||
+#endif | ||
+ | ||
#include "access/parallel.h" | ||
#include "access/printtup.h" | ||
#include "access/xact.h" | ||
@@ -206,6 +210,36 @@ static void enable_statement_timeout(void); | ||
static void disable_statement_timeout(void); | ||
|
||
/* ---------------- | ||
* global variables | ||
@@ -986,6 +989,7 @@ exec_simple_query(const char *query_string) | ||
bool was_logged = false; | ||
bool use_implicit_block; | ||
char msec_str[32]; | ||
+ static long long unsigned vgErrorsSoFar = 0; | ||
|
||
/* | ||
* Report query to various monitoring facilities. | ||
@@ -1343,6 +1347,16 @@ exec_simple_query(const char *query_string) | ||
TRACE_POSTGRESQL_QUERY_DONE(query_string); | ||
+/* ---------------------------------------------------------------- | ||
+ * infrastructure for valgrind debugging | ||
+ * ---------------------------------------------------------------- | ||
+ */ | ||
+#ifdef USE_VALGRIND | ||
+/* This variable should be set at the top of the main loop. */ | ||
+static unsigned int old_valgrind_error_count; | ||
+ | ||
+/* | ||
+ * If Valgrind detected any errors since old_valgrind_error_count was updated, | ||
+ * report the current query as the cause. This should be called at the end | ||
+ * of message processing. | ||
+ */ | ||
+static void | ||
+valgrind_report_error_query(const char *query) | ||
+{ | ||
+ unsigned int valgrind_error_count = VALGRIND_COUNT_ERRORS; | ||
+ | ||
+ if (unlikely(valgrind_error_count != old_valgrind_error_count) && | ||
+ query != NULL) | ||
+ VALGRIND_PRINTF("Valgrind detected %u error(s) during execution of \"%s\"\n", | ||
+ valgrind_error_count - old_valgrind_error_count, | ||
+ query); | ||
+} | ||
+ | ||
+#else /* !USE_VALGRIND */ | ||
+#define valgrind_report_error_query(query) ((void) 0) | ||
+#endif /* USE_VALGRIND */ | ||
+ | ||
+ | ||
/* ---------------------------------------------------------------- | ||
* routines to obtain user input | ||
* ---------------------------------------------------------------- | ||
@@ -2052,6 +2086,8 @@ exec_bind_message(StringInfo input_message) | ||
if (save_log_statement_stats) | ||
ShowUsage("BIND MESSAGE STATISTICS"); | ||
|
||
+ valgrind_report_error_query(debug_query_string); | ||
+ | ||
debug_query_string = NULL; | ||
} | ||
|
||
@@ -2299,6 +2335,8 @@ exec_execute_message(const char *portal_name, long max_rows) | ||
if (save_log_statement_stats) | ||
ShowUsage("EXECUTE MESSAGE STATISTICS"); | ||
|
||
+ valgrind_report_error_query(debug_query_string); | ||
+ | ||
debug_query_string = NULL; | ||
} | ||
|
||
@@ -4308,6 +4346,12 @@ PostgresMain(const char *dbname, const char *username) | ||
/* Report the error to the client and/or server log */ | ||
EmitErrorReport(); | ||
|
||
+ /* | ||
+ * If Valgrind noticed something during the erroneous query, print the | ||
+ * query string, assuming we have one. | ||
+ */ | ||
+ valgrind_report_error_query(debug_query_string); | ||
+ | ||
/* | ||
* Make sure debug_query_string gets reset before we possibly clobber | ||
* the storage it points at. | ||
@@ -4392,6 +4436,13 @@ PostgresMain(const char *dbname, const char *username) | ||
*/ | ||
doing_extended_query_message = false; | ||
|
||
+ /* | ||
+ * For valgrind reporting purposes, the "current query" begins here. | ||
+ */ | ||
+#ifdef USE_VALGRIND | ||
+ if (VALGRIND_COUNT_ERRORS > vgErrorsSoFar) | ||
+ { | ||
+ VALGRIND_PRINTF("The query for which valgrind reported a " | ||
+ "memory error was: %s\n", | ||
+ query_string); | ||
+ } | ||
+ vgErrorsSoFar = VALGRIND_COUNT_ERRORS; | ||
+ old_valgrind_error_count = VALGRIND_COUNT_ERRORS; | ||
+#endif | ||
} | ||
+ | ||
/* | ||
* Release storage left over from prior query cycle, and create a new | ||
* query input buffer in the cleared MessageContext. | ||
@@ -4592,6 +4643,8 @@ PostgresMain(const char *dbname, const char *username) | ||
else | ||
exec_simple_query(query_string); | ||
|
||
+ valgrind_report_error_query(query_string); | ||
+ | ||
send_ready_for_query = true; | ||
} | ||
break; | ||
@@ -4621,6 +4674,8 @@ PostgresMain(const char *dbname, const char *username) | ||
|
||
exec_parse_message(query_string, stmt_name, | ||
paramTypes, numParams); | ||
+ | ||
+ valgrind_report_error_query(query_string); | ||
} | ||
break; | ||
|
||
@@ -4635,6 +4690,8 @@ PostgresMain(const char *dbname, const char *username) | ||
* the field extraction out-of-line | ||
*/ | ||
exec_bind_message(&input_message); | ||
+ | ||
+ /* exec_bind_message does valgrind_report_error_query */ | ||
break; | ||
|
||
case 'E': /* execute */ | ||
@@ -4652,6 +4709,8 @@ PostgresMain(const char *dbname, const char *username) | ||
pq_getmsgend(&input_message); | ||
|
||
exec_execute_message(portal_name, max_rows); | ||
+ | ||
+ /* exec_execute_message does valgrind_report_error_query */ | ||
} | ||
break; | ||
|
||
@@ -4685,6 +4744,8 @@ PostgresMain(const char *dbname, const char *username) | ||
/* commit the function-invocation transaction */ | ||
finish_xact_command(); | ||
|
||
+ valgrind_report_error_query("fastpath function call"); | ||
+ | ||
send_ready_for_query = true; | ||
break; | ||
|
||
@@ -4729,6 +4790,8 @@ PostgresMain(const char *dbname, const char *username) | ||
|
||
if (whereToSendOutput == DestRemote) | ||
pq_putemptymessage('3'); /* CloseComplete */ | ||
+ | ||
+ valgrind_report_error_query("CLOSE message"); | ||
} | ||
break; | ||
|
||
@@ -4761,6 +4824,8 @@ PostgresMain(const char *dbname, const char *username) | ||
describe_type))); | ||
break; | ||
} | ||
+ | ||
+ valgrind_report_error_query("DESCRIBE message"); | ||
} | ||
break; | ||
|
||
@@ -4773,6 +4838,7 @@ PostgresMain(const char *dbname, const char *username) | ||
case 'S': /* sync */ | ||
pq_getmsgend(&input_message); | ||
finish_xact_command(); | ||
+ valgrind_report_error_query("SYNC message"); | ||
send_ready_for_query = true; | ||
break; | ||
|
||
/* |