You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdesdk/kcachegrind/converters/op2calltree

239 lines
5.2 KiB

#!/usr/bin/perl
#
# Copyright (c) 2004
# Author: Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
#
# op2calltree is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
#
# Converter from OProfile's output of "opreport -gdf" (v 0.8)
# into callgrind format.
#
# Generate a OProfile report with opreport and flags -gdf
# and pipe this as standard input into this script.
# This will generate separate cachegrind files for every application.
#
# parse symbol line. example (with 1 event type, $has_image==0):
# 308 0.1491 /path/source.c:6 /path/app main
sub parseSymSpec {
$e = 0;
while($e < $eventCount) {
($line) = ($line =~ /\d+\s+\S+\s+(.*)/);
$e++;
}
if ($line =~ s/^\(no location information\)\s+//) {
$file = "???";
$linenr = 0;
}
else {
($file,$linenr) = ($line =~ s/(\S+?):(\d+)\s+//);
}
if ($has_image) {
if ($line =~ s/^(\S+)\s+//) { $img = $1; }
}
if ($has_app) {
if ($line =~ s/^(\S+)\s+//) { $app = $1; }
if (!$has_image) { $img = $app; }
}
$sym = $line;
$app =~ s/^.*\///;
if ($sym eq "(no symbols)") { $sym = "???"; }
$file{$sym} = $file;
$linenr{$sym} = $linenr;
$app{$sym} = $app;
$img{$app,$sym} = $img;
$syms{$app}++;
if ($app ne $oldApp) {
$oldApp = $app;
print "\n\nApp $app\n";
}
print " Symbol $sym (Image $img)\n";
}
$eventCount = 0;
$descCount = 0;
$lnr = 0;
$has_image = 0;
$has_app = 0;
$app = "unnamed";
$img = "???";
# first loop till first symbol specification
while(<>) {
$lnr++;
chomp;
if (/^CPU:/) {
$desc[$descCount++] = $_;
next;
}
if (/^Counted\s*(\S+)/) {
$desc[$descCount++] = $_;
$eventCount++;
$events[$eventCount] = $1;
next;
}
if (/^(Profiling through timer.*)/) {
$desc[$descCount++] = $_;
$eventCount++;
$events[$eventCount] = "Timer";
next;
}
if (/^vma/) {
# title row: adapt to separation options of OProfile
if (/image/) { $has_image = 1; }
if (/app/) { $has_app = 1; }
next;
}
if (/^([0-9a-fA-F]+)\s*(.*)$/) {
$vmaSym = $1;
$line = $2;
last;
}
}
if ($eventCount == 0) {
die "No Events found";
}
print "Description:\n";
foreach $d (@desc) { print " $d\n"; }
print "\n";
print "Events:";
foreach $e (@events) { print " $e"; }
print "\n";
parseSymSpec;
while(<>) {
$lnr++;
if (/^([0-9a-fA-F]+)\s*(.*)$/) {
$vmaSym = $1;
$line = $2;
parseSymSpec;
next;
}
if (/^\s+([0-9a-fA-F]+)\s*(.*)$/) {
$sampleCount{$app,$sym}++;
$sc = $sampleCount{$app,$sym};
$vma{$app,$sym,$sc} = $1;
$line = $2;
$e = 1;
while($e <= $eventCount) {
($cost, $line) = ($line =~ /(\d+)\s+\S+\s+(.*)/);
$summary{$app,$e} += $cost;
$cost{"$app,$sym,$sc,$e"} = $cost;
$e++;
}
if ($line =~ /\(no location information\)/) {
$file = "???";
$linenr = 0;
}
else {
($file,$linenr) = ($line =~ /(\S+?):(\d+)/);
}
$sFile{$app,$sym,$sc} = $file;
$linenr{$app,$sym,$sc} = $linenr;
$file =~ s/^.*\///;
print " Sample $sc: $vma{$app,$sym,$sc} ($file:$linenr):";
foreach $e (1 .. $eventCount) { $c = $cost{"$app,$sym,$sc,$e"} ; print " $c"; }
print "\n";
next;
}
die "ERROR: Reading line $lnr '$_'\n";
}
foreach $app (keys %syms) {
if ($app eq "") { next; }
print "Generating dump for App '$app'...\n";
$out = "# Generated by op2cg, using OProfile with opreport -gdf\n";
$out .= "positions: instr line\n";
$out .= "events:";
foreach $e (@events) { $out .= " $e"; }
$out .= "\n";
$out .= "summary:";
foreach $e (1 .. $eventCount) { $out .= " $summary{$app,$e}"; }
$out .= "\n\n";
%fileNum = ();
$fileNum = 1;
$sf = "";
$img = "";
foreach $sym (keys %file) {
if ($sampleCount{$app,$sym} eq "") { next; }
if ($img{$app,$sym} ne $img) {
$img = $img{$app,$sym};
$out .= "ob=$img\n";
}
$file = $file{$sym};
if ($sf ne $file) {
if ($fileNum{$file} eq "") {
$fileNum{$file} = $fileNum;
$out .= "fl=($fileNum) $file\n";
$fileNum++;
}
else {
$out .= "fl=($fileNum{$file})\n";
}
$sf = $file;
}
$out .= "fn=$sym\n";
foreach $sc (1 .. $sampleCount{$app,$sym}) {
if ($sf ne $sFile{$app,$sym,$sc}) {
$sf = $sFile{$app,$sym,$sc};
if ($sf eq $file) {
$out .= "fe=($fileNum{$file})\n";
}
else {
if ($fileNum{$sf} eq "") {
$fileNum{$sf} = $fileNum;
$out .= "fi=($fileNum) $sf\n";
$fileNum++;
}
else {
$out .= "fi=($fileNum{$sf})\n";
}
}
}
$out .= "0x$vma{$app,$sym,$sc} $linenr{$app,$sym,$sc}";
foreach $e (1 .. $eventCount) { $c = $cost{"$app,$sym,$sc,$e"} ; $out .= " $c"; }
$out .= "\n";
}
}
open OUT, ">oprof.out.$app";
print OUT $out;
close OUT;
}