Add GUC backtrace_on_internal_error
authorPeter Eisentraut <[email protected]>
Sat, 30 Dec 2023 10:11:26 +0000 (11:11 +0100)
committerPeter Eisentraut <[email protected]>
Sat, 30 Dec 2023 10:43:57 +0000 (11:43 +0100)
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
src/backend/utils/error/elog.c
src/backend/utils/misc/guc_tables.c
src/include/utils/guc.h

index b5624ca884741c60d2eb395e3dea7611d57e9516..f323bba018f9f944694b3798454c97e137a744de 100644 (file)
@@ -11086,6 +11086,33 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-backtrace-on-internal-error" xreflabel="backtrace_on_internal_error">
+      <term><varname>backtrace_on_internal_error</varname> (<type>boolean</type>)
+      <indexterm>
+        <primary><varname>backtrace_on_internal_error</varname> configuration parameter</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+        If this parameter is on and an error with error code XX000 (internal
+        error; see also <xref linkend="errcodes-appendix"/>) 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.
+       </para>
+
+       <para>
+        Backtrace support is not available on all platforms, and the quality
+        of the backtraces depends on compilation options.
+       </para>
+
+       <para>
+        Only superusers and users with the appropriate <literal>SET</literal>
+        privilege can change this setting.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry id="guc-debug-discard-caches" xreflabel="debug_discard_caches">
       <term><varname>debug_discard_caches</varname> (<type>integer</type>)
       <indexterm>
index 07a45597c4bd65abf6760710e0b3035330780c47..b2967184ca2f4ab3be033d586cf191dd07174705 100644 (file)
@@ -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);
 
    /*
index 9f59440526f4b11fb818b2bd7c334e552573dedd..3945a92ddddf4a01eeea98456caf7c49b4156fb9 100644 (file)
@@ -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."),
index 49ee046cf0f3dfb9282644ed25c5b28a6478426f..631c09c16b2e117bb9d7946e6db20b44ddba7d77 100644 (file)
@@ -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;