aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/config.sgml27
-rw-r--r--src/backend/utils/error/elog.c8
-rw-r--r--src/backend/utils/misc/guc_tables.c11
-rw-r--r--src/include/utils/guc.h1
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'
</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>
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;
@@ -813,6 +814,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."),
NULL,
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;