Skip to content

Commit 80bb83c

Browse files
committed
feature: added new tool resolve-inlines to resolve inlined functions in the backtrace aggregation dump from sample-bt and etc.
1 parent 1994bc5 commit 80bb83c

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

README.markdown

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ Table of Contents
4040
* [ngx-lua-conn-pools](#ngx-lua-conn-pools)
4141
* [check-debug-info](#check-debug-info)
4242
* [ngx-phase-handlers](#ngx-phase-handlers)
43+
* [resolve-inlines](#resolve-inlines)
4344
* [Community](#community)
4445
* [English Mailing List](#english-mailing-list)
4546
* [Chinese Mailing List](#chinese-mailing-list)
@@ -1361,6 +1362,23 @@ Here is another example for an Nginx worker process with quite a few Nginx modul
13611362

13621363
[Back to TOC](#table-of-contents)
13631364

1365+
resolve-inlines
1366+
---------------
1367+
1368+
This tool calls the `addr2line` utility to resolve the inlined function frames generated by those `sample-*` tools like [sample-bt](#sample-bt).
1369+
1370+
It accepts two command-line arguments, the `.bt` file and the executable file.
1371+
1372+
For example,
1373+
1374+
```
1375+
resolve-inlines a.bt /path/to/nginx > new-a.bt
1376+
```
1377+
1378+
Right now, inlined functions in PIC (Position-Indenpendent Code) are not yet supported but are technically feasiable. (Patches welcome!)
1379+
1380+
[Back to TOC](#table-of-contents)
1381+
13641382
Community
13651383
=========
13661384

resolve-inlines

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/usr/bin/env perl
2+
3+
use strict;
4+
use warnings;
5+
6+
my $infile = shift;
7+
open my $in, $infile or
8+
die "Cannot open $infile for reading: $!\n";
9+
10+
my $execfile = shift;
11+
12+
my $cached_limit = 10000;
13+
my $cached_count = 0;
14+
my %cached;
15+
my $tip = 1;
16+
while (<$in>) {
17+
if (/^\t\d+$/) {
18+
$tip = 1;
19+
print;
20+
next;
21+
}
22+
if (/^ (0x[0-9a-f]+)\b/i) {
23+
my $stack = $1;
24+
my $line = $_;
25+
26+
my $frames = $cached{$stack};
27+
if (!$frames) {
28+
$frames = [];
29+
my $addr;
30+
if (!$tip) {
31+
no warnings 'portable';
32+
$addr = hex($stack);
33+
# XXX I don't know why I need to substract by 1,
34+
# but I need it to get the correct result at least with
35+
# gcc 4.8
36+
$addr = sprintf("%x", $addr - 1);
37+
38+
} else {
39+
$addr = $stack;
40+
}
41+
my $out = `addr2line -fsip -e $execfile $addr`;
42+
#warn "$addr: $out";
43+
open my $t, "<", \$out;
44+
while (<$t>) {
45+
if (/(\w+) at (\S+:\d+)/) {
46+
push @$frames, [$1, $2];
47+
#warn "$1\n";
48+
}
49+
}
50+
close $t;
51+
if (++$cached_count > $cached_limit) {
52+
# prevent the cache from growing forever...
53+
%cached = ();
54+
}
55+
$cached{$stack} = $frames;
56+
}
57+
if (@$frames > 1) {
58+
#warn "HIT";
59+
for my $fr (@$frames) {
60+
my ($func, $loc) = @$fr;
61+
print " $stack : $func+0x0/0x0 [$loc]\n";
62+
}
63+
64+
} else {
65+
print $line;
66+
}
67+
#print "@frames\n";
68+
#print "$cnt\n";
69+
70+
} else {
71+
print;
72+
}
73+
undef $tip;
74+
}
75+
76+
close $in;

0 commit comments

Comments
 (0)