File indexing completed on 2024-11-17 05:08:16
0001 #!/usr/bin/perl 0002 # 0003 # Copyright (c) 2004 0004 # Author: Josef Weidendorfer <Josef.Weidendorfer@gmx.de> 0005 # 0006 # op2calltree is free software; you can redistribute it and/or 0007 # modify it under the terms of the GNU General Public 0008 # License as published by the Free Software Foundation, version 2. 0009 # 0010 # This program is distributed in the hope that it will be useful, 0011 # but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 # General Public License for more details. 0014 0015 # You should have received a copy of the GNU General Public License 0016 # along with this program; see the file COPYING. If not, write to 0017 # the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 # Boston, MA 02110-1301, USA. 0019 # 0020 # 0021 # Converter from OProfile's output of "opreport -gdf" (v 0.8) 0022 # into callgrind format. 0023 # 0024 # Generate a OProfile report with opreport and flags -gdf 0025 # and pipe this as standard input into this script. 0026 # This will generate separate cachegrind files for every application. 0027 # 0028 0029 0030 # parse symbol line. example (with 1 event type, $has_image==0): 0031 # 308 0.1491 /path/source.c:6 /path/app main 0032 sub parseSymSpec { 0033 $e = 0; 0034 while($e < $eventCount) { 0035 ($line) = ($line =~ /\d+\s+\S+\s+(.*)/); 0036 $e++; 0037 } 0038 if ($line =~ s/^\(no location information\)\s+//) { 0039 $file = "???"; 0040 $linenr = 0; 0041 } 0042 else { 0043 ($file,$linenr) = ($line =~ s/(\S+?):(\d+)\s+//); 0044 } 0045 if ($has_image) { 0046 if ($line =~ s/^(\S+)\s+//) { $img = $1; } 0047 } 0048 if ($has_app) { 0049 if ($line =~ s/^(\S+)\s+//) { $app = $1; } 0050 if (!$has_image) { $img = $app; } 0051 } 0052 $sym = $line; 0053 0054 $app =~ s/^.*\///; 0055 if ($sym eq "(no symbols)") { $sym = "???"; } 0056 $file{$sym} = $file; 0057 $linenr{$sym} = $linenr; 0058 $app{$sym} = $app; 0059 $img{$app,$sym} = $img; 0060 $syms{$app}++; 0061 0062 if ($app ne $oldApp) { 0063 $oldApp = $app; 0064 print "\n\nApp $app\n"; 0065 } 0066 print " Symbol $sym (Image $img)\n"; 0067 } 0068 0069 0070 0071 $eventCount = 0; 0072 $descCount = 0; 0073 $lnr = 0; 0074 $has_image = 0; 0075 $has_app = 0; 0076 $app = "unnamed"; 0077 $img = "???"; 0078 0079 # first loop till first symbol specification 0080 while(<>) { 0081 $lnr++; 0082 chomp; 0083 if (/^CPU:/) { 0084 $desc[$descCount++] = $_; 0085 next; 0086 } 0087 if (/^Counted\s*(\S+)/) { 0088 $desc[$descCount++] = $_; 0089 $eventCount++; 0090 $events[$eventCount] = $1; 0091 next; 0092 } 0093 if (/^(Profiling through timer.*)/) { 0094 $desc[$descCount++] = $_; 0095 $eventCount++; 0096 $events[$eventCount] = "Timer"; 0097 next; 0098 } 0099 if (/^vma/) { 0100 # title row: adapt to separation options of OProfile 0101 if (/image/) { $has_image = 1; } 0102 if (/app/) { $has_app = 1; } 0103 next; 0104 } 0105 if (/^([0-9a-fA-F]+)\s*(.*)$/) { 0106 $vmaSym = $1; 0107 $line = $2; 0108 last; 0109 } 0110 } 0111 0112 if ($eventCount == 0) { 0113 die "No Events found"; 0114 } 0115 0116 print "Description:\n"; 0117 foreach $d (@desc) { print " $d\n"; } 0118 print "\n"; 0119 0120 print "Events:"; 0121 foreach $e (@events) { print " $e"; } 0122 print "\n"; 0123 0124 parseSymSpec; 0125 0126 while(<>) { 0127 $lnr++; 0128 if (/^([0-9a-fA-F]+)\s*(.*)$/) { 0129 $vmaSym = $1; 0130 $line = $2; 0131 0132 parseSymSpec; 0133 next; 0134 } 0135 if (/^\s+([0-9a-fA-F]+)\s*(.*)$/) { 0136 0137 $sampleCount{$app,$sym}++; 0138 $sc = $sampleCount{$app,$sym}; 0139 0140 $vma{$app,$sym,$sc} = $1; 0141 $line = $2; 0142 0143 $e = 1; 0144 while($e <= $eventCount) { 0145 ($cost, $line) = ($line =~ /(\d+)\s+\S+\s+(.*)/); 0146 $summary{$app,$e} += $cost; 0147 $cost{"$app,$sym,$sc,$e"} = $cost; 0148 $e++; 0149 } 0150 if ($line =~ /\(no location information\)/) { 0151 $file = "???"; 0152 $linenr = 0; 0153 } 0154 else { 0155 ($file,$linenr) = ($line =~ /(\S+?):(\d+)/); 0156 } 0157 $sFile{$app,$sym,$sc} = $file; 0158 $linenr{$app,$sym,$sc} = $linenr; 0159 0160 $file =~ s/^.*\///; 0161 print " Sample $sc: $vma{$app,$sym,$sc} ($file:$linenr):"; 0162 foreach $e (1 .. $eventCount) { $c = $cost{"$app,$sym,$sc,$e"} ; print " $c"; } 0163 print "\n"; 0164 next; 0165 } 0166 die "ERROR: Reading line $lnr '$_'\n"; 0167 } 0168 0169 foreach $app (keys %syms) { 0170 if ($app eq "") { next; } 0171 print "Generating dump for App '$app'...\n"; 0172 0173 $out = "# Generated by op2cg, using OProfile with opreport -gdf\n"; 0174 $out .= "positions: instr line\n"; 0175 0176 $out .= "events:"; 0177 foreach $e (@events) { $out .= " $e"; } 0178 $out .= "\n"; 0179 0180 $out .= "summary:"; 0181 foreach $e (1 .. $eventCount) { $out .= " $summary{$app,$e}"; } 0182 $out .= "\n\n"; 0183 0184 %fileNum = (); 0185 $fileNum = 1; 0186 $sf = ""; 0187 0188 $img = ""; 0189 0190 foreach $sym (keys %file) { 0191 if ($sampleCount{$app,$sym} eq "") { next; } 0192 0193 if ($img{$app,$sym} ne $img) { 0194 $img = $img{$app,$sym}; 0195 $out .= "ob=$img\n"; 0196 } 0197 0198 $file = $file{$sym}; 0199 if ($sf ne $file) { 0200 if ($fileNum{$file} eq "") { 0201 $fileNum{$file} = $fileNum; 0202 $out .= "fl=($fileNum) $file\n"; 0203 $fileNum++; 0204 } 0205 else { 0206 $out .= "fl=($fileNum{$file})\n"; 0207 } 0208 $sf = $file; 0209 } 0210 0211 $out .= "fn=$sym\n"; 0212 foreach $sc (1 .. $sampleCount{$app,$sym}) { 0213 if ($sf ne $sFile{$app,$sym,$sc}) { 0214 $sf = $sFile{$app,$sym,$sc}; 0215 if ($sf eq $file) { 0216 $out .= "fe=($fileNum{$file})\n"; 0217 } 0218 else { 0219 if ($fileNum{$sf} eq "") { 0220 $fileNum{$sf} = $fileNum; 0221 $out .= "fi=($fileNum) $sf\n"; 0222 $fileNum++; 0223 } 0224 else { 0225 $out .= "fi=($fileNum{$sf})\n"; 0226 } 0227 } 0228 } 0229 $out .= "0x$vma{$app,$sym,$sc} $linenr{$app,$sym,$sc}"; 0230 foreach $e (1 .. $eventCount) { $c = $cost{"$app,$sym,$sc,$e"} ; $out .= " $c"; } 0231 $out .= "\n"; 0232 } 0233 } 0234 0235 open OUT, ">oprof.out.$app"; 0236 print OUT $out; 0237 close OUT; 0238 }