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