Home | History | Annotate | Download | only in ioshark
      1 #!/bin/sh
      2 
      3 # This function just re-writes the timestamp of the strace entries to be
      4 # seconds.usecs since boot. To match the timestamping of ftrace (so we can
      5 # merge them later).
      6 process_strace()
      7 {
      8     strace=$1
      9     # parse in data/system/vendor and parse out /sys/devices/system/...
     10     egrep '\/system\/|\/data\/|\/vendor\/' $strace | egrep -v '\/sys\/devices\/system\/' > bar
     11     fgrep -v '= -1' bar > foo
     12     mv foo bar
     13     # begin_time is seconds since epoch
     14     begin_time=`cat trace.begin`
     15     # replace seconds since epoch with SECONDS SINCE BOOT in the
     16     # strace files
     17     awk -v begin="$begin_time" '{ printf "%f strace ", $1 - begin; $1=""; print $0}' bar > $2
     18     rm bar
     19 }
     20 
     21 #
     22 # This function processes the ftrace file, removing the fields that we don't care
     23 # about, breaks up the ftrace file into one file per pid.
     24 # Input : One single fstrace file.
     25 # Output : Multiple fstrace.pid files.
     26 prep_fstrace()
     27 {
     28     # Remove leading junk
     29     fgrep android_fs_data $1 | sed 's/^.* \[.*\] //' | sed s/://g | sed s/,//g > foo
     30     # Sanitize the filenames, removing spaces within the filename etc
     31     sed 's/android_fs_dataread_start/read/' foo > bar1
     32     mv bar1 bar
     33     # First column is timestamp SECONDS SINCE BOOT
     34     awk '{ print $2, "ftrace", $3, $5, $7, $9, $13 }' bar > foo
     35     #awk '{ s ="" ; for (i=2; i <= NF ; i++) s = s $i " "; print s}' bar > foo
     36     rm bar
     37     # Get all the uniq pids
     38     awk '{print $7}' foo | sort | uniq > pidlist
     39     for i in `cat pidlist`
     40     do
     41 	awk -v pid=$i '{ if (pid == $7) print $0}' foo > fstrace.$i
     42     done
     43     rm pidlist
     44     rm foo
     45 }
     46 
     47 # Merge straces and ftraces.
     48 # The goal here is to catch mmap'ed IO (reads) that won't be in the
     49 # strace file. The algorithm is to look for mmaps in the strace file,
     50 # use the files tha are mmap'ed to search in the ftraces to pick up
     51 # tracepoints from there, and merge those with the straces.
     52 # The output of this function is a set of parsed_input_trace.<pid>
     53 # files, that can then be compiled into .wl files
     54 merge_compile()
     55 {
     56     for stracefile in trace.*
     57     do
     58 	if [ $stracefile == trace.begin ] || [ $stracefile == trace.tar ];
     59 	then
     60 	    continue
     61 	fi
     62 	# Get the pid from the strace filename (pid is the extension)
     63 	pid=${stracefile##*.}
     64 	process_strace $stracefile foo.$pid
     65 	if ! [ -s foo.$pid ]; then
     66 	    rm foo.$pid
     67 	    continue
     68 	fi
     69 	#
     70 	# If we have matching strace and ftrace files, then look for mmaps in
     71 	# the strace pluck the corresponding entries for the mmap (mmaped IO)
     72 	# from the ftrace and merge them into the strace
     73 	#
     74 	if [ -f fstrace.$pid ]; then
     75 	    fgrep mmap foo.$pid > bar
     76 	    if [ -s bar ]; then
     77 		# Get all the unique mmap'ed filenames from the strace
     78 		awk '{ print $7 }' bar | sed 's/^[^<]*<//g' | sed 's/>,//g' > mapped_files
     79 		# Pluck all the lines from the ftrace corresponding to the mmaps
     80 		cat /dev/null > footemp
     81 		for j in `sort mapped_files | uniq`
     82 		do
     83 		    # Merge the readpage(s) traces from the ftrace into strace
     84 		    # for this mmaped file.
     85 		    grep -w $j fstrace.$pid > foobar
     86 		    if [ $? == 0 ]; then
     87 			sort foo.$pid foobar >> footemp
     88 		    fi
     89 		    rm foobar
     90 		done
     91 		rm mapped_files
     92 		if [ -s footemp ]; then
     93 		    mv footemp parsed_input_trace.$pid
     94 		else
     95 		    mv foo.$pid parsed_input_trace.$pid
     96 		fi
     97 	    else
     98 		mv foo.$pid parsed_input_trace.$pid
     99 	    fi
    100 	    rm bar
    101 	else
    102 	    mv foo.$pid parsed_input_trace.$pid
    103 	fi
    104 	echo compiling parsed_input_trace.$pid
    105 	compile_ioshark parsed_input_trace.$pid $pid.wl
    106 	rm parsed_input_trace.$pid
    107 	rm -f foo.$pid
    108     done
    109 }
    110 
    111 catch_sigint()
    112 {
    113     echo "signal INT received, killing streaming trace capture"
    114     ps_line=`ps -ef | grep trace_pipe | grep adb `
    115     if [ $? == 0 ]; then
    116         echo Killing `echo $ps_line | awk '{s = ""; for (i=8; i <= NF ; i++) s = s $i " "; print s}' `
    117 	kill `echo $ps_line | awk '{print $2}' `
    118     fi
    119     ps_line=`ps -ef | grep strace | grep adb `
    120     if [ $? == 0 ]; then
    121         echo Killing `echo $ps_line | awk '{s = ""; for (i=8; i <= NF ; i++) s = s $i " "; print s}' `
    122 	kill `echo $ps_line | awk '{print $2}' `
    123     fi
    124 }
    125 
    126 enable_tracepoints()
    127 {
    128     adb shell "echo 1 > /sys/kernel/debug/tracing/events/android_fs/android_fs_dataread_start/enable"
    129     adb shell "echo 1 > /sys/kernel/debug/tracing/tracing_on"
    130 }
    131 
    132 disable_tracepoints()
    133 {
    134     adb shell "echo 0 > /sys/kernel/debug/tracing/events/android_fs/android_fs_dataread_start/enable"
    135     adb shell "echo 0 > /sys/kernel/debug/tracing/tracing_on"
    136 }
    137 
    138 kill_traces()
    139 {
    140     ps_line=`ps -ef | grep trace_pipe | grep adb `
    141     if [ $? == 0 ]; then
    142         echo Killing `echo $ps_line | awk '{s = ""; for (i=8; i <= NF ; i++) s = s $i " "; print s}' `
    143 	kill `echo $ps_line | awk '{print $2}' `
    144     fi
    145     ps_line=`ps -ef | grep strace | grep adb `
    146     if [ $? == 0 ]; then
    147         echo Killing `echo $ps_line | awk '{s = ""; for (i=8; i <= NF ; i++) s = s $i " "; print s}' `
    148 	kill `echo $ps_line | awk '{print $2}' `
    149     fi
    150 }
    151 
    152 catch_sigint()
    153 {
    154     echo "signal INT received, killing streaming trace capture"
    155     kill_traces
    156 }
    157 
    158 # main() starts here
    159 
    160 adb root && adb wait-for-device
    161 
    162 enable_tracepoints
    163 
    164 trap 'catch_sigint' INT
    165 
    166 adb shell 'ps' | grep zygote > zygote_pids
    167 fgrep -v grep zygote_pids > bar
    168 mv bar zygote_pids
    169 pid1=`grep -w zygote zygote_pids | awk '{print $2}' `
    170 pid2=`grep -w zygote64 zygote_pids | awk '{print $2}' `
    171 rm -f zygote_pids
    172 
    173 adb shell "date +%s > /data/local/tmp/trace.begin ; strace -p $pid1,$pid2 -o /data/local/tmp/trace -q -qq -f -ff -y -ttt -e trace=mmap2,read,write,pread64,pwrite64,fsync,fdatasync,openat,close,lseek,_llseek" &
    174 adb shell "cat /sys/kernel/debug/tracing/trace_pipe" > fstrace &
    175 
    176 echo "^C this when done with the test"
    177 
    178 wait
    179 
    180 adb shell 'monkey -p com.android.alarmclock -p com.android.chrome -p com.android.calculator -p com.android.calendar -p com.google.android.calendar -p com.google.android.camera -p com.android.contacts -p com.google.android.gm -p com.android.im -p com.android.launcher -p com.google.android.apps.maps -p com.android.mms -p com.google.android.music -p com.android.phone -p com.google.android.youtube -p com.android.email -p com.google.android.voicesearch -c android.intent.category.LAUNCHER --throttle 200 --ignore-security-exceptions --ignore-crashes --ignore-timeouts -v -v -v 25000'
    181 
    182 kill_traces
    183 
    184 disable_tracepoints
    185 
    186 rm -f trace.*
    187 rm -f fstrace.*
    188 rm -f *.wl
    189 rm -f parsed*
    190 
    191 # Get the tracefiles from the device
    192 adb shell 'cd /data/local/tmp ; tar cvf trace.tar trace.*'
    193 adb pull /data/local/tmp/trace.tar
    194 tar xf trace.tar
    195 
    196 # Pre-process the ftrace file
    197 prep_fstrace fstrace
    198 # Merge the ftrace file(s) with the strace files
    199 merge_compile
    200 
    201 # tar up the .wl files just created
    202 tar cf wl.tar ioshark_filenames *.wl
    203