os/kernelhwsrv/kerneltest/e32utils/trace/btrace_syslock.pl
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
# Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
# All rights reserved.
sl@0
     3
# This component and the accompanying materials are made available
sl@0
     4
# under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
# which accompanies this distribution, and is available
sl@0
     6
# at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
#
sl@0
     8
# Initial Contributors:
sl@0
     9
# Nokia Corporation - initial contribution.
sl@0
    10
#
sl@0
    11
# Contributors:
sl@0
    12
#
sl@0
    13
# Description:
sl@0
    14
# e32utils\trace\btrace_syslock.pl
sl@0
    15
# Process runtests btrace log file to determine the maximum time the system
sl@0
    16
# lock was held for.
sl@0
    17
# Example commands to generate a runtests btrace log file with system lock 
sl@0
    18
# tracing analysis when running e32test.auto.bat and 10MB btrace buffer:
sl@0
    19
# 1 - btrace -f4,17 -m1 -b10480
sl@0
    20
# 2 - runtests e32test.auto.bat -a OR use 
sl@0
    21
# btrace -a
sl@0
    22
# after running what ever is being tested
sl@0
    23
# Syntax:
sl@0
    24
# perl btrace_syslock.pl <inputfile> [<symbolfile> [<maxsymbols]]
sl@0
    25
# If <maxsymbols> is given, this is how many of the last (i.e. slowest)
sl@0
    26
# results to look up in the symbol file.  Defaults to 1.
sl@0
    27
# 
sl@0
    28
#
sl@0
    29
sl@0
    30
use strict;
sl@0
    31
sl@0
    32
# Unbuffer stderr
sl@0
    33
my $oldfh = select(STDERR); $| = 1; select($oldfh);
sl@0
    34
sl@0
    35
print STDERR "\nTHIS TOOL IS UNOFFICIAL, UNSUPPORTED AND SUBJECT TO CHANGE WITHOUT NOTICE!\n\n";
sl@0
    36
sl@0
    37
sl@0
    38
my $usage = "$0: usage: perl $0 <logfile> [<symbolfile> [<maxsymbols>]]\n";
sl@0
    39
sl@0
    40
my ($infile, $symbolfile, $howmany) = @ARGV;
sl@0
    41
sl@0
    42
die($usage) if !($infile && -f $infile) || ($symbolfile && ! -f $symbolfile);
sl@0
    43
sl@0
    44
my $symbols = new SymbolTable($symbolfile);
sl@0
    45
sl@0
    46
open(my $in, "<", $infile) || die("$0: $infile: $!\n");
sl@0
    47
sl@0
    48
my @wanted = ();
sl@0
    49
sl@0
    50
my $lockinfo;
sl@0
    51
my $testnames = {};
sl@0
    52
my $bufferfulls = 0;
sl@0
    53
my $berror = 0;
sl@0
    54
sl@0
    55
while (<$in>)
sl@0
    56
	{
sl@0
    57
	if (/BTRACE BUFFER IS FULL/)
sl@0
    58
		{
sl@0
    59
			$berror = 1;
sl@0
    60
			next;
sl@0
    61
		}
sl@0
    62
	if (/^RUNTESTS: Test/)
sl@0
    63
		{
sl@0
    64
			$testnames->{$lockinfo} = $_ if $lockinfo;
sl@0
    65
			$berror = 0;
sl@0
    66
			next;
sl@0
    67
		}
sl@0
    68
	if (/^<FM/ && /System lock/i)
sl@0
    69
		{
sl@0
    70
		push(@wanted, $_);
sl@0
    71
		$lockinfo = $_;
sl@0
    72
		$bufferfulls++ if $berror;
sl@0
    73
		}
sl@0
    74
	}
sl@0
    75
sl@0
    76
close($in);
sl@0
    77
sl@0
    78
@wanted = sort @wanted;
sl@0
    79
sl@0
    80
