From 7f9208ccb95df113873e7c23257e1215b1be6919 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Mon, 12 Feb 2024 14:02:40 +0100 Subject: [PATCH v2 2/2] Support wildcard in backtrace_functions to handle all errors Sometimes during debugging it can be useful to get backtraces for all errors, regardless of where they were fired. This is possible already by specifying a list of functions, but it can quickly become unwieldy when the exact callsite isn't known in advance. This adds support for specifying a '*' wildcard which will emit backtraces for *all* errors regardless (but only elevel >= ERROR). Author: Jelte Fennema-Nio Discussion: https://postgr.es/m/CAGECzQTpdujCEt2SH4DBwRLoDq4HJArGDaxJSsWX0G=tNnzaVA@mail.gmail.com --- doc/src/sgml/config.sgml | 5 +++++ src/backend/utils/error/elog.c | 14 ++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index f865d0b87e..21cc96c327 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -11075,6 +11075,11 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir' be used to debug specific areas of the source code. + + A single * character is interpreted as a wildcard and + will cause all errors in the log to contain backtraces. + + Backtrace support is not available on all platforms, and the quality of the backtraces depends on compilation options. diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 700fbde6db..6776972309 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -182,7 +182,7 @@ static void set_stack_entry_domain(ErrorData *edata, const char *domain); static void set_stack_entry_location(ErrorData *edata, const char *filename, int lineno, const char *funcname); -static bool matches_backtrace_functions(const char *funcname); +static bool matches_backtrace_functions(const char *funcname, int elevel); static pg_noinline void set_backtrace(ErrorData *edata, int num_skip); static void set_errdata_field(MemoryContextData *cxt, char **ptr, const char *str); static void FreeErrorDataContents(ErrorData *edata); @@ -500,7 +500,7 @@ errfinish(const char *filename, int lineno, const char *funcname) if (!edata->backtrace && ((edata->funcname && backtrace_functions && - matches_backtrace_functions(edata->funcname)) || + matches_backtrace_functions(edata->funcname, edata->elevel)) || (edata->sqlerrcode == ERRCODE_INTERNAL_ERROR && backtrace_on_internal_error))) set_backtrace(edata, 2); @@ -829,7 +829,7 @@ set_stack_entry_location(ErrorData *edata, * See check_backtrace_functions. */ static bool -matches_backtrace_functions(const char *funcname) +matches_backtrace_functions(const char *funcname, int elevel) { const char *p; @@ -842,6 +842,8 @@ matches_backtrace_functions(const char *funcname) if (*p == '\0') /* end of backtrace_function_list */ break; + if (strcmp("*", p) == 0 && elevel >= ERROR) + return true; if (strcmp(funcname, p) == 0) return true; p += strlen(p) + 1; @@ -2134,14 +2136,14 @@ check_backtrace_functions(char **newval, void **extra, GucSource source) int j; /* - * Allow characters that can be C identifiers and commas as separators, as - * well as some whitespace for readability. + * Allow characters that can be C identifiers, commas as separators, the + * wildcard symbol, as well as some whitespace for readability. */ validlen = strspn(*newval, "0123456789_" "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - ", \n\t"); + ",* \n\t"); if (validlen != newvallen) { GUC_check_errdetail("Invalid character"); -- 2.32.1 (Apple Git-133)