Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filter calls to libc from valgrind's callgrind output

I'm trying to generate a call graph for a server for documentation purposes. Not for any kind of profiling.

I generated the output with:

sudo valgrind --tool=callgrind --dump-instr=yes /opt/ats-trunk/bin/traffic_server

and converted with: http://code.google.com/p/jrfonseca/wiki/Gprof2Dot to a .dot file, but this contains way too much info to be useful as documentation.

I would like to filter out the calls to libraries such as libc, libstdc++, libtcl, libhwloc and whatnot.

n.b.: I've been trying to just grep out the useless libraries, but that seems cumbersome and incomplete at best.

Thank you very much for your answers in advance.

like image 783
Igor Galić Avatar asked Dec 27 '22 12:12

Igor Galić


1 Answers

After the deafening silence here, and actually everywhere I asked, I turned to the valgrind-users@ ML. Here's the thread:

http://sourceforge.net/mailarchive/forum.php?thread_name=e847e3a9-0d10-4c5e-929f-51258ecf9dfc%40iris&forum_name=valgrind-users

Josef's reply was extremely helpful, and with a lot of patience from #perl I have put together a script helps me filter out libraries I don't need in my call-graph.

The script relies on telling callgrind to be extra verbose:

valgrind --tool=callgrind --dump-instr=yes --compress-pos=no \
  --compress-strings=no /opt/ats-trunk/bin/traffic_server

This way it will produce strings instead of reference numbers, making it much easier parsable:

#!/usr/bin/perl

use Modern::Perl;
require File::Temp;

my $cob = qr{^cob=/(?:usr/)?lib};
my $ob = qr{^ob=/(?:usr/)?lib/};
my $calls = qr{^calls=};

open (my $fh, '<', $ARGV[0]) or die $!;
my $tmp = File::Temp->new(UNLINK => 1);

## Skip all external libraries, as defined by $ob
while (readline $fh) {
    if (/$ob/ ) {
        # skip the entire ob= section we don't need.
        0 while defined($_ = readline $fh) && !/^ob=/;

        # put the last line back, we read too far
        seek($fh, -length($_), 1);
    } else {
        print $tmp $_;
    }
}
close ($fh);

## Skip all calls to external libraries, as defined by $cob
my $tmpname = $tmp->filename;
open ($tmp, '<', $tmpname) or die $!;
while (readline $tmp) {
    if (/$cob/) {

        # skip until we find a line starting with calls=
        # skip that line too
        0 while defined($_ = readline $tmp) && !/$calls/;

        # then we skip until we either hit ^word= or an empty line.
        # In other words: skip all lines that start with 0x
        0 while defined($_ = readline $tmp) && /^0x/;

        # put the last line back, we read too far
        seek($tmp, -length($_), 1);
    }  else {
       print;
    }
}
like image 110
Igor Galić Avatar answered May 13 '23 03:05

Igor Galić