From a740b213d4b4d3360ad0cac696e47e5ec0eb8864 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Sat, 30 Dec 2023 11:11:26 +0100 Subject: [PATCH] Add GUC backtrace_on_internal_error When enabled (default off), this logs a backtrace anytime elog() or an equivalent ereport() for internal errors is called. This is not well covered by the existing backtrace_functions, because there are many equally-worded low-level errors in many functions. And if you find out where the error is, then you need to manually rewrite the elog() to ereport() to attach the errbacktrace(), which is annoying. Having a backtrace automatically on every elog() call could be very helpful during development for various kinds of common errors from palloc, syscache, node support, etc. Discussion: https://www.postgresql.org/message-id/flat/ba76c6bc-f03f-4285-bf16-47759cfcab9e@eisentraut.org --- doc/src/sgml/config.sgml | 27 +++++++++++++++++++++++++++ src/backend/utils/error/elog.c | 8 +++++--- src/backend/utils/misc/guc_tables.c | 11 +++++++++++ src/include/utils/guc.h | 1 + 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index b5624ca8847..f323bba018f 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -11086,6 +11086,33 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' + + backtrace_on_internal_error (boolean) + + backtrace_on_internal_error configuration parameter + + + + + If this parameter is on and an error with error code XX000 (internal + error; see also ) is raised, then a + backtrace is written to the server log together with the error + message. This can be used to debug such internal errors (which should + normally not happen in production). The default is off. + + + + Backtrace support is not available on all platforms, and the quality + of the backtraces depends on compilation options. + + + + Only superusers and users with the appropriate SET + privilege can change this setting. + + + + debug_discard_caches (integer) diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 07a45597c4b..b2967184ca2 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -498,9 +498,11 @@ errfinish(const char *filename, int lineno, const char *funcname) /* Collect backtrace, if enabled and we didn't already */ if (!edata->backtrace && - edata->funcname && - backtrace_functions && - matches_backtrace_functions(edata->funcname)) + ((edata->funcname && + backtrace_functions && + matches_backtrace_functions(edata->funcname)) || + (edata->sqlerrcode == ERRCODE_INTERNAL_ERROR && + backtrace_on_internal_error))) set_backtrace(edata, 2); /* diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index 9f59440526f..3945a92dddd 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -527,6 +527,7 @@ int log_temp_files = -1; double log_statement_sample_rate = 1.0; double log_xact_sample_rate = 0; char *backtrace_functions; +bool backtrace_on_internal_error = false; int temp_file_limit = -1; @@ -812,6 +813,16 @@ StaticAssertDecl(lengthof(config_type_names) == (PGC_ENUM + 1), struct config_bool ConfigureNamesBool[] = { + { + {"backtrace_on_internal_error", PGC_SUSET, DEVELOPER_OPTIONS, + gettext_noop("Log backtrace for any error with error code XX000 (internal error)."), + NULL, + GUC_NOT_IN_SAMPLE + }, + &backtrace_on_internal_error, + false, + NULL, NULL, NULL + }, { {"enable_seqscan", PGC_USERSET, QUERY_TUNING_METHOD, gettext_noop("Enables the planner's use of sequential-scan plans."), diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h index 49ee046cf0f..631c09c16b2 100644 --- a/src/include/utils/guc.h +++ b/src/include/utils/guc.h @@ -266,6 +266,7 @@ extern PGDLLIMPORT int log_temp_files; extern PGDLLIMPORT double log_statement_sample_rate; extern PGDLLIMPORT double log_xact_sample_rate; extern PGDLLIMPORT char *backtrace_functions; +extern PGDLLIMPORT bool backtrace_on_internal_error; extern PGDLLIMPORT int temp_file_limit; -- 2.30.2