Subject: Optionally using a better backtrace library?

From: Andres Freund <[email-masked]>
Date: Sun, 2 Jul 2023 11:31:56 -0700

Hi,

I like that we now have a builtin backtrace ability. Unfortunately I think the
backtraces are often not very useful, because only externally visible
functions are symbolized.

E.g.:

2023-07-02 10:54:01.756 PDT [1398494][client backend][:0][[unknown]] LOG:  will crash
2023-07-02 10:54:01.756 PDT [1398494][client backend][:0][[unknown]] BACKTRACE:
	postgres: dev assert: andres postgres [local] initializing(errbacktrace+0xbb) [0x562a44c97ca9]
	postgres: dev assert: andres postgres [local] initializing(PostgresMain+0xb6) [0x562a44ac56d4]
	postgres: dev assert: andres postgres [local] initializing(+0x806add) [0x562a449f0add]
	postgres: dev assert: andres postgres [local] initializing(+0x806369) [0x562a449f0369]
	postgres: dev assert: andres postgres [local] initializing(+0x802406) [0x562a449ec406]
	postgres: dev assert: andres postgres [local] initializing(PostmasterMain+0x1676) [0x562a449ebd17]
	postgres: dev assert: andres postgres [local] initializing(+0x6ec2e2) [0x562a448d62e2]
	/lib/x86_64-linux-gnu/libc.so.6(+0x276ca) [0x7f1e820456ca]
	/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x85) [0x7f1e82045785]
	postgres: dev assert: andres postgres [local] initializing(_start+0x21) [0x562a445ede21]

which is far from as useful as it could be.

A lot of platforms have "libbacktrace" available, e.g. as part of gcc. I think
we should consider using it, when available, to produce more useful
backtraces.

I hacked it up for ereport() to debug something, and the backtraces are
considerably better:

2023-07-02 10:52:54.863 PDT [1398207][client backend][:0][[unknown]] LOG:  will crash
2023-07-02 10:52:54.863 PDT [1398207][client backend][:0][[unknown]] BACKTRACE:
	[0x55fcd03e6143] PostgresMain: ../../../../home/andres/src/postgresql/src/backend/tcop/postgres.c:4126
	[0x55fcd031154c] BackendRun: ../../../../home/andres/src/postgresql/src/backend/postmaster/postmaster.c:4461
	[0x55fcd0310dd8] BackendStartup: ../../../../home/andres/src/postgresql/src/backend/postmaster/postmaster.c:4189
	[0x55fcd030ce75] ServerLoop: ../../../../home/andres/src/postgresql/src/backend/postmaster/postmaster.c:1779
	[0x55fcd030c786] PostmasterMain: ../../../../home/andres/src/postgresql/src/backend/postmaster/postmaster.c:1463
	[0x55fcd01f6d51] main: ../../../../home/andres/src/postgresql/src/backend/main/main.c:198
	[0x7fdd914456c9] __libc_start_call_main: ../sysdeps/nptl/libc_start_call_main.h:58
	[0x7fdd91445784] __libc_start_main_impl: ../csu/libc-start.c:360
	[0x55fccff0e890] [unknown]: [unknown]:0

The way each frame looks is my fault, not libbacktrace's...

Nice things about libbacktrace are that the generation of stack traces is
documented to be async signal safe on most platforms (with a #define to figure
that out, and a more minimal safe version always available) and that it
supports a wide range of platforms:

https://github.com/ianlancetaylor/libbacktrace
  As of October 2020, libbacktrace supports ELF, PE/COFF, Mach-O, and XCOFF
  executables with DWARF debugging information. In other words, it supports
  GNU/Linux, *BSD, macOS, Windows, and AIX. The library is written to make it
  straightforward to add support for other object file and debugging formats.

The state I currently have is very hacky, but if there's interest in
upstreaming something like this, I could clean it up.

Greetings,

Andres Freund