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;

Reply via email to