diff -r 000000000000 -r 96e5fb8b040d kerneltest/e32utils/trace/btrace_syslock.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32utils/trace/btrace_syslock.pl Thu Dec 17 09:24:54 2009 +0200 @@ -0,0 +1,210 @@ +# Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of the License "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# e32utils\trace\btrace_syslock.pl +# Process runtests btrace log file to determine the maximum time the system +# lock was held for. +# Example commands to generate a runtests btrace log file with system lock +# tracing analysis when running e32test.auto.bat and 10MB btrace buffer: +# 1 - btrace -f4,17 -m1 -b10480 +# 2 - runtests e32test.auto.bat -a OR use +# btrace -a +# after running what ever is being tested +# Syntax: +# perl btrace_syslock.pl [ [ is given, this is how many of the last (i.e. slowest) +# results to look up in the symbol file. Defaults to 1. +# +# + +use strict; + +# Unbuffer stderr +my $oldfh = select(STDERR); $| = 1; select($oldfh); + +print STDERR "\nTHIS TOOL IS UNOFFICIAL, UNSUPPORTED AND SUBJECT TO CHANGE WITHOUT NOTICE!\n\n"; + + +my $usage = "$0: usage: perl $0 [ []]\n"; + +my ($infile, $symbolfile, $howmany) = @ARGV; + +die($usage) if !($infile && -f $infile) || ($symbolfile && ! -f $symbolfile); + +my $symbols = new SymbolTable($symbolfile); + +open(my $in, "<", $infile) || die("$0: $infile: $!\n"); + +my @wanted = (); + +my $lockinfo; +my $testnames = {}; +my $bufferfulls = 0; +my $berror = 0; + +while (<$in>) + { + if (/BTRACE BUFFER IS FULL/) + { + $berror = 1; + next; + } + if (/^RUNTESTS: Test/) + { + $testnames->{$lockinfo} = $_ if $lockinfo; + $berror = 0; + next; + } + if (/^ scalar(@wanted); + + print @wanted[0 .. $#wanted - $howmany]; + + for my $line (@wanted[$#wanted - $howmany + 1 .. $#wanted]) + { + print "\n", $line; + +# MaxTime AveTime HeldCount MaxPC MaxTimestamp TraceId Name +# 71 7 104631 f8023ddc 300257957 640005a4 'Sys +# + my @fields = split(" ", $line); + my $maxpc = $fields[4]; + + print " ", + $symbols->lookup($maxpc); + + print " ", + $testnames->{$line} if $testnames->{$line}; + } + } +else + { + print @wanted; + } + +printf(STDERR "%d buffer %s found\n", $bufferfulls, + $bufferfulls == 1 ? "overflow was" : "overflows were") if $bufferfulls; + + +# ======================================================================== +# +package SymbolTable; + +sub new +{ + my ($proto, $filename) = @_; + + return undef if ! $filename; + + my @symbols; + + open(my $in, "<", $filename) || die("$0: $filename: $!\n"); + + print STDERR "Loading symbols..."; + + while (<$in>) + { + # f800c040 0000 btrace_fiq k_entry_.o(.emb_text) + if (/^[0-9a-f]{8}\s/i) # Have a symbol table entry + { + # Ensure the address is in lowercase + $_ = lc(substr($_, 0, 8)) . substr($_, 8); + push(@symbols, $_); + } + } + + close($in); + + my $symbols = [sort @symbols]; + + my $class = ref($proto) || $proto; + + bless($symbols, $class); + + print STDERR " done\n"; + + return $symbols; +} + +# lookup() is an implementation of the binary search algorithm below, +# retrieved from wikipedia on 10/9/07 +# +# BinarySearch(A[0..N-1], value) { +# low = 0 +# high = N - 1 +# while (low <= high) { +# mid = (low + high) / 2 +# if (A[mid] > value) +# high = mid - 1 +# else if (A[mid] < value) +# low = mid + 1 +# else +# return mid +# } +# return not_found +# } +# +sub lookup +{ + my ($symbols, $addr) = @_; + + return "BAD ADDRESS $addr\n" unless $addr =~ /^[0-9a-f]{8}$/i; + $addr = lc($addr); + + my ($low, $high) = (0, $#$symbols); + + while ($low <= $high) + { + my $mid = int(($low + $high) / 2); + my $mid_value = substr($symbols->[$mid], 0, 8); +## print "low: $low, high: $high, mid: $mid, mid_value: $mid_value\n"; + if ($mid_value gt $addr) + { + $high = $mid - 1; + } + elsif ($mid_value lt $addr) + { + $low = $mid + 1; + } + else + { + # Found an exact match + return($symbols->[$mid]); + } + } + + # We didn't find an exact match. We want the largest value that is + # less than the input address. This will be the value at either + # $low or $high. + + return $symbols->[$low] if $low <= $#$symbols && + $symbols->[$low] lt $addr; + return "NO SYMBOL FOUND\n" if $high < 0; + return $symbols->[$high] if $symbols->[$high] lt $addr; + return "THIS SHOULDN'T HAPPEN\n"; +}