Hello community, here is the log from the commit of package kcachegrind for openSUSE:Factory checked in at 2014-03-18 17:17:07 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/kcachegrind (Old) and /work/SRC/openSUSE:Factory/.kcachegrind.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kcachegrind" Changes: -------- --- /work/SRC/openSUSE:Factory/kcachegrind/kcachegrind.changes 2014-02-20 07:58:45.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.kcachegrind.new/kcachegrind.changes 2014-03-18 17:17:09.000000000 +0100 @@ -1,0 +2,14 @@ +Thu Mar 13 20:52:08 UTC 2014 - [email protected] + +- Update to 4.12.90 + * KDE 4.13 Beta 2 release + * See http://www.kde.org/announcements/announce-4.13-beta2.php + +------------------------------------------------------------------- +Fri Mar 7 11:36:41 UTC 2014 - [email protected] + +- Update to 4.12.80 + * KDE 4.13 Beta 1 release + * See http://www.kde.org/announcements/announce-4.13-beta1.php + +------------------------------------------------------------------- Old: ---- kcachegrind-4.12.2.tar.xz New: ---- kcachegrind-4.12.90.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kcachegrind.spec ++++++ --- /var/tmp/diff_new_pack.jmLq3H/_old 2014-03-18 17:17:09.000000000 +0100 +++ /var/tmp/diff_new_pack.jmLq3H/_new 2014-03-18 17:17:09.000000000 +0100 @@ -22,7 +22,7 @@ License: GPL-2.0 and BSD-4-Clause and GFDL-1.2 Group: Development/Tools/Other Url: http://www.kde.org/ -Version: 4.12.2 +Version: 4.12.90 Release: 0 Source0: %{name}-%{version}.tar.xz BuildRoot: %{_tmppath}/%{name}-%{version}-build ++++++ kcachegrind-4.12.2.tar.xz -> kcachegrind-4.12.90.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcachegrind-4.12.2/converters/CMakeLists.txt new/kcachegrind-4.12.90/converters/CMakeLists.txt --- old/kcachegrind-4.12.2/converters/CMakeLists.txt 2013-10-29 16:54:37.000000000 +0100 +++ new/kcachegrind-4.12.90/converters/CMakeLists.txt 2014-03-04 07:02:07.000000000 +0100 @@ -1,2 +1,11 @@ -install( PROGRAMS hotshot2calltree op2calltree pprof2calltree dprof2calltree memprof2calltree - DESTINATION ${BIN_INSTALL_DIR} ) +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/hotshot2calltree.cmake + ${CMAKE_CURRENT_BINARY_DIR}/hotshot2calltree + ) +macro_additional_clean_files( + ${CMAKE_CURRENT_BINARY_DIR}/hotshot2calltree + ) + +install( PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/hotshot2calltree + op2calltree pprof2calltree dprof2calltree memprof2calltree + DESTINATION ${BIN_INSTALL_DIR} ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcachegrind-4.12.2/converters/hotshot2calltree new/kcachegrind-4.12.90/converters/hotshot2calltree --- old/kcachegrind-4.12.2/converters/hotshot2calltree 2013-10-29 16:54:37.000000000 +0100 +++ new/kcachegrind-4.12.90/converters/hotshot2calltree 1970-01-01 01:00:00.000000000 +0100 @@ -1,394 +0,0 @@ -#!/usr/bin/env python -# _*_ coding: latin1 _*_ - -# -# Copyright (c) 2003 by WEB.DE, Karlsruhe -# Autor: Jörg Beyer <[email protected]> -# -# 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 kcachegrind. -# -# 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 kcachegrind: -# kcachegrind 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 the 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 kcachegrind - 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 kcachegrind - 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 kcachegrind - 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 kcachegrind, 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcachegrind-4.12.2/converters/hotshot2calltree.cmake new/kcachegrind-4.12.90/converters/hotshot2calltree.cmake --- old/kcachegrind-4.12.2/converters/hotshot2calltree.cmake 1970-01-01 01:00:00.000000000 +0100 +++ new/kcachegrind-4.12.90/converters/hotshot2calltree.cmake 2014-03-04 07:02:07.000000000 +0100 @@ -0,0 +1,394 @@ +#!/usr/bin/env python +# _*_ coding: latin1 _*_ + +# +# Copyright (c) 2003 by WEB.DE, Karlsruhe +# Autor: Jörg Beyer <[email protected]> +# +# 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 kcachegrind. +# +# 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 kcachegrind: +# kcachegrind 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 = "Version ${KCACHEGRIND_VERSION}" +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 the 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 kcachegrind + 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 kcachegrind + 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 kcachegrind + 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 kcachegrind, 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcachegrind-4.12.2/libcore/costitem.cpp new/kcachegrind-4.12.90/libcore/costitem.cpp --- old/kcachegrind-4.12.2/libcore/costitem.cpp 2013-10-29 16:54:37.000000000 +0100 +++ new/kcachegrind-4.12.90/libcore/costitem.cpp 2014-03-04 07:02:07.000000000 +0100 @@ -605,6 +605,14 @@ QString ProfileCostArray::prettySubCostPerCall(EventType* t, int calls) { + if (calls == 0) { + /* For callgrind, a call count of zero means that + * a function was already active when measuring started + * (even without that possibility, we never should crash). + * To show full cost, set <calls> to 1. + */ + calls = 1; + } return SubCost(subCost(t) / calls).pretty(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcachegrind-4.12.2/libcore/coverage.cpp new/kcachegrind-4.12.90/libcore/coverage.cpp --- old/kcachegrind-4.12.2/libcore/coverage.cpp 2013-10-29 16:54:37.000000000 +0100 +++ new/kcachegrind-4.12.90/libcore/coverage.cpp 2014-03-04 07:02:07.000000000 +0100 @@ -147,7 +147,7 @@ if (call->subCost(_costType)>0) { TraceFunction* caller = call->caller(); - Coverage* c = (Coverage*) caller->assoziation(rtti()); + Coverage* c = (Coverage*) caller->association(rtti()); if (!c) { c = new Coverage(); c->setFunction(caller); @@ -258,7 +258,7 @@ if (call->subCost(_costType)>0) { TraceFunction* calling = call->called(); - Coverage* c = (Coverage*) calling->assoziation(rtti()); + Coverage* c = (Coverage*) calling->association(rtti()); if (!c) { c = new Coverage(); c->setFunction(calling); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcachegrind-4.12.2/libcore/coverage.h new/kcachegrind-4.12.90/libcore/coverage.h --- old/kcachegrind-4.12.2/libcore/coverage.h 2013-10-29 16:54:37.000000000 +0100 +++ new/kcachegrind-4.12.90/libcore/coverage.h 2014-03-04 07:02:07.000000000 +0100 @@ -33,7 +33,7 @@ * This function also holds the main routine for coverage analysis, * Coverage::coverage(), as static method. */ -class Coverage : public TraceAssoziation +class Coverage : public TraceAssociation { public: /* Direction of coverage analysis */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcachegrind-4.12.2/libcore/tracedata.cpp new/kcachegrind-4.12.90/libcore/tracedata.cpp --- old/kcachegrind-4.12.2/libcore/tracedata.cpp 2013-10-29 16:54:37.000000000 +0100 +++ new/kcachegrind-4.12.90/libcore/tracedata.cpp 2014-03-04 07:02:07.000000000 +0100 @@ -1732,59 +1732,59 @@ //--------------------------------------------------- -// TraceAssoziation +// TraceAssociation -TraceAssoziation::TraceAssoziation() +TraceAssociation::TraceAssociation() { _function = 0; _valid = false; } -TraceAssoziation::~TraceAssoziation() +TraceAssociation::~TraceAssociation() { // do not delete from TraceFunction - if (_function) _function->removeAssoziation(this); + if (_function) _function->removeAssociation(this); } -bool TraceAssoziation::isAssoziated() +bool TraceAssociation::isAssociated() { if (!_function) return false; - return _function->assoziation(rtti())==this; + return _function->association(rtti())==this; } -bool TraceAssoziation::setFunction(TraceFunction* f) +bool TraceAssociation::setFunction(TraceFunction* f) { if (_function == f) - return isAssoziated(); + return isAssociated(); if (_function) { // do not delete ourself - _function->removeAssoziation(this); + _function->removeAssociation(this); } _function = f; - if (f && f->assoziation(rtti()) == 0) { - f->addAssoziation(this); + if (f && f->association(rtti()) == 0) { + f->addAssociation(this); return true; } return false; } -void TraceAssoziation::clear(TraceData* d, int rtti) +void TraceAssociation::clear(TraceData* d, int rtti) { TraceFunctionMap::Iterator it; for ( it = d->functionMap().begin(); it != d->functionMap().end(); ++it ) - (*it).removeAssoziation(rtti); + (*it).removeAssociation(rtti); } -void TraceAssoziation::invalidate(TraceData* d, int rtti) +void TraceAssociation::invalidate(TraceData* d, int rtti) { TraceFunctionMap::Iterator it; for ( it = d->functionMap().begin(); it != d->functionMap().end(); ++it ) - (*it).invalidateAssoziation(rtti); + (*it).invalidateAssociation(rtti); } @@ -1811,7 +1811,7 @@ TraceFunction::~TraceFunction() { - qDeleteAll(_assoziations); + qDeleteAll(_associations); // we are the owner of items generated in our factories qDeleteAll(_deps); @@ -1822,46 +1822,46 @@ } // no unique check is done! -void TraceFunction::addAssoziation(TraceAssoziation* a) +void TraceFunction::addAssociation(TraceAssociation* a) { if (!a) return; - _assoziations.append(a); + _associations.append(a); } -void TraceFunction::removeAssoziation(TraceAssoziation* a) +void TraceFunction::removeAssociation(TraceAssociation* a) { - _assoziations.removeAll(a); + _associations.removeAll(a); } -void TraceFunction::removeAssoziation(int rtti, bool reallyDelete) +void TraceFunction::removeAssociation(int rtti, bool reallyDelete) { if (rtti==0) { if (reallyDelete) - qDeleteAll(_assoziations); - _assoziations.clear(); + qDeleteAll(_associations); + _associations.clear(); return; } - foreach(TraceAssoziation* a, _assoziations) { + foreach(TraceAssociation* a, _associations) { if (a->rtti() == rtti) { if (reallyDelete) delete a; - _assoziations.removeAll(a); + _associations.removeAll(a); return; } } } -void TraceFunction::invalidateAssoziation(int rtti) +void TraceFunction::invalidateAssociation(int rtti) { - foreach(TraceAssoziation* a, _assoziations) { + foreach(TraceAssociation* a, _associations) { if ((rtti==0) || (a->rtti() == rtti)) a->invalidate(); } } -TraceAssoziation* TraceFunction::assoziation(int rtti) +TraceAssociation* TraceFunction::association(int rtti) { - foreach(TraceAssoziation* a, _assoziations) { + foreach(TraceAssociation* a, _associations) { if (a->rtti() == rtti) return a; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcachegrind-4.12.2/libcore/tracedata.h new/kcachegrind-4.12.90/libcore/tracedata.h --- old/kcachegrind-4.12.2/libcore/tracedata.h 2013-10-29 16:54:37.000000000 +0100 +++ new/kcachegrind-4.12.90/libcore/tracedata.h 2014-03-04 07:02:07.000000000 +0100 @@ -1062,30 +1062,30 @@ /** - * For temporary assoziation of objects with TraceFunctions. + * For temporary association of objects with TraceFunctions. * Used in coverage analysis and TreeMap drawing. */ -class TraceAssoziation +class TraceAssociation { public: /** - * Creates an invalid assoziation. + * Creates an invalid association. */ - TraceAssoziation(); - virtual ~TraceAssoziation(); + TraceAssociation(); + virtual ~TraceAssociation(); // for runtime detection virtual int rtti() { return 0; } /** - * Could we set the function assoziation to ourself? - * This only can return false if this is a unique assoziation. + * Could we set the function association to ourself? + * This only can return false if this is a unique association. */ - bool isAssoziated(); + bool isAssociated(); /** * reset function to associate this object to. - * returns true if assoziation could be established + * returns true if association could be established */ bool setFunction(TraceFunction*); TraceFunction* function() { return _function; } @@ -1094,14 +1094,14 @@ bool isValid() { return _valid; } /** - * Delete all assoziations in TraceFunctions of data with - * rtti runtime info. rtti = 0: delete ALL assoziations. + * Delete all associations in TraceFunctions of data with + * rtti runtime info. rtti = 0: delete ALL associations. */ static void clear(TraceData* data, int rtti); /** - * Invalidate all assoziations in TraceFunctions of data with - * rtti runtime info. rtti = 0: Invalidate ALL assoziations. + * Invalidate all associations in TraceFunctions of data with + * rtti runtime info. rtti = 0: Invalidate ALL associations. */ static void invalidate(TraceData* data, int rtti); @@ -1110,7 +1110,7 @@ bool _valid; }; -typedef QList<TraceAssoziation*> TraceAssoziationList; +typedef QList<TraceAssociation*> TraceAssociationList; /** * A traced function @@ -1188,12 +1188,12 @@ void setClass(TraceClass* cls) { _cls = cls; } //void setMapIterator(TraceFunctionMap::Iterator it) { _myMapIterator = it; } - // see TraceFunctionAssoziation - void addAssoziation(TraceAssoziation* a); - void removeAssoziation(TraceAssoziation* a); - void removeAssoziation(int rtti, bool reallyDelete = true); - void invalidateAssoziation(int rtti); - TraceAssoziation* assoziation(int rtti); + // see TraceFunctionAssociation + void addAssociation(TraceAssociation* a); + void removeAssociation(TraceAssociation* a); + void removeAssociation(int rtti, bool reallyDelete = true); + void invalidateAssociation(int rtti); + TraceAssociation* association(int rtti); // cycles void setCycle(TraceFunctionCycle* c) { _cycle = c; } @@ -1220,8 +1220,8 @@ TraceInstrMap* _instrMap; // we are owner bool _instrMapFilled; - // see TraceAssoziation - TraceAssoziationList _assoziations; + // see TraceAssociation + TraceAssociationList _associations; // for cycle detection int _cycleLow; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcachegrind-4.12.2/libviews/callmapview.cpp new/kcachegrind-4.12.90/libviews/callmapview.cpp --- old/kcachegrind-4.12.2/libviews/callmapview.cpp 2013-10-29 16:54:37.000000000 +0100 +++ new/kcachegrind-4.12.90/libviews/callmapview.cpp 2014-03-04 07:02:07.000000000 +0100 @@ -726,7 +726,7 @@ void CallMapCallingItem::init() { #if 0 - // create assoziation: if not possible, i.e. an ass. already exists + // create association: if not possible, i.e. an ass. already exists // for the function, we need to draw the recursive version _recursive = !setFunction(_c->called()); _valid = true; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcachegrind-4.12.2/libviews/coverageview.cpp new/kcachegrind-4.12.90/libviews/coverageview.cpp --- old/kcachegrind-4.12.2/libviews/coverageview.cpp 2013-10-29 16:54:37.000000000 +0100 +++ new/kcachegrind-4.12.90/libviews/coverageview.cpp 2014-03-04 07:02:07.000000000 +0100 @@ -326,7 +326,7 @@ l = Coverage::coverage(f, Coverage::Called, _eventType); foreach(TraceFunction* f2, l) { - Coverage* c = (Coverage*) f2->assoziation(Coverage::Rtti); + Coverage* c = (Coverage*) f2->association(Coverage::Rtti); if (c && (c->inclusive()>0.0)) _hc.addCost(f2, SubCost(realSum * c->inclusive())); } @@ -336,7 +336,7 @@ TraceFunction* ff; for(int i=0;i<_hc.realCount();i++) { ff = (TraceFunction*) _hc[i]; - Coverage* c = (Coverage*) ff->assoziation(Coverage::Rtti); + Coverage* c = (Coverage*) ff->association(Coverage::Rtti); if (_showCallers) item = new CallerCoverageItem(0, c, f, _eventType, _groupType); else @@ -346,7 +346,7 @@ if (_hc.hasMore()) { // a placeholder for all the functions skipped ... ff = (TraceFunction*) _hc[_hc.maxSize()-1]; - Coverage* c = (Coverage*) ff->assoziation(Coverage::Rtti); + Coverage* c = (Coverage*) ff->association(Coverage::Rtti); if (_showCallers) item = new CallerCoverageItem(0, _hc.count() - _hc.maxSize(), c, f, _eventType, _groupType); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcachegrind-4.12.2/libviews/treemap.h new/kcachegrind-4.12.90/libviews/treemap.h --- old/kcachegrind-4.12.2/libviews/treemap.h 2013-10-29 16:54:37.000000000 +0100 +++ new/kcachegrind-4.12.90/libviews/treemap.h 2014-03-04 07:02:07.000000000 +0100 @@ -41,7 +41,6 @@ #include <QMouseEvent> class QMenu; -class Q3PopupMenu; class TreeMapWidget; class TreeMapItem; class TreeMapItemList; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kcachegrind-4.12.2/qcachegrind/qcachegrind.desktop new/kcachegrind-4.12.90/qcachegrind/qcachegrind.desktop --- old/kcachegrind-4.12.2/qcachegrind/qcachegrind.desktop 2013-10-29 16:54:37.000000000 +0100 +++ new/kcachegrind-4.12.90/qcachegrind/qcachegrind.desktop 2014-03-04 07:02:07.000000000 +0100 @@ -22,6 +22,7 @@ Name[hu]=QCachegrind Name[it]=QCachegrind Name[kk]=QCachegrind +Name[ko]=QCachegrind Name[lt]=QCachegrind Name[mr]=क्यु-कॅशेग्रिन्ड Name[nb]=QCachegrind -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