if (ref($symbols))
sl@0
    81
	{
sl@0
    82
	$howmany ||= 1;
sl@0
    83
	$howmany = 1 if $howmany < 1;
sl@0
    84
	$howmany = scalar(@wanted) if $howmany > scalar(@wanted);
sl@0
    85
sl@0
    86
	print @wanted[0 .. $#wanted - $howmany];
sl@0
    87
sl@0
    88
	for my $line (@wanted[$#wanted - $howmany + 1 .. $#wanted])
sl@0
    89
		{
sl@0
    90
		print "\n", $line;
sl@0
    91
sl@0
    92
#             MaxTime  AveTime HeldCount MaxPC    MaxTimestamp  TraceId Name
sl@0
    93
# <FM000000>       71        7    104631 f8023ddc    300257957 640005a4 'Sys
sl@0
    94
#
sl@0
    95
		my @fields = split(" ", $line);
sl@0
    96
		my $maxpc = $fields[4];
sl@0
    97
sl@0
    98
		print "                                       ",
sl@0
    99
		    $symbols->lookup($maxpc);
sl@0
   100
sl@0
   101
		print "                                       ",
sl@0
   102
		    $testnames->{$line} if $testnames->{$line};
sl@0
   103
		}
sl@0
   104
	}
sl@0
   105
else
sl@0
   106
	{
sl@0
   107
	print @wanted;
sl@0
   108
	}
sl@0
   109
sl@0
   110
printf(STDERR "%d buffer %s found\n", $bufferfulls,
sl@0
   111
    $bufferfulls == 1 ? "overflow was" : "overflows were") if $bufferfulls;
sl@0
   112
sl@0
   113
sl@0
   114
# ========================================================================
sl@0
   115
#
sl@0
   116
package SymbolTable;
sl@0
   117
sl@0
   118
sub new
sl@0
   119
{
sl@0
   120
	my ($proto, $filename) = @_;
sl@0
   121
sl@0
   122
	return undef if ! $filename;
sl@0
   123
sl@0
   124
	my @symbols;
sl@0
   125
sl@0
   126
	open(my $in, "<", $filename) || die("$0: $filename: $!\n");
sl@0
   127
sl@0
   128
	print STDERR "Loading symbols...";
sl@0
   129
sl@0
   130
	while (<$in>)
sl@0
   131
		{
sl@0
   132
		# f800c040    0000    btrace_fiq   k_entry_.o(.emb_text)
sl@0
   133
		if (/^[0-9a-f]{8}\s/i)	# Have a symbol table entry
sl@0
   134
			{
sl@0
   135
			# Ensure the address is in lowercase
sl@0
   136
			$_ = lc(substr($_, 0, 8)) . substr($_, 8);
sl@0
   137
			push(@symbols, $_);
sl@0
   138
			}
sl@0
   139
		}
sl@0
   140
sl@0
   141
	close($in);
sl@0
   142
sl@0
   143
	my $symbols = [sort @symbols];
sl@0
   144
sl@0
   145
	my $class = ref($proto) || $proto;
sl@0
   146
sl@0
   147
	bless($symbols, $class);
sl@0
   148
sl@0
   149
	print STDERR " done\n";
sl@0
   150
sl@0
   151
	return $symbols;
sl@0
   152
}
sl@0
   153
sl@0
   154
# lookup() is an implementation of the binary search algorithm below,
sl@0
   155
# retrieved from wikipedia on 10/9/07
sl@0
   156
#
sl@0
   157
#  BinarySearch(A[0..N-1], value) {
sl@0
   158
#       low = 0
sl@0
   159
#       high = N - 1
sl@0
   160
#       while (low <= high) {
sl@0
   161
#           mid = (low + high) / 2
sl@0
   162
#           if (A[mid] > value)
sl@0
   163
#               high = mid - 1
sl@0
   164
#           else if (A[mid] < value)
sl@0
   165
#               low = mid + 1
sl@0
   166
#           else
sl@0
   167
#               return mid
sl@0
   168
#       }
sl@0
   169
#       return not_found
sl@0
   170
#   }
sl@0
   171
#
sl@0
   172
sub lookup
sl@0
   173
{
sl@0
   174
	my ($symbols, $addr) = @_;
sl@0
   175
sl@0
   176
	return "BAD ADDRESS $addr\n" unless $addr =~ /^[0-9a-f]{8}$/i;
sl@0
   177
	$addr = lc($addr);
sl@0
   178
sl@0
   179
	my ($low, $high) = (0, $#$symbols);
sl@0
   180
sl@0
   181
	while ($low <= $high)
sl@0
   182
		{
sl@0
   183
		my $mid = int(($low + $high) / 2);
sl@0
   184
		my $mid_value = substr($symbols->[$mid], 0, 8);
sl@0
   185
## print "low: $low, high: $high, mid: $mid, mid_value: $mid_value\n";
sl@0
   186
		if ($mid_value gt $addr)
sl@0
   187
			{
sl@0
   188
			$high = $mid - 1;
sl@0
   189
			}
sl@0
   190
		elsif ($mid_value lt $addr)
sl@0
   191
			{
sl@0
   192
			$low = $mid + 1;
sl@0
   193
			}
sl@0
   194
		else
sl@0
   195
			{
sl@0
   196
			# Found an exact match
sl@0
   197
			return($symbols->[$mid]);
sl@0
   198
			}
sl@0
   199
		}
sl@0
   200
sl@0
   201
	# We didn't find an exact match.  We want the largest value that is
sl@0
   202
	# less than the input address.  This will be the value at either
sl@0
   203
	# $low or $high.
sl@0
   204
sl@0
   205
	return $symbols->[$low] if $low <= $#$symbols &&
sl@0
   206
	    $symbols->[$low] lt $addr;
sl@0
   207
	return "NO SYMBOL FOUND\n" if $high < 0;
sl@0
   208
	return $symbols->[$high] if $symbols->[$high] lt $addr;
sl@0
   209
	return "THIS SHOULDN'T HAPPEN\n";
sl@0
   210
}