From: Justin Pryzby Date: Wed, 17 Nov 2021 21:49:23 -0600 Subject: [PATCH 2/4] f! --- doc/src/sgml/func.sgml | 27 +++++++++---------- src/backend/postmaster/autovacuum.c | 2 +- src/backend/storage/ipc/procsignal.c | 4 +-- src/backend/storage/ipc/signalfuncs.c | 33 +++++++++++------------ src/backend/tcop/postgres.c | 2 +- src/backend/utils/error/elog.c | 9 +++---- src/include/catalog/pg_proc.dat | 2 +- src/test/regress/expected/backtrace.out | 2 +- src/test/regress/expected/backtrace_1.out | 2 +- src/test/regress/sql/backtrace.sql | 2 +- 10 files changed, 41 insertions(+), 44 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index a88583edfd..f2a1b701e6 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -25360,14 +25360,14 @@ SELECT collation for ('foo' COLLATE "de_DE"); level LOG. It will appear in the server log based on the log configuration set (See for more information), but will not be sent to the client regardless of - . A backtrace will identify - where exactly the backend process is currently executing. This may be - useful to developers to diagnose stuck processes and other problems. + . A backtrace identifies + what function the backend process is currently executing, and how it was called. + This may be useful to developers to diagnose stuck processes and other problems. This feature is not supported for the postmaster, logger, checkpointer, - walwriter, background writer or statistics collector process. This - feature will be available if PostgreSQL was built with the ability to - capture backtrace. If not available, the function will emit a warning - and return false. + walwriter, background writer or statistics collector processes. This + feature is available if PostgreSQL was built with the ability to + capture backtraces. If the feature is not supported, the function will + emit a warning and return false. @@ -25494,9 +25494,8 @@ postgres=# select pg_log_backtrace(pg_backend_pid()); t (1 row) -The backtrace will be logged to the log file if logging is enabled, if logging -is disabled backtrace will be logged to the console where the postmaster was -started. For example: +The backtrace will be logged as specified by the logging configuration. +For example: 2021-01-27 11:33:50.247 IST [111735] LOG: current backtrace: postgres: postgresdba postgres [local] SELECT(set_backtrace+0x38) [0xae06c5] @@ -25518,9 +25517,9 @@ started. For example: /lib64/libc.so.6(__libc_start_main+0xf5) [0x7f2107bbd505] postgres: postgresdba postgres [local] SELECT() [0x4842a9] - You can get the file name and line number by using gdb/addr2line in - linux platforms, as a prerequisite users must ensure gdb/addr2line is - already installed: + You can get the file name and line number from the logged details by using gdb/addr2line in + linux platforms (users must ensure gdb/addr2line is + already installed). 1) "info line *address" from gdb on postgres executable. For example: gdb ./postgres @@ -25535,7 +25534,7 @@ addr2line -e ./postgres 0x71c25d function will emit a warning and return false, for example: WARNING: backtrace generation is not supported by this installation -HINT: You need to rebuild PostgreSQL using library containing backtrace_symbols. +HINT: You need to rebuild PostgreSQL using a library containing backtrace_symbols. pg_log_backtrace ------------------ f diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index 90111135ff..ca74937603 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -840,7 +840,7 @@ HandleAutoVacLauncherInterrupts(void) if (LogMemoryContextPending) ProcessLogMemoryContextInterrupt(); - /* Process logging backtrace */ + /* Process a request to log our backtrace */ if (LogBacktracePending) ProcessLogBacktraceInterrupt(); diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 3dac4a8f4b..e769a7f785 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -613,8 +613,8 @@ ProcessBarrierPlaceholder(void) } /* - * HandleLogBacktraceInterrupt - Handle receipt of an interrupt indicating - * logging of backtrace. + * HandleLogBacktraceInterrupt - Handle receipt of an interrupt requesting to + * log a backtrace. * * All the actual work is deferred to ProcessLogBacktraceInterrupt(), * because we cannot safely emit a log message inside the signal handler. diff --git a/src/backend/storage/ipc/signalfuncs.c b/src/backend/storage/ipc/signalfuncs.c index d042feefee..0315968aa2 100644 --- a/src/backend/storage/ipc/signalfuncs.c +++ b/src/backend/storage/ipc/signalfuncs.c @@ -303,23 +303,29 @@ pg_rotate_logfile_v2(PG_FUNCTION_ARGS) /* * pg_log_backtrace - log backtrace of backend process. * - * By default, only superusers can log backtrace. Additional roles can be + * By default, only superusers can log a backtrace. Additional roles can be * permitted with GRANT. */ Datum pg_log_backtrace(PG_FUNCTION_ARGS) { -#ifdef HAVE_BACKTRACE_SYMBOLS int pid = PG_GETARG_INT32(0); PGPROC *proc; +#ifndef HAVE_BACKTRACE_SYMBOLS + ereport(WARNING, + errmsg("backtrace generation is not supported by this installation"), + errhint("You need to rebuild PostgreSQL using a library containing backtrace_symbols.")); + PG_RETURN_BOOL(false); +#endif + /* * BackendPidGetProc returns NULL if the pid isn't valid; but by the time * we reach kill(), a process for which we get a valid proc here might have - * terminated on its own. There's no way to acquire a lock on an arbitrary - * process to prevent that. But since this mechanism is usually used to - * debug a backend running and consuming lots of CPU cycles, that it might - * end on its own first and its backtrace are not logged is not a problem. + * terminated on its own. There's no way to prevent a process from ending + * to avoid that. But since this mechanism is usually used to debug a + * backend consuming lots of CPU cycles, it's not considered a problem if + * it ends on its own without first logging its backtrace. */ proc = BackendPidGetProc(pid); if (proc == NULL) @@ -330,20 +336,13 @@ pg_log_backtrace(PG_FUNCTION_ARGS) } /* - * Send SIGUSR1 to postgres backend whose pid matches pid by - * setting PROCSIG_LOG_BACKTRACE, the backend process will log - * the backtrace once the signal is received. + * Send SIGUSR1 to postgres backend with the given pid, setting + * PROCSIG_LOG_BACKTRACE, requesting the backend to log its backtrace. */ if (!SendProcSignal(pid, PROCSIG_LOG_BACKTRACE, proc->backendId)) PG_RETURN_BOOL(true); - else - ereport(WARNING, - (errmsg("could not send signal to process %d: %m", pid))); /* return false below */ -#else - ereport(WARNING, - errmsg("backtrace generation is not supported by this installation"), - errhint("You need to rebuild PostgreSQL using library containing backtrace_symbols.")); -#endif + ereport(WARNING, + (errmsg("could not send signal to process %d: %m", pid))); PG_RETURN_BOOL(false); } diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 3a2b670d23..cb3d218449 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -3367,7 +3367,7 @@ ProcessInterrupts(void) if (LogMemoryContextPending) ProcessLogMemoryContextInterrupt(); - /* Process logging backtrace */ + /* Process a request to log our backtrace */ if (LogBacktracePending) ProcessLogBacktraceInterrupt(); } diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 6166965a39..dce0e2b155 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -948,7 +948,7 @@ errbacktrace(void) * Compute backtrace data and add it to the supplied ErrorData. num_skip * specifies how many inner frames to skip. Use this to avoid showing the * internal backtrace support functions in the backtrace. This requires that - * this and related functions are not inlined. If edata pointer is valid + * this and related functions are not inlined. If the edata pointer is valid, * backtrace information will be set in edata. */ void @@ -983,10 +983,9 @@ set_backtrace(ErrorData *edata, int num_skip) else { /* - * LOG_SERVER_ONLY is used intentionally to make sure this information - * is not sent to client based on client_min_messages. We don't want - * to mess up a different session as pg_log_backtrace will be - * sending SIGNAL to a different backend. + * LOG_SERVER_ONLY is used to make sure the backtrace is never + * sent to client. We want to avoid messing up the other client + * session. */ elog(LOG_SERVER_ONLY, "current backtrace:%s", errtrace.data); pfree(errtrace.data); diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 2537edca12..498ee4e869 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -11694,7 +11694,7 @@ prosrc => 'brin_minmax_multi_summary_send' }, # function to get the backtrace of server process -{ oid => '6105', descr => 'log backtrace of process', +{ oid => '6105', descr => 'log backtrace of server process', proname => 'pg_log_backtrace', provolatile => 'v', prorettype => 'bool', proargtypes => 'int4', prosrc => 'pg_log_backtrace' }, diff --git a/src/test/regress/expected/backtrace.out b/src/test/regress/expected/backtrace.out index 88ee383d4d..dfb044fd1d 100644 --- a/src/test/regress/expected/backtrace.out +++ b/src/test/regress/expected/backtrace.out @@ -1,7 +1,7 @@ -- -- pg_log_backtrace() -- --- Backtrace are logged and they are not returned to the function. +-- Backtraces are logged and not returned to the function. -- Furthermore, their contents can vary depending on the timing. However, -- we can at least verify that the code doesn't fail, and that the -- permissions are set properly. diff --git a/src/test/regress/expected/backtrace_1.out b/src/test/regress/expected/backtrace_1.out index 62beef8f51..f2c837965e 100644 --- a/src/test/regress/expected/backtrace_1.out +++ b/src/test/regress/expected/backtrace_1.out @@ -1,7 +1,7 @@ -- -- pg_log_backtrace() -- --- Backtrace are logged and they are not returned to the function. +-- Backtraces are logged and not returned to the function. -- Furthermore, their contents can vary depending on the timing. However, -- we can at least verify that the code doesn't fail, and that the -- permissions are set properly. diff --git a/src/test/regress/sql/backtrace.sql b/src/test/regress/sql/backtrace.sql index 2688bc7330..a8465b017f 100644 --- a/src/test/regress/sql/backtrace.sql +++ b/src/test/regress/sql/backtrace.sql @@ -1,7 +1,7 @@ -- -- pg_log_backtrace() -- --- Backtrace are logged and they are not returned to the function. +-- Backtraces are logged and not returned to the function. -- Furthermore, their contents can vary depending on the timing. However, -- we can at least verify that the code doesn't fail, and that the -- permissions are set properly. -- 2.17.0 --exKAuxcSaZxx4B14 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0003-pg_log_backtrace-support-for-logging-backtrace-of-au.patch"