Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a8a0012

Browse files
committed
When using valgrind, log the current query after an error is detected.
In USE_VALGRIND builds, add code to print the text of the current query to the valgrind log whenever the valgrind error count has increased during the query. Valgrind will already have printed its report, if the error is distinct from ones already seen, so that this works out fairly well as a way of annotating the log. Onur Tirtir and Tom Lane Discussion: https://postgr.es/m/AM9PR83MB0498531E804DC8DF8CFF0E8FE9D09@AM9PR83MB0498.EURPRD83.prod.outlook.com
1 parent b0b91ce commit a8a0012

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

src/backend/tcop/postgres.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
#include <sys/socket.h>
2828
#include <sys/time.h>
2929

30+
#ifdef USE_VALGRIND
31+
#include <valgrind/valgrind.h>
32+
#endif
33+
3034
#include "access/parallel.h"
3135
#include "access/printtup.h"
3236
#include "access/xact.h"
@@ -191,6 +195,36 @@ static void enable_statement_timeout(void);
191195
static void disable_statement_timeout(void);
192196

193197

198+
/* ----------------------------------------------------------------
199+
* infrastructure for valgrind debugging
200+
* ----------------------------------------------------------------
201+
*/
202+
#ifdef USE_VALGRIND
203+
/* This variable should be set at the top of the main loop. */
204+
static unsigned int old_valgrind_error_count;
205+
206+
/*
207+
* If Valgrind detected any errors since old_valgrind_error_count was updated,
208+
* report the current query as the cause. This should be called at the end
209+
* of message processing.
210+
*/
211+
static void
212+
valgrind_report_error_query(const char *query)
213+
{
214+
unsigned int valgrind_error_count = VALGRIND_COUNT_ERRORS;
215+
216+
if (unlikely(valgrind_error_count != old_valgrind_error_count) &&
217+
query != NULL)
218+
VALGRIND_PRINTF("Valgrind detected %u error(s) during execution of \"%s\"\n",
219+
valgrind_error_count - old_valgrind_error_count,
220+
query);
221+
}
222+
223+
#else /* !USE_VALGRIND */
224+
#define valgrind_report_error_query(query) ((void) 0)
225+
#endif /* USE_VALGRIND */
226+
227+
194228
/* ----------------------------------------------------------------
195229
* routines to obtain user input
196230
* ----------------------------------------------------------------
@@ -2041,6 +2075,8 @@ exec_bind_message(StringInfo input_message)
20412075
if (save_log_statement_stats)
20422076
ShowUsage("BIND MESSAGE STATISTICS");
20432077

2078+
valgrind_report_error_query(debug_query_string);
2079+
20442080
debug_query_string = NULL;
20452081
}
20462082

@@ -2292,6 +2328,8 @@ exec_execute_message(const char *portal_name, long max_rows)
22922328
if (save_log_statement_stats)
22932329
ShowUsage("EXECUTE MESSAGE STATISTICS");
22942330

2331+
valgrind_report_error_query(debug_query_string);
2332+
22952333
debug_query_string = NULL;
22962334
}
22972335

@@ -4287,6 +4325,12 @@ PostgresMain(const char *dbname, const char *username)
42874325
/* Report the error to the client and/or server log */
42884326
EmitErrorReport();
42894327

4328+
/*
4329+
* If Valgrind noticed something during the erroneous query, print the
4330+
* query string, assuming we have one.
4331+
*/
4332+
valgrind_report_error_query(debug_query_string);
4333+
42904334
/*
42914335
* Make sure debug_query_string gets reset before we possibly clobber
42924336
* the storage it points at.
@@ -4371,6 +4415,13 @@ PostgresMain(const char *dbname, const char *username)
43714415
*/
43724416
doing_extended_query_message = false;
43734417

4418+
/*
4419+
* For valgrind reporting purposes, the "current query" begins here.
4420+
*/
4421+
#ifdef USE_VALGRIND
4422+
old_valgrind_error_count = VALGRIND_COUNT_ERRORS;
4423+
#endif
4424+
43744425
/*
43754426
* Release storage left over from prior query cycle, and create a new
43764427
* query input buffer in the cleared MessageContext.
@@ -4571,6 +4622,8 @@ PostgresMain(const char *dbname, const char *username)
45714622
else
45724623
exec_simple_query(query_string);
45734624

4625+
valgrind_report_error_query(query_string);
4626+
45744627
send_ready_for_query = true;
45754628
}
45764629
break;
@@ -4600,6 +4653,8 @@ PostgresMain(const char *dbname, const char *username)
46004653

46014654
exec_parse_message(query_string, stmt_name,
46024655
paramTypes, numParams);
4656+
4657+
valgrind_report_error_query(query_string);
46034658
}
46044659
break;
46054660

@@ -4614,6 +4669,8 @@ PostgresMain(const char *dbname, const char *username)
46144669
* the field extraction out-of-line
46154670
*/
46164671
exec_bind_message(&input_message);
4672+
4673+
/* exec_bind_message does valgrind_report_error_query */
46174674
break;
46184675

46194676
case 'E': /* execute */
@@ -4631,6 +4688,8 @@ PostgresMain(const char *dbname, const char *username)
46314688
pq_getmsgend(&input_message);
46324689

46334690
exec_execute_message(portal_name, max_rows);
4691+
4692+
/* exec_execute_message does valgrind_report_error_query */
46344693
}
46354694
break;
46364695

@@ -4664,6 +4723,8 @@ PostgresMain(const char *dbname, const char *username)
46644723
/* commit the function-invocation transaction */
46654724
finish_xact_command();
46664725

4726+
valgrind_report_error_query("fastpath function call");
4727+
46674728
send_ready_for_query = true;
46684729
break;
46694730

@@ -4708,6 +4769,8 @@ PostgresMain(const char *dbname, const char *username)
47084769

47094770
if (whereToSendOutput == DestRemote)
47104771
pq_putemptymessage('3'); /* CloseComplete */
4772+
4773+
valgrind_report_error_query("CLOSE message");
47114774
}
47124775
break;
47134776

@@ -4740,6 +4803,8 @@ PostgresMain(const char *dbname, const char *username)
47404803
describe_type)));
47414804
break;
47424805
}
4806+
4807+
valgrind_report_error_query("DESCRIBE message");
47434808
}
47444809
break;
47454810

@@ -4752,6 +4817,7 @@ PostgresMain(const char *dbname, const char *username)
47524817
case 'S': /* sync */
47534818
pq_getmsgend(&input_message);
47544819
finish_xact_command();
4820+
valgrind_report_error_query("SYNC message");
47554821
send_ready_for_query = true;
47564822
break;
47574823

0 commit comments

Comments
 (0)