Filter calls to libc from valgrind's callgrind output

前端 未结 1 895
孤城傲影
孤城傲影 2021-02-10 09:09

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

I generated the output wit

1条回答
  •  南笙
    南笙 (楼主)
    2021-02-10 09:33

    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;
        }
    }
    

    0 讨论(0)
提交回复
热议问题