CygProfiler
cyg-resolve.pl source
Project updated · 7 February 2007
#!/usr/bin/perl
#
# cyg-resolve.pl - CygProfiler resolver
#
# Michal Ludvig <michal@logix.cz>
# /devel
#
# Use this script to parse the output of the CygProfile suite.
#
use strict;
use warnings;
no warnings 'portable';
use diagnostics;
use English;
my %symtab;
my ($binfile, $textfile, $levelcorr);
$OUTPUT_AUTOFLUSH=1;
&help() if($#ARGV < 1);
$binfile=$ARGV[0];
&help() if($binfile =~ /--help/);
$textfile=($#ARGV > 0 ? $ARGV[1] : "cygprof.log");
$levelcorr=($#ARGV > 1 ? $ARGV[2] : -1);
&main();
# ==== Subs
sub help()
{
printf("CygProgile parser, Michal Ludvig <michal\@logix.cz>, 2002-2003\n");
printf("Usage: %s <bin-file> <log-file> [<correction>]\n", $0);
printf("\t<bin-file> Program that generated the logfile.\n");
printf("\t<log-file> Logfile generated by the profiled program.\n");
printf("\t<correction> Correction of the nesting level.\n");
exit;
}
sub main()
{
my($offset, $type, $function);
my($nsym, $nfunc);
$nsym=0;
$nfunc=0;
open(NM, "nm $binfile|") or die("Unable to run 'nm $binfile': $!\n");
printf("Loading symbols from $binfile ... ");
while(<NM>)
{
$nsym++;
next if(!/^([0-9A-F]+) (.) (.+)$/i);
$offset=hex($1); $type=$2; $function=$3;
next if($type !~ /[tT]/);
$nfunc++;
$symtab{$offset}=$function;
}
printf("OK\nSeen %d symbols, stored %d function offsets\n", $nsym, $nfunc);
close(NM);
open(TEXT, "$textfile")
or die("Unable to open '$textfile': $!\n");
if ($levelcorr == -1)
{
$levelcorr = 0;
while(<TEXT>)
{
if ((/^.*[+-] (-*\d+)/) && ($1 < -$levelcorr))
{ $levelcorr = -$1; }
}
printf("Level correction set to %d\n", $levelcorr);
seek(TEXT, 0, 0);
}
while(<TEXT>)
{
# Change the pattern if the output format
# of __cyg_...() functions has changed.
if(!/(.*)([+-]) (-*\d+) 0x([[:xdigit:]]+) 0x([[:xdigit:]]+)\s*(\d*)/)
{ print $_; next; }
else
{
my $prolog=$1;
my $type=$2;
my $level=$3 + $levelcorr;
my $off1=hex($4);
my $off2=hex($5);
my $pid=$6;
printf("$prolog\n") if ($prolog);
# Don't print exits
next if($type eq "-");
my $sym=(defined($symtab{$off1})?$symtab{$off1}:"???");
printf("\t%s %2d 0x%x (from 0x%x) %*s%s\n",
$type, $level, $off1, $off2,
$level+1, " ", "$sym()");
}
}
close(TEXT);
printf("done\n");
}