134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#!/usr/bin/perl
234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# This script processes strace -f output.  It displays a graph of invoked
434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# subprocesses, and is useful for finding out what complex commands do.
534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# You will probably want to invoke strace with -q as well, and with
734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# -s 100 to get complete filenames.
834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# The script can also handle the output with strace -t, -tt, or -ttt.
1034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# It will add elapsed time for each process in that case.
1134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
1234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# This script is Copyright (C) 1998 by Richard Braakman <dark@xs4all.nl>.
1334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
1434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# Redistribution and use in source and binary forms, with or without
1534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# modification, are permitted provided that the following conditions
1634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# are met:
1734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# 1. Redistributions of source code must retain the above copyright
1834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#    notice, this list of conditions and the following disclaimer.
1934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# 2. Redistributions in binary form must reproduce the above copyright
2034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#    notice, this list of conditions and the following disclaimer in the
2134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#    documentation and/or other materials provided with the distribution.
2234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# 3. The name of the author may not be used to endorse or promote products
2334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#    derived from this software without specific prior written permission.
2434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#
2534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
3034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
3634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectmy %unfinished;
3734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
3834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# Scales for strace slowdown.  Make configurable!
3934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectmy $scale_factor = 3.5;
4034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
4134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectwhile (<>) {
4234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    my ($pid, $call, $args, $result, $time);
4334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    chop;
4434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
4534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    s/^(\d+)\s+//;
4634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    $pid = $1;
4734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
4834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    if (s/^(\d\d):(\d\d):(\d\d)(?:\.(\d\d\d\d\d\d))? //) {
4934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	$time = $1 * 3600 + $2 * 60 + $3;
5034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	if (defined $4) {
5134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    $time = $time + $4 / 1000000;
5234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    $floatform = 1;
5334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	}
5434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    } elsif (s/^(\d+)\.(\d\d\d\d\d\d) //) {
5534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	$time = $1 + ($2 / 1000000);
5634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	$floatform = 1;
5734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    }
5834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
5934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    if (s/ <unfinished ...>$//) {
6034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	$unfinished{$pid} = $_;
6134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	next;
6234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    }
6334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
6434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    if (s/^<... \S+ resumed> //) {
6534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	unless (exists $unfinished{$pid}) {
6634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    print STDERR "$0: $ARGV: cannot find start of resumed call on line $.";
6734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    next;
6834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	}
6934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	$_ = $unfinished{$pid} . $_;
7034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	delete $unfinished{$pid};
7134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    }
7234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
7334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    if (/^--- SIG(\S+) \(.*\) ---$/) {
7434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	# $pid received signal $1
7534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	# currently we don't do anything with this
7634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	next;
7734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    }
7834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
7934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    if (/^\+\+\+ killed by SIG(\S+) \+\+\+$/) {
8034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	# $pid received signal $1
8134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	handle_killed($pid, $time);
8234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	next;
8334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    }
8434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
8534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    ($call, $args, $result) = /(\S+)\((.*)\)\s+= (.*)$/;
8634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    unless (defined $result) {
8734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	print STDERR "$0: $ARGV: $.: cannot parse line.\n";
8834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	next;
8934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    }
9034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
9134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    handle_trace($pid, $call, $args, $result, $time);
9234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project}
9334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
9434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectdisplay_trace();
9534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
9634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectexit 0;
9734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
9834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectsub parse_str {
9934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    my ($in) = @_;
10034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    my $result = "";
10134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
10234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    while (1) {
10334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	if ($in =~ s/^\\(.)//) {
10434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    $result .= $1;
10534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	} elsif ($in =~ s/^\"//) {
10634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    if ($in =~ s/^\.\.\.//) {
10734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		return ("$result...", $in);
10834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    }
10934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    return ($result, $in);
11034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	} elsif ($in =~ s/([^\\\"]*)//) {
11134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    $result .= $1;
11234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	} else {
11334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    return (undef, $in);
11434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	}
11534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    }
116f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown}
11734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
11834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectsub parse_one {
11934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    my ($in) = @_;
12034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
12134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    if ($in =~ s/^\"//) {
12234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	($tmp, $in) = parse_str($in);
12334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	if (not defined $tmp) {
12434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    print STDERR "$0: $ARGV: $.: cannot parse string.\n";
12534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    return (undef, $in);
12634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	}
12734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	return ($tmp, $in);
12834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    } elsif ($in =~ s/^0x(\x+)//) {
12934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	return (hex $1, $in);
13034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    } elsif ($in =~ s/^(\d+)//) {
13134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	return (int $1, $in);
13234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    } else {
13334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	print STDERR "$0: $ARGV: $.: unrecognized element.\n";
13434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	return (undef, $in);
13534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    }
13634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project}
13734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
13834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectsub parseargs {
13934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    my ($in) = @_;
14034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    my @args = ();
14134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    my $tmp;
14234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
14334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    while (length $in) {
14434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	if ($in =~ s/^\[//) {
14534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    my @subarr = ();
14634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    if ($in =~ s,^/\* (\d+) vars \*/\],,) {
14734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		push @args, $1;
14834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    } else {
14934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		while ($in !~ s/^\]//) {
15034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		    ($tmp, $in) = parse_one($in);
15134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		    defined $tmp or return undef;
15234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		    push @subarr, $tmp;
15334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		    unless ($in =~ /^\]/ or $in =~ s/^, //) {
15434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project			print STDERR "$0: $ARGV: $.: missing comma in array.\n";
15534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project			return undef;
15634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		    }
15734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		    if ($in =~ s/^\.\.\.//) {
15834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project			push @subarr, "...";
15934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		    }
16034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		}
16134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		push @args, \@subarr;
16234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    }
16334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	} elsif ($in =~ s/^\{//) {
16434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    my %subhash = ();
16534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    while ($in !~ s/^\}//) {
16634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		my $key;
16734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		unless ($in =~ s/^(\w+)=//) {
16834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		    print STDERR "$0: $ARGV: $.: struct field expected.\n";
16934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		    return undef;
17034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		}
17134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		$key = $1;
17234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		($tmp, $in) = parse_one($in);
17334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		defined $tmp or return undef;
17434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		$subhash{$key} = $tmp;
17534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		unless ($in =~ s/, //) {
17634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		    print STDERR "$0: $ARGV: $.: missing comma in struct.\n";
17734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		    return undef;
17834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		}
17934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    }
18034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    push @args, \%subhash;
18134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	} else {
18234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    ($tmp, $in) = parse_one($in);
18334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    defined $tmp or return undef;
18434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    push @args, $tmp;
18534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	}
18634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	unless (length($in) == 0 or $in =~ s/^, //) {
18734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    print STDERR "$0: $ARGV: $.: missing comma.\n";
18834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    return undef;
189f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown	}
19034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    }
19134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    return @args;
19234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project}
193f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown
19434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
19534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectmy $depth = "";
19634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
19734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# process info, indexed by pid.
198f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# fields:
19934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#    parent         pid number
20034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#    seq            forks and execs for this pid, in sequence  (array)
201f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown
20234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#  filename and argv (from latest exec)
20334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#  basename (derived from filename)
20434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# argv[0] is modified to add the basename if it differs from the 0th argument.
20534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
20634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectmy %pr;
20734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
20834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectsub handle_trace {
20934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    my ($pid, $call, $args, $result, $time) = @_;
21034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    my $p;
21134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
21234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    if (defined $time and not defined $pr{$pid}{start}) {
21334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	$pr{$pid}{start} = $time;
21434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    }
21534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
21634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    if ($call eq 'execve') {
21734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	return if $result != 0;
21834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
21934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	my ($filename, $argv) = parseargs($args);
22034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	($basename) = $filename =~ m/([^\/]*)$/;
22134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	if ($basename ne $$argv[0]) {
22234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    $$argv[0] = "$basename($$argv[0])";
22334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project        }
22434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	my $seq = $pr{$pid}{seq};
22534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	$seq = [] if not defined $seq;
22634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
22734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	push @$seq, ['EXEC', $filename, $argv];
22834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
22934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	$pr{$pid}{seq} = $seq;
230f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown    } elsif ($call eq 'fork' || $call eq 'clone' || $call eq 'vfork') {
23134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	return if $result == 0;
23234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
23334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	my $seq = $pr{$pid}{seq};
23434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	$seq = [] if not defined $seq;
23534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	push @$seq, ['FORK', $result];
23634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	$pr{$pid}{seq} = $seq;
23734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	$pr{$result}{parent} = $pid;
23834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    } elsif ($call eq '_exit') {
23934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	$pr{$pid}{end} = $time if defined $time;
24034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    }
24134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project}
24234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
24334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectsub handle_killed {
24434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    my ($pid, $time) = @_;
24534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    $pr{$pid}{end} = $time if defined $time;
24634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project}
24734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
24834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectsub straight_seq {
24934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    my ($pid) = @_;
25034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    my $seq = $pr{$pid}{seq};
25134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
25234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    for $elem (@$seq) {
25334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	if ($$elem[0] eq 'EXEC') {
25434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    my $argv = $$elem[2];
25534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    print "$$elem[0] $$elem[1] @$argv\n";
25634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	} elsif ($$elem[0] eq 'FORK') {
25734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    print "$$elem[0] $$elem[1]\n";
25834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	} else {
25934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    print "$$elem[0]\n";
26034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	}
26134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    }
26234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project}
26334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
26434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectsub first_exec {
26534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    my ($pid) = @_;
26634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    my $seq = $pr{$pid}{seq};
26734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
26834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    for $elem (@$seq) {
26934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	if ($$elem[0] eq 'EXEC') {
27034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    return $elem;
27134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	}
27234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    }
27334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    return undef;
27434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project}
27534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
27634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectsub display_pid_trace {
27734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    my ($pid, $lead) = @_;
27834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    my $i = 0;
27934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    my @seq = @{$pr{$pid}{seq}};
28034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    my $elapsed;
28134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
28234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    if (not defined first_exec($pid)) {
28334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	unshift @seq, ['EXEC', '', ['(anon)'] ];
28434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    }
28534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
28634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    if (defined $pr{$pid}{start} and defined $pr{$pid}{end}) {
28734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	$elapsed = $pr{$pid}{end} - $pr{$pid}{start};
28834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	$elapsed /= $scale_factor;
28934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	if ($floatform) {
29034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    $elapsed = sprintf("%0.02f", $elapsed);
29134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	} else {
29234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    $elapsed = int $elapsed;
29334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	}
29434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    }
29534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
29634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    for $elem (@seq) {
29734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	$i++;
29834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	if ($$elem[0] eq 'EXEC') {
29934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    my $argv = $$elem[2];
30034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    if (defined $elapsed) {
30134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		print "$lead [$elapsed] @$argv\n";
30234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		undef $elapsed;
30334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    } else {
30434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		print "$lead @$argv\n";
30534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    }
30634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	} elsif ($$elem[0] eq 'FORK') {
30734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    if ($i == 1) {
30834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project                if ($lead =~ /-$/) {
309f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown		    display_pid_trace($$elem[1], "$lead--+--");
31034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project                } else {
311f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown		    display_pid_trace($$elem[1], "$lead  +--");
31234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project                }
31334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    } elsif ($i == @seq) {
31434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		display_pid_trace($$elem[1], "$lead  `--");
31534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    } else {
31634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project		display_pid_trace($$elem[1], "$lead  +--");
31734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    }
31834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	}
31934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	if ($i == 1) {
32034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    $lead =~ s/\`--/   /g;
32134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    $lead =~ s/-/ /g;
32234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	    $lead =~ s/\+/|/g;
32334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	}
32434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    }
32534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project}
32634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
32734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectsub display_trace {
32834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    my ($startpid) = @_;
32934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
33034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    $startpid = (keys %pr)[0];
33134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    while ($pr{$startpid}{parent}) {
33234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project	$startpid = $pr{$startpid}{parent};
33334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    }
33434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project
33534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project    display_pid_trace($startpid, "");
33634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project}
337