On Mon, Jul 03, 2023 at 11:58:25AM +0200, Alvaro Herrera wrote:
> On 2023-Jul-02, Andres Freund wrote:
> > 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.
>
> Agreed, these backtraces are pretty close to useless. Not completely,
> but I haven't found a practical way to use them for actual debugging
> of production problems.
For what it's worth, I use the attached script to convert the current
errbacktrace output to a fully-symbolized backtrace. Nonetheless, ...
> > 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
>
> Yeah, this looks much more usable.
... +1 for offering this.
#! /usr/bin/perl
# Usage: errbacktrace2line EXE_FILE <backtrace-lines
use strict;
use warnings;
my $bin = shift;
my $addr_obj;
my @addr;
sub flush_addr {
system qw(eu-addr2line --inlines --basename --functions --pretty-print
--exe), $addr_obj, @addr;
undef @addr;
}
sub conditional_flush_addr {
my($obj) = @_;
flush_addr if defined $addr_obj && $addr_obj ne $obj;
$addr_obj = $obj;
}
my $last2_fields = qr/\(([^+)]*(?:\+0x[a-f0-9]*)?)\) \[(0x[a-f0-9]*)\]/;
while (<>) {
if (/^[[:space:]]*(\/.*\.so)$last2_fields/) {
my($obj, $offset, $return_addr) = ($1, $2, $3);
conditional_flush_addr $obj;
push @addr, ($offset || $return_addr);
} elsif (/$last2_fields/) {
my($offset, $return_addr) = ($1, $2);
conditional_flush_addr $bin;
push @addr, ($offset || $return_addr);
}
}
flush_addr;