summaryrefslogtreecommitdiffstats
path: root/kcachegrind/converters
diff options
context:
space:
mode:
Diffstat (limited to 'kcachegrind/converters')
-rw-r--r--kcachegrind/converters/Makefile.am2
-rw-r--r--kcachegrind/converters/README24
-rw-r--r--kcachegrind/converters/dprof2calltree199
-rw-r--r--kcachegrind/converters/hotshot2calltree394
-rwxr-xr-xkcachegrind/converters/memprof2calltree38
-rwxr-xr-xkcachegrind/converters/op2calltree238
-rw-r--r--kcachegrind/converters/pprof2calltree218
7 files changed, 0 insertions, 1113 deletions
diff --git a/kcachegrind/converters/Makefile.am b/kcachegrind/converters/Makefile.am
deleted file mode 100644
index 08b3696b..00000000
--- a/kcachegrind/converters/Makefile.am
+++ /dev/null
@@ -1,2 +0,0 @@
-bin_SCRIPTS = hotshot2calltree op2calltree pprof2calltree dprof2calltree \
- memprof2calltree
diff --git a/kcachegrind/converters/README b/kcachegrind/converters/README
deleted file mode 100644
index c27d3c6d..00000000
--- a/kcachegrind/converters/README
+++ /dev/null
@@ -1,24 +0,0 @@
-This directory contains some scripts to convert output of different
-profiling tools into the format which can be loaded by KCachegrind.
-See the comment at start of every script for details.
-
-In the long run, these should be replaced by import filters in
-KCachegrind directly, but I can't promise anything. Partly, this
-is because some scripts are provided as contribution from others.
-
-hotshot2calltree Converter from Python Hotshot Profiler.
-op2calltree Converter from OProfile sampling data.
-dprof2calltree Converter from PERL::DProf Profiler.
-pprof2calltree Converter from APD PHP Profiler.
-
-Thanks go to
-* George Schlossnagle <george@omniti.com> for
- dprof2calltree and pprof2calltree,
-* Jörg Beyer <job@webde-ag.de> for
- hotshot2calltree
-
-If you want to write a converter, have a look at the calltree format
-description on the web site (tdecachegrind.sf.net).
-
-Josef
-
diff --git a/kcachegrind/converters/dprof2calltree b/kcachegrind/converters/dprof2calltree
deleted file mode 100644
index f276e188..00000000
--- a/kcachegrind/converters/dprof2calltree
+++ /dev/null
@@ -1,199 +0,0 @@
-#!/usr/bin/perl
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# - Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-#
-# - Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# - All advertising materials mentioning features or use of this software
-# must display the following acknowledgement: This product includes software
-# developed by OmniTI Computer Consulting.
-#
-# - Neither name of the company nor the names of its contributors may be
-# used to endorse or promote products derived from this software without
-# specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS `AS IS'' AND ANY
-# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
-# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# Copyright (c) 2004 OmniTI Computer Consulting
-# All rights reserved
-# The following code was written by George Schlossnagle <george@omniti.com>
-# and is provided completely free and without any warranty.
-#
-
-#
-# This script is designed to convert the tmon.out output emitted
-# from Perl's Devel::DProf profiling package. To use this:
-#
-# 1) Run your perl script as
-# > perl -d:DProf yoursript.pl
-# This will create a file called tmon.out. If you want to
-# inspect it on the command line, look at the man page
-# for dprofp for details.
-#
-# 2) Run
-# > dprof2calltree -f tmon.out
-# or
-# > dprof2calltree -f tmon.out -o cachegrind.out.foo
-#
-# This creates a cachegrind-style file called cachgrind.out.tmon.out or
-# cachegrind.out.foo, respecitvely.
-#
-# 3) Run tdecachegrind cachegrind.out.foo
-#
-# 4) Enjoy!
-
-use strict;
-use Config;
-use Getopt::Std;
-use IO::File;
-
-my @callstack;
-my %function_info;
-my $tree = {};
-my $total_cost = 0;
-my %opts;
-
-getopt('f:o:', \%opts);
-
-my $infd;
-usage() unless ($opts{'f'} && ($infd = IO::File->new($opts{'f'}, "r")));
-
-my $outfd;
-my $outfile = $opts{'o'};
-unless($outfile) {
- $opts{'f'} =~ m!([^/]+)$!;
- $outfile = "cachegrind.out.$1";
-}
-$outfd = new IO::File $outfile, "w";
-usage() unless defined $outfd;
-
-while(<$infd>) {
- last if /^PART2/;
-}
-while(<$infd>) {
- chomp;
- my @args = split;
- if($args[0] eq '@') {
- # record timing event
- my $call_element = pop @callstack;
- if($call_element) {
- $call_element->{'cost'} += $args[3];
- $call_element->{'cumm_cost'} += $args[3];
- $total_cost += $args[3];
- push @callstack, $call_element;
- }
- }
- elsif($args[0] eq '&') {
- # declare function
- $function_info{$args[1]}->{'package'} = $args[2];
- if($args[2] ne 'main') {
- $function_info{$args[1]}->{'name'} = $args[2]."::".$args[3];
- } else {
- $function_info{$args[1]}->{'name'} = $args[3];
- }
- }
- elsif($args[0] eq '+') {
- # push myself onto the stack
- my $call_element = { 'specifier' => $args[1], 'cost' => 0 };
- push @callstack, $call_element;
- }
- elsif($args[0] eq '-') {
- my $called = pop @callstack;
- my $called_id = $called->{'specifier'};
- my $caller = pop @callstack;
- if (exists $tree->{$called_id}) {
- $tree->{$called_id}->{'cost'} += $called->{'cost'};
- }
- else {
- $tree->{$called_id} = $called;
- }
- if($caller) {
- $caller->{'child_calls'}++;
- my $caller_id = $caller->{'specifier'};
- if(! exists $tree->{$caller_id} ) {
- $tree->{$caller_id} = { 'specifier' => $caller_id, 'cost' => 0 };
-# $tree->{$caller_id} = $caller;
- }
- $caller->{'cumm_cost'} += $called->{'cumm_cost'};
- $tree->{$caller_id}->{'called_funcs'}->[$tree->{$caller_id}->{'call_counter'}++]->{$called_id} += $called->{'cumm_cost'};
- push @callstack, $caller;
- }
- }
- elsif($args[0] eq '*') {
- # goto &func
- # replace last caller with self
- my $call_element = pop @callstack;
- $call_element->{'specifier'} = $args[1];
- push @callstack, $call_element;
- }
- else {print STDERR "Unexpected line: $_\n";}
-}
-
-#
-# Generate output
-#
-my $output = '';
-$output .= "events: Tick\n";
-$output .= "summary: $total_cost\n";
-$output .= "cmd: your script\n\n";
-foreach my $specifier ( keys %$tree ) {
- my $caller_package = $function_info{$specifier}->{'package'} || '???';
- my $caller_name = $function_info{$specifier}->{'name'} || '???';
- my $include = find_include($caller_package);
- $output .= "ob=\n";
- $output .= sprintf "fl=%s\n", find_include($caller_package);
- $output .= sprintf "fn=%s\n", $caller_name;
- $output .= sprintf "1 %d\n", $tree->{$specifier}->{'cost'};
- if(exists $tree->{$specifier}->{'called_funcs'}) {
- foreach my $items (@{$tree->{$specifier}->{'called_funcs'}}) {
- while(my ($child_specifier, $costs) = each %$items) {
- $output .= sprintf "cfn=%s\n", $function_info{$child_specifier}->{'name'};
- $output .= sprintf "cfi=%s\n", find_include($function_info{$child_specifier}->{'package'});
- $output .= "calls=1\n";
- $output .= sprintf "1 %d\n", $costs;
- }
- }
- }
- $output .= "\n";
-}
-print STDERR "Writing tdecachegrind output to $outfile\n";
-$outfd->print($output);
-
-
-
-sub find_include {
- my $module = shift;
- $module =~ s!::!/!g;
- for (@INC) {
- if ( -f "$_/$module.pm" ) {
- return "$_/$module.pm";
- }
- if ( -f "$_/$module.so" ) {
- return "$_/$module.so";
- }
- }
- return "???";
-}
-
-sub usage() {
- print STDERR "dprof2calltree -f <tmon.out> [-o outfile]\n";
- exit -1;
-}
-
-
-# vim: set sts=2 ts=2 bs ai expandtab :
diff --git a/kcachegrind/converters/hotshot2calltree b/kcachegrind/converters/hotshot2calltree
deleted file mode 100644
index f62a46e3..00000000
--- a/kcachegrind/converters/hotshot2calltree
+++ /dev/null
@@ -1,394 +0,0 @@
-#!/usr/bin/env python
-# _*_ coding: latin1 _*_
-
-#
-# Copyright (c) 2003 by WEB.DE, Karlsruhe
-# Autor: Jörg Beyer <job@webde-ag.de>
-#
-# hotshot2cachegrind 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.
-#
-#
-# This script transforms the pstat output of the hotshot
-# python profiler into the input of tdecachegrind.
-#
-# example usage:
-# modify you python script to run this code:
-#
-# import hotshot
-# filename = "pythongrind.prof"
-# prof = hotshot.Profile(filename, lineevents=1)
-# prof.runcall(run) # assuming that "run" should be called.
-# prof.close()
-#
-# it will run the "run"-method under profiling and write
-# the results in a file, called "pythongrind.prof".
-#
-# then call this script:
-# hotshot2cachegrind -o <output> <input>
-# or here:
-# hotshot2cachegrind cachegrind.out.0 pythongrind.prof
-#
-# then call tdecachegrind:
-# tdecachegrind cachegrind.out.0
-#
-# TODO:
-# * es gibt Probleme mit rekursiven (direkt und indirekt) Aufrufen - dann
-# stimmen die Kosten nicht.
-#
-# * einige Funktionen werden mit "?" als Name angezeigt. Evtl sind
-# das nur die C/C++ extensions.
-#
-# * es fehlt noch ein Funktionsnamen Mangling, dass die Filenamen berücksichtigt,
-# zZ sind alle __init__'s und alle run's schwer unterscheidbar :-(
-#
-version = "$Revision$"
-progname = "hotshot2cachegrind"
-
-import os, sys
-from hotshot import stats,log
-import os.path
-
-file_limit=0
-
-what2text = {
- log.WHAT_ADD_INFO : "ADD_INFO",
- log.WHAT_DEFINE_FUNC : "DEFINE_FUNC",
- log.WHAT_DEFINE_FILE : "DEFINE_FILE",
- log.WHAT_LINENO : "LINENO",
- log.WHAT_EXIT : "EXIT",
- log.WHAT_ENTER : "ENTER"}
-
-# a pseudo caller on the caller stack. This represents
-# the Python interpreter that executes the given python
-# code.
-root_caller = ("PythonInterpreter",0,"execute")
-
-class CallStack:
- """A tiny Stack implementation, based on python lists"""
- def __init__(self):
- self.stack = []
- self.recursion_counter = {}
- def push(self, elem):
- """put something on the stack"""
- self.stack.append(elem)
- rc = self.recursion_counter.get(elem, 0)
- self.recursion_counter[elem] = rc + 1
-
- def pop(self):
- """get the head element of the stack and remove it from teh stack"""
- elem = self.stack[-1:][0]
- rc = self.recursion_counter.get(elem) - 1
- if rc>0:
- self.recursion_counter[elem] = rc
- else:
- del self.recursion_counter[elem]
- return self.stack.pop()
-
- def top(self):
- """get the head element of the stack, stack is unchanged."""
- return self.stack[-1:][0]
- def handleLineCost(self, tdelta):
- p, c = self.stack.pop()
- self.stack.append( (p,c + tdelta) )
- def size(self):
- """ return how many elements the stack has"""
- return len(self.stack)
-
- def __str__(self):
- return "[stack: %s]" % self.stack
-
- def recursion(self, pos):
- return self.recursion_counter.get(pos, 0)
- #return self.recursion_dict.has_key((entry[0][0], entry[0][2]))
-
-def return_from_call(caller_stack, call_dict, cost_now):
- """return from a function call
- remove the function from the caller stack,
- add the costs to the calling function.
- """
- called, cost_at_enter = caller_stack.pop()
- caller, caller_cost = caller_stack.top()
-
- #print "return_from_call: %s ruft %s" % (caller, called,)
-
- per_file_dict = call_dict.get(called[0], {})
- per_caller_dict = per_file_dict.get(called[2], {})
- cost_so_far, call_counter = per_caller_dict.get(caller, (0, 0))
-
- if caller_stack.recursion(called):
- per_caller_dict[caller] = (cost_so_far, call_counter + 1)
- else:
- per_caller_dict[caller] = (cost_so_far + cost_now - cost_at_enter, call_counter + 1)
-
- per_file_dict[called[2]] = per_caller_dict
- call_dict[called[0]] = per_file_dict
-
-
-def updateStatus(filecount):
- sys.stdout.write("reading File #%d \r" % filecount)
- sys.stdout.flush()
-def convertProfFiles(output, inputfilenames):
- """convert all the given input files into one tdecachegrind
- input file.
- """
- call_dict = {}
- cost_per_pos = {}
- cost_per_function = {}
- caller_stack = CallStack()
- caller_stack.push((root_caller, 0))
-
- total_cost = 0
- filecount = 1
- number_of_files = len(inputfilenames)
- for inputfilename in inputfilenames:
- updateStatus(filecount)
- cost, filecount = convertHandleFilename(inputfilename, caller_stack, call_dict, cost_per_pos, cost_per_function, filecount)
- total_cost += cost
- if (file_limit > 0) and (filecount > file_limit):
- break
-
- print
- print "total_cost: % d Ticks",total_cost
- dumpResults(output, call_dict, total_cost, cost_per_pos, cost_per_function)
-
-def convertHandleFilename(inputfilename, caller_stack, call_dict, cost_per_pos, cost_per_function, filecount):
- updateStatus(filecount)
- if not ((file_limit > 0) and (filecount > file_limit)):
- if os.path.isdir(inputfilename):
- cost, filecount = convertProfDir(inputfilename, caller_stack, call_dict, cost_per_pos, cost_per_function, filecount)
- elif os.path.isfile(inputfilename):
- cost = convertProfFile(inputfilename, caller_stack, call_dict, cost_per_pos, cost_per_function)
- filecount += 1
- else:
- sys.stderr.write("warn: ignoring '%s', is no file and no directory\n" % inputfilename)
- cost = 0
- return (cost, filecount)
-
-def convertProfDir(start, caller_stack, call_dict, cost_per_pos, cost_per_function, filecount):
- cost = 0
- filenames = os.listdir(start)
- for f in filenames:
- if (file_limit > 0) and (filecount > file_limit):
- break
- full = os.path.join(start, f)
- c, filecount = convertHandleFilename(full, caller_stack, call_dict, cost_per_pos, cost_per_function, filecount)
- cost += c;
- return (cost, filecount)
-
-def handleCostPerPos(cost_per_pos, pos, current_cost):
- """
- the cost per source position are managed in a dict in a dict.
-
- the cost are handled per file and there per function.
- so, the per-file-dict contains some per-function-dicts
- which sum up the cost per line (in this function and in
- this file).
- """
- filename = pos[0]
- lineno = pos[1]
- funcname = pos[2]
- file_dict = cost_per_pos.get(filename, {})
- func_dict = file_dict.get(funcname, {})
- func_dict.setdefault(lineno, 0)
- func_dict[lineno] += current_cost
- file_dict[funcname] = func_dict
- cost_per_pos[filename] = file_dict
-
-def convertProfFile(inputfilename, caller_stack, call_dict, cost_per_pos, cost_per_function):
- """convert a single input file into one tdecachegrind
- data.
-
- this is the most expensive function in this python source :-)
- """
-
- total_cost = 0
- try:
- logreader = log.LogReader(inputfilename)
- current_cost = 0
- hc = handleCostPerPos # shortcut
- for item in logreader:
- what, pos ,tdelta = item
- (file, lineno, func) = pos
- #line = "%s %s %d %s %d" % (what2text[what], file, lineno, func, tdelta)
- #print line
- # most common cases first
- if what == log.WHAT_LINENO:
- # add the current cost to the current function
- hc(cost_per_pos, pos, tdelta)
- total_cost += tdelta
- elif what == log.WHAT_ENTER:
- caller_stack.push((pos, total_cost))
- hc(cost_per_pos, pos, tdelta)
- total_cost += tdelta
- elif what == log.WHAT_EXIT:
- hc(cost_per_pos, pos, tdelta)
- total_cost += tdelta
- return_from_call(caller_stack, call_dict, total_cost)
- else:
- assert 0, "duh: %d" % what
-
-
- # I have no idea, why sometimes the stack is not empty - we
- # have to rewind the stack to get 100% for the root_caller
- while caller_stack.size() > 1:
- return_from_call(caller_stack, call_dict, total_cost)
-
- except IOError:
- print "could not open inputfile '%s', ignore this." % inputfilename
- except EOFError, m:
- print "EOF: %s" % (m,)
- return total_cost
-
-def pretty_name(file, function):
- #pfile = os.path.splitext(os.path.basename(file)) [0]
- #return "%s_[%s]" % (function, file)
- return "%s" % function
- #return "%s::%s" % (file, function)
- #return "%s_%s" % (pfile, function)
-
-class TagWriter:
- def __init__(self, output):
- self.output = output
- self.last_values = {}
-
- def clearTag(self, tag):
- if self.last_values.has_key(tag):
- del self.last_values[ tag ]
- def clear(self):
- self.last_values = {}
-
- def write(self, tag, value):
- self.output.write("%s=%s\n" % (tag, value))
- #if (not self.last_values.has_key(tag)) or self.last_values[tag] != value:
- # self.last_values[ tag ] = value
- # self.output.write("%s=%s\n" % (tag, value))
-
-def dumpResults(output, call_dict, total_cost, cost_per_pos, cost_per_function):
- """write the collected results in the format tdecachegrind
- could read.
- """
- # the intro
- output.write("events: Tick\n")
- output.write("summary: %d\n" % total_cost)
- output.write("cmd: your python script\n")
- output.write("\n")
- tagwriter = TagWriter(output)
-
- # now the costs per line
- for file in cost_per_pos.keys():
- func_dict = cost_per_pos[file]
- for func in func_dict.keys():
- line_dict = func_dict[func]
- tagwriter.write("ob", file)
- tagwriter.write("fn", func)# pretty_name(file, func)) ; output.write("# ^--- 2\n")
- tagwriter.write("fl", file)
- for line in line_dict:
- output.write("%d %d\n" %( line, line_dict[line] ))
-
- output.write("\n\n")
- # now the function calls. For each caller all the called
- # functions and their costs are written.
- for file in call_dict.keys():
- per_file_dict = call_dict[file]
- #print "file %s -> %s" % (file, per_file_dict)
- for called_x in per_file_dict.keys():
- #print "called_x:",called_x
- per_caller_dict = per_file_dict[called_x]
- #print "called_x %s wird gerufen von: %s" % (called_x, per_caller_dict)
- for caller_x in per_caller_dict.keys():
- tagwriter.write("ob", caller_x[0])
- tagwriter.write("fn", caller_x[2])# pretty_name(caller_x[2], caller_x[0])) ; output.write("# ^--- 1\n")
- tagwriter.write("fl", caller_x[0])
- tagwriter.write("cob", file)
- tagwriter.write("cfn", called_x) #pretty_name(file, called_x))
- tagwriter.write("cfl", file)
- cost, count = per_caller_dict[caller_x]
- #print "called_x:",called_x
- output.write("calls=%d\n%d %d\n" % (count, caller_x[1], cost))
- tagwriter.clear()
- #tagwriter.clearTag("cob")
- # is it a bug in tdecachegrind, that the "cob=xxx" line has
- # to be rewritten after a calls entry with costline ?
- #assert cost <= total_cost, "caller_x: %s, per_caller_dict: %s " % (caller_x, per_caller_dict, )
- #output.write("calls=%d\n%d %d\n" % (count, caller_x[1], cost))
- output.write("\n")
-
-def run_without_optparse():
- """parse the options without optparse, use sys.argv"""
- if len(sys.argv) < 4 or sys.argv[1] != "-o" :
- print "usage: hotshot2cachegrind -o outputfile in1 [in2 [in3 [...]]]"
- return
- outputfilename = sys.argv[2]
- try:
- output = file(outputfilename, "w")
- args = sys.argv[3:]
- convertProfFiles(output, args)
- output.close()
- except IOError:
- print "could not open '%s' for writing." % outputfilename
-
-def run_with_optparse():
- """parse the options with optparse"""
-
- global file_limit
-
- versiontext = "%s version: %s" % ( progname, version.split()[1], )
- parser = OptionParser(version=versiontext)
- parser.add_option("-o", "--output",
- action="store", type="string", dest="outputfilename",
- help="write output into FILE")
- parser.add_option("--file-limit",
- action="store", dest="file_limit", default=0,
- help="stop after given number of input files")
- output = sys.stdout
- close_output = 0
- (options, args) = parser.parse_args()
- file_limit = int(options.file_limit)
- try:
- if options.outputfilename and options.outputfilename != "-":
- output = file(options.outputfilename, "w")
- close_output = 1
- except IOError:
- print "could not open '%s' for writing." % options.outputfilename
- if output:
- convertProfFiles(output, args)
- if close_output:
- output.close()
-
-
-def profile_myself():
- import hotshot
- filename = "self.prof"
- if not os.path.exists(filename):
- prof = hotshot.Profile(filename, lineevents=1)
- prof.runcall(run)
- prof.close()
- else:
- print "not profiling myself, since '%s' exists, running normal" % filename
- run()
-
-# check if optparse is available.
-try:
- from optparse import OptionParser
- run = run_with_optparse
-except ImportError:
- run = run_without_optparse
-
-if __name__ == "__main__":
- try:
- run()
- #profile_myself()
- except KeyboardInterrupt:
- sys.exit(1)
diff --git a/kcachegrind/converters/memprof2calltree b/kcachegrind/converters/memprof2calltree
deleted file mode 100755
index e82d6e85..00000000
--- a/kcachegrind/converters/memprof2calltree
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/perl
-#
-# Convert the memory profiles of memprof to calltree format,
-# loadable with KCachegrind
-#
-# (C) 2004, Josef Weidendorfer
-
-print "events: Allocated\n";
-
-while(<>) {
- if (/^(\S.*)$/) {
- $next = 0;
- print "\nfn=$1\n";
- next;
- }
- if (/^ children:/) {
- $next = 1; #children
- next;
- }
- if (/^ inherited:/) {
- $next = 2; #inherited
- next;
- }
- if (/^ total:/) {
- # ignore, is calculated
- next;
- }
- if (/^ self:\s*(\d+)/) {
- if ($1 ne "0") {
- print "0 $1\n";
- }
- next;
- }
- if (/^\s+(\S.*?):\s*(\d+)$/) {
- if ($next < 2) { next; }
- print "cfn=$1\ncalls=0 0\n0 $2\n";
- }
-}
diff --git a/kcachegrind/converters/op2calltree b/kcachegrind/converters/op2calltree
deleted file mode 100755
index ca121a2a..00000000
--- a/kcachegrind/converters/op2calltree
+++ /dev/null
@@ -1,238 +0,0 @@
-#!/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;
-}
diff --git a/kcachegrind/converters/pprof2calltree b/kcachegrind/converters/pprof2calltree
deleted file mode 100644
index 0e70e1c2..00000000
--- a/kcachegrind/converters/pprof2calltree
+++ /dev/null
@@ -1,218 +0,0 @@
-#!/usr/bin/env php
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# - Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-#
-# - Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-#
-# - All advertising materials mentioning features or use of this software
-# must display the following acknowledgement: This product includes software
-# developed by OmniTI Computer Consulting.
-#
-# - Neither name of the company nor the names of its contributors may be
-# used to endorse or promote products derived from this software without
-# specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS `AS IS'' AND ANY
-# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-# DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
-# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# Copyright (c) 2004 OmniTI Computer Consulting
-# All rights reserved
-# The following code was written by George Schlossnagle <george@omniti.com>
-# and is provided completely free and without any warranty.
-#
-# This script is designed to convert the pprof output from
-# APD (http://pecl.php.net/apd/) to one readable by tdecachegrind. To use
-# this script:
-#
-# 1) Install APD.
-# 2) Profile your script with APD accordingto the directions in it's
-# README file.
-# 3) Take the pprof trace file for your script (pprof.XXXXX.Y) and run it
-# through this script as follows:
-# > pprof2calltree -f pprof.12345.1
-# This creates a new file cachegrind.out.12345.1
-# 4) View your trace with pprof2calltree cachegrind.out.12345.1
-
-<?php
-
-require "Console/Getopt.php";
-
-$con = new Console_Getopt;
-$args = $con->readPHPArgv();
-array_shift($args);
-$shortoptions = 'f:';
-$retval = $con->getopt( $args, $shortoptions);
-if(is_object($retval)) {
- usage();
-}
-foreach ($retval[0] as $kv_array) {
- $opt[$kv_array[0]] = $kv_array[1];
-}
-if(!$opt['f']) {
- usage();
-}
-if(!file_exists($opt['f'])) {
- print "Trace file ${opt['f']} does not exist\n";
- exit;
-}
-$IN = fopen($opt['f'], "r");
-if(!$IN) {
- print "Trace file ${opt['f']} could not be opened\n";
- exit;
-}
-
-$path_parts = pathinfo($opt['f']);
-$outfile = "cachegrind.out.".$path_parts['basename'];
-$OUT = fopen($outfile, "w");
-if(!$OUT) {
- print "Destination file $outfile could not be opened.\n";
- exit;
-}
-
-while(($line = fgets($IN)) !== false) {
- $line = rtrim($line);
- if($line == "END_HEADER") {
- break;
- }
-}
-$tree = array();
-$callstack = array();
-while(($line = fgets($IN)) !== false) {
- $line = rtrim($line);
- $args = explode(" ", $line);
- if($args[0] == '!') {
- $file_lookup[$args[1]] = $args[2];
- }
- else if($args[0] == '&') {
- $function_lookup[$args[1]] = $args[2];
- $function_type[$args[1]] = ($args[3] == 2)?"USER":"INTERNAL";
- }
- else if($args[0] == '+') {
- $val = array(function_id => $args[1],
- file_id => $args[2],
- line => $args[3],
- cost => 0);
- array_push($callstack, $val);
- }
- else if($args[0] == '-') {
- // retrieve $called to discard
- $called = array_pop($callstack);
- // retrieve $caller for reference
- $caller = array_pop($callstack);
- $called_id = $called['function_id'];
-
- // Set meta data if not already set'
- if(!array_key_exists($called_id, $tree)) {
- $tree[$called_id] = $called;
- // initialize these to 0
- $tree[$called_id]['cost_per_line'] = array();
- }
- if($caller !== null) {
- $caller['child_calls']++;
- $caller_id = $caller['function_id'];
- if(!array_key_exists($caller_id, $tree)) {
- $tree[$caller_id] = $caller;
- }
- $caller['cost'] += $called['cost'];
- $tree[$caller_id]['called_funcs'][$tree[$caller_id]['call_counter']++][$called_id][$called['file_id']][$called['line']] += $called['cost'];
- array_push($callstack, $caller);
- }
- if(is_array($called['cost_per_line'])) {
- foreach($called[cost_per_line] as $file => $lines) {
- foreach($lines as $line => $cost) {
- $tree[$called_id]['cost_per_line'][$file][$line] += $cost;
- }
- }
- }
- }
- else if($args[0] == '@') {
- $called = array_pop($callstack);
- switch(count($args)) {
- // support new and old-style pprof data
- case 6:
- $file = $args[1];
- $line = $args[2];
- $real_tm = $args[5];
- break;
- case 4:
- $file = $called['file_id'];
- $line = $called['line'];
- $real_tm = $args[3];
- break;
-
- }
- $called['cost_per_line'][$file][$line] += $real_tm;
- $called['cost'] += $real_tm;
- $total_cost += $real_tm;
- array_push($callstack, $called);
- }
-}
-
-ob_start();
-print "events: Tick\n";
-print "summary: $total_cost\n";
-printf("cmd: %s\n", $file_lookup[1]);
-print "\n";
-
-foreach($tree as $caller => $data) {
- $filename = $file_lookup[$data['file_id']]?$file_lookup[$data['file_id']]:"???";
- printf("ob=%s\n", $function_type[$caller]);
- printf("fl=%s\n", $filename);
- printf("fn=%s\n", $function_lookup[$caller]);
- if(is_array($data['cost_per_line'])) {
- foreach($data['cost_per_line'] as $file => $lines) {
- foreach($lines as $line => $cost) {
- print "$line $cost\n";
- }
- }
- }
- else if ($data['cost']) {
- printf("COST %s %s\n", $items['line'], $items['cost']);
- }
- else {
- print_r($items);
- }
- if(is_array($data['called_funcs'])) {
- foreach($data['called_funcs'] as $counter => $items) {
- foreach($items as $called_id => $costs) {
- if(is_array($costs)) {
- printf("cfn=%s\n", $function_lookup[$called_id]);
- foreach($costs as $file => $lines) {
- printf("cfi=%s\ncalls=1\n", $file_lookup[$file]);
- foreach($lines as $line => $cost) {
- print "$line $cost\n";
- }
- }
- }
- }
- }
- }
- print "\n";
-}
-print "\ntotals=$total_cost\n";
-$buffer = ob_get_clean();
-print "Writing tdecachegrind compatible output to $outfile\n";
-fwrite($OUT, $buffer);
-
-function usage()
-{
- print <<<EOD
-pprof2calltree -f <tracefile>
-
-EOD;
- exit(1);
-}
-?>