Home | History | Annotate | Download | only in perl
      1 #!/usr/bin/perl -w
      2 # (c) 2009, Tom Zanussi <tzanussi (at] gmail.com>
      3 # Licensed under the terms of the GNU GPL License version 2
      4 
      5 # Display r/w activity for files read/written to for a given program
      6 
      7 # The common_* event handler fields are the most useful fields common to
      8 # all events.  They don't necessarily correspond to the 'common_*' fields
      9 # in the status files.  Those fields not available as handler params can
     10 # be retrieved via script functions of the form get_common_*().
     11 
     12 use 5.010000;
     13 use strict;
     14 use warnings;
     15 
     16 use lib "$ENV{'PERF_EXEC_PATH'}/scripts/perl/Perf-Trace-Util/lib";
     17 use lib "./Perf-Trace-Util/lib";
     18 use Perf::Trace::Core;
     19 use Perf::Trace::Util;
     20 
     21 my $usage = "perf script -s rw-by-file.pl <comm>\n";
     22 
     23 my $for_comm = shift or die $usage;
     24 
     25 my %reads;
     26 my %writes;
     27 
     28 sub syscalls::sys_enter_read
     29 {
     30     my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
     31 	$common_pid, $common_comm, $nr, $fd, $buf, $count) = @_;
     32 
     33     if ($common_comm eq $for_comm) {
     34 	$reads{$fd}{bytes_requested} += $count;
     35 	$reads{$fd}{total_reads}++;
     36     }
     37 }
     38 
     39 sub syscalls::sys_enter_write
     40 {
     41     my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
     42 	$common_pid, $common_comm, $nr, $fd, $buf, $count) = @_;
     43 
     44     if ($common_comm eq $for_comm) {
     45 	$writes{$fd}{bytes_written} += $count;
     46 	$writes{$fd}{total_writes}++;
     47     }
     48 }
     49 
     50 sub trace_end
     51 {
     52     printf("file read counts for $for_comm:\n\n");
     53 
     54     printf("%6s  %10s  %10s\n", "fd", "# reads", "bytes_requested");
     55     printf("%6s  %10s  %10s\n", "------", "----------", "-----------");
     56 
     57     foreach my $fd (sort {$reads{$b}{bytes_requested} <=>
     58 			      $reads{$a}{bytes_requested}} keys %reads) {
     59 	my $total_reads = $reads{$fd}{total_reads};
     60 	my $bytes_requested = $reads{$fd}{bytes_requested};
     61 	printf("%6u  %10u  %10u\n", $fd, $total_reads, $bytes_requested);
     62     }
     63 
     64     printf("\nfile write counts for $for_comm:\n\n");
     65 
     66     printf("%6s  %10s  %10s\n", "fd", "# writes", "bytes_written");
     67     printf("%6s  %10s  %10s\n", "------", "----------", "-----------");
     68 
     69     foreach my $fd (sort {$writes{$b}{bytes_written} <=>
     70 			      $writes{$a}{bytes_written}} keys %writes) {
     71 	my $total_writes = $writes{$fd}{total_writes};
     72 	my $bytes_written = $writes{$fd}{bytes_written};
     73 	printf("%6u  %10u  %10u\n", $fd, $total_writes, $bytes_written);
     74     }
     75 
     76     print_unhandled();
     77 }
     78 
     79 my %unhandled;
     80 
     81 sub print_unhandled
     82 {
     83     if ((scalar keys %unhandled) == 0) {
     84 	return;
     85     }
     86 
     87     print "\nunhandled events:\n\n";
     88 
     89     printf("%-40s  %10s\n", "event", "count");
     90     printf("%-40s  %10s\n", "----------------------------------------",
     91 	   "-----------");
     92 
     93     foreach my $event_name (keys %unhandled) {
     94 	printf("%-40s  %10d\n", $event_name, $unhandled{$event_name});
     95     }
     96 }
     97 
     98 sub trace_unhandled
     99 {
    100     my ($event_name, $context, $common_cpu, $common_secs, $common_nsecs,
    101 	$common_pid, $common_comm) = @_;
    102 
    103     $unhandled{$event_name}++;
    104 }
    105 
    106 
    107