xref: /aosp_15_r20/art/tools/runtime_memusage/sanitizer_logcat_analysis.sh (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker#!/bin/bash
2*795d594fSAndroid Build Coastguard Worker#
3*795d594fSAndroid Build Coastguard Worker# Copyright (C) 2017 The Android Open Source Project
4*795d594fSAndroid Build Coastguard Worker#
5*795d594fSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
6*795d594fSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
7*795d594fSAndroid Build Coastguard Worker# You may obtain a copy of the License at
8*795d594fSAndroid Build Coastguard Worker#
9*795d594fSAndroid Build Coastguard Worker#      http://www.apache.org/licenses/LICENSE-2.0
10*795d594fSAndroid Build Coastguard Worker#
11*795d594fSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
12*795d594fSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
13*795d594fSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*795d594fSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
15*795d594fSAndroid Build Coastguard Worker# limitations under the License.
16*795d594fSAndroid Build Coastguard Worker#
17*795d594fSAndroid Build Coastguard Worker# Note: Requires $ANDROID_BUILD_TOP/build/envsetup.sh to have been run.
18*795d594fSAndroid Build Coastguard Worker#
19*795d594fSAndroid Build Coastguard Worker# This script takes in a logcat containing Sanitizer traces and outputs several
20*795d594fSAndroid Build Coastguard Worker# files, prints information regarding the traces, and plots information as well.
21*795d594fSAndroid Build Coastguard WorkerALL_PIDS=false
22*795d594fSAndroid Build Coastguard WorkerUSE_TEMP=true
23*795d594fSAndroid Build Coastguard WorkerDO_REDO=false
24*795d594fSAndroid Build Coastguard WorkerPACKAGE_NAME=""
25*795d594fSAndroid Build Coastguard WorkerBAKSMALI_NUM=0
26*795d594fSAndroid Build Coastguard Worker# EXACT_ARG and MIN_ARG are passed to prune_sanitizer_output.py
27*795d594fSAndroid Build Coastguard WorkerEXACT_ARG=""
28*795d594fSAndroid Build Coastguard WorkerMIN_ARG=()
29*795d594fSAndroid Build Coastguard WorkerOFFSET_ARGS=()
30*795d594fSAndroid Build Coastguard WorkerTIME_ARGS=()
31*795d594fSAndroid Build Coastguard Workerusage() {
32*795d594fSAndroid Build Coastguard Worker  echo "Usage: $0 [options] [LOGCAT_FILE] [CATEGORIES...]"
33*795d594fSAndroid Build Coastguard Worker  echo "    -a"
34*795d594fSAndroid Build Coastguard Worker  echo "        Forces all pids associated with registered dex"
35*795d594fSAndroid Build Coastguard Worker  echo "        files in the logcat to be processed."
36*795d594fSAndroid Build Coastguard Worker  echo "        default: only the last pid is processed"
37*795d594fSAndroid Build Coastguard Worker  echo
38*795d594fSAndroid Build Coastguard Worker  echo "    -b  [DEX_FILE_NUMBER]"
39*795d594fSAndroid Build Coastguard Worker  echo "        Outputs data for the specified baksmali"
40*795d594fSAndroid Build Coastguard Worker  echo "        dump if -p is provided."
41*795d594fSAndroid Build Coastguard Worker  echo "        default: first baksmali dump in order of dex"
42*795d594fSAndroid Build Coastguard Worker  echo "          file registration"
43*795d594fSAndroid Build Coastguard Worker  echo
44*795d594fSAndroid Build Coastguard Worker  echo "    -d  OUT_DIRECTORY"
45*795d594fSAndroid Build Coastguard Worker  echo "        Puts all output in specified directory."
46*795d594fSAndroid Build Coastguard Worker  echo "        If not given, output will be put in a local"
47*795d594fSAndroid Build Coastguard Worker  echo "        temp folder which will be deleted after"
48*795d594fSAndroid Build Coastguard Worker  echo "        execution."
49*795d594fSAndroid Build Coastguard Worker  echo
50*795d594fSAndroid Build Coastguard Worker  echo "    -e"
51*795d594fSAndroid Build Coastguard Worker  echo "        All traces will have exactly the same number"
52*795d594fSAndroid Build Coastguard Worker  echo "        of categories which is specified by either"
53*795d594fSAndroid Build Coastguard Worker  echo "        the -m argument or by prune_sanitizer_output.py"
54*795d594fSAndroid Build Coastguard Worker  echo
55*795d594fSAndroid Build Coastguard Worker  echo "    -f"
56*795d594fSAndroid Build Coastguard Worker  echo "        Forces redo of all commands even if output"
57*795d594fSAndroid Build Coastguard Worker  echo "        files exist. Steps are skipped if their output"
58*795d594fSAndroid Build Coastguard Worker  echo "        exist already and this is not enabled."
59*795d594fSAndroid Build Coastguard Worker  echo
60*795d594fSAndroid Build Coastguard Worker  echo "    -m  [MINIMUM_CALLS_PER_TRACE]"
61*795d594fSAndroid Build Coastguard Worker  echo "        Filters out all traces that do not have"
62*795d594fSAndroid Build Coastguard Worker  echo "        at least MINIMUM_CALLS_PER_TRACE lines."
63*795d594fSAndroid Build Coastguard Worker  echo "        default: specified by prune_sanitizer_output.py"
64*795d594fSAndroid Build Coastguard Worker  echo
65*795d594fSAndroid Build Coastguard Worker  echo "    -o  [OFFSET],[OFFSET]"
66*795d594fSAndroid Build Coastguard Worker  echo "        Filters out all Dex File offsets outside the"
67*795d594fSAndroid Build Coastguard Worker  echo "        range between provided offsets. 'inf' can be"
68*795d594fSAndroid Build Coastguard Worker  echo "        provided for infinity."
69*795d594fSAndroid Build Coastguard Worker  echo "        default: 0,inf"
70*795d594fSAndroid Build Coastguard Worker  echo
71*795d594fSAndroid Build Coastguard Worker  echo "    -p  [PACKAGE_NAME]"
72*795d594fSAndroid Build Coastguard Worker  echo "        Using the package name, uses baksmali to get"
73*795d594fSAndroid Build Coastguard Worker  echo "        a dump of the Dex File format for the package."
74*795d594fSAndroid Build Coastguard Worker  echo
75*795d594fSAndroid Build Coastguard Worker  echo "    -t  [TIME_OFFSET],[TIME_OFFSET]"
76*795d594fSAndroid Build Coastguard Worker  echo "        Filters out all time offsets outside the"
77*795d594fSAndroid Build Coastguard Worker  echo "        range between provided offsets. 'inf' can be"
78*795d594fSAndroid Build Coastguard Worker  echo "        provided for infinity."
79*795d594fSAndroid Build Coastguard Worker  echo "        default: 0,inf"
80*795d594fSAndroid Build Coastguard Worker  echo
81*795d594fSAndroid Build Coastguard Worker  echo "    CATEGORIES are words that are expected to show in"
82*795d594fSAndroid Build Coastguard Worker  echo "       a large subset of symbolized traces. Splits"
83*795d594fSAndroid Build Coastguard Worker  echo "       output based on each word."
84*795d594fSAndroid Build Coastguard Worker  echo
85*795d594fSAndroid Build Coastguard Worker  echo "    LOGCAT_FILE is the piped output from adb logcat."
86*795d594fSAndroid Build Coastguard Worker  echo
87*795d594fSAndroid Build Coastguard Worker}
88*795d594fSAndroid Build Coastguard Worker
89*795d594fSAndroid Build Coastguard Worker
90*795d594fSAndroid Build Coastguard Workerwhile getopts ":ab:d:efm:o:p:t:" opt ; do
91*795d594fSAndroid Build Coastguard Workercase ${opt} in
92*795d594fSAndroid Build Coastguard Worker  a)
93*795d594fSAndroid Build Coastguard Worker    ALL_PIDS=true
94*795d594fSAndroid Build Coastguard Worker    ;;
95*795d594fSAndroid Build Coastguard Worker  b)
96*795d594fSAndroid Build Coastguard Worker    if ! [[ "$OPTARG" -eq "$OPTARG" ]]; then
97*795d594fSAndroid Build Coastguard Worker      usage
98*795d594fSAndroid Build Coastguard Worker      exit
99*795d594fSAndroid Build Coastguard Worker    fi
100*795d594fSAndroid Build Coastguard Worker    BAKSMALI_NUM=$OPTARG
101*795d594fSAndroid Build Coastguard Worker    ;;
102*795d594fSAndroid Build Coastguard Worker  d)
103*795d594fSAndroid Build Coastguard Worker    USE_TEMP=false
104*795d594fSAndroid Build Coastguard Worker    OUT_DIR=$OPTARG
105*795d594fSAndroid Build Coastguard Worker    ;;
106*795d594fSAndroid Build Coastguard Worker  e)
107*795d594fSAndroid Build Coastguard Worker    EXACT_ARG='-e'
108*795d594fSAndroid Build Coastguard Worker    ;;
109*795d594fSAndroid Build Coastguard Worker  f)
110*795d594fSAndroid Build Coastguard Worker    DO_REDO=true
111*795d594fSAndroid Build Coastguard Worker    ;;
112*795d594fSAndroid Build Coastguard Worker  m)
113*795d594fSAndroid Build Coastguard Worker    if ! [[ "$OPTARG" -eq "$OPTARG" ]]; then
114*795d594fSAndroid Build Coastguard Worker      usage
115*795d594fSAndroid Build Coastguard Worker      exit
116*795d594fSAndroid Build Coastguard Worker    fi
117*795d594fSAndroid Build Coastguard Worker    MIN_ARG=( "-m" "$OPTARG" )
118*795d594fSAndroid Build Coastguard Worker    ;;
119*795d594fSAndroid Build Coastguard Worker  o)
120*795d594fSAndroid Build Coastguard Worker    set -f
121*795d594fSAndroid Build Coastguard Worker    old_ifs=$IFS
122*795d594fSAndroid Build Coastguard Worker    IFS=","
123*795d594fSAndroid Build Coastguard Worker    OFFSET_ARGS=( $OPTARG )
124*795d594fSAndroid Build Coastguard Worker    if [[ "${#OFFSET_ARGS[@]}" -ne 2 ]]; then
125*795d594fSAndroid Build Coastguard Worker      usage
126*795d594fSAndroid Build Coastguard Worker      exit
127*795d594fSAndroid Build Coastguard Worker    fi
128*795d594fSAndroid Build Coastguard Worker    OFFSET_ARGS=( "--offsets" "${OFFSET_ARGS[@]}" )
129*795d594fSAndroid Build Coastguard Worker    IFS=$old_ifs
130*795d594fSAndroid Build Coastguard Worker    set +f
131*795d594fSAndroid Build Coastguard Worker    ;;
132*795d594fSAndroid Build Coastguard Worker  t)
133*795d594fSAndroid Build Coastguard Worker    set -f
134*795d594fSAndroid Build Coastguard Worker    old_ifs=$IFS
135*795d594fSAndroid Build Coastguard Worker    IFS=","
136*795d594fSAndroid Build Coastguard Worker    TIME_ARGS=( $OPTARG )
137*795d594fSAndroid Build Coastguard Worker    if [[ "${#TIME_ARGS[@]}" -ne 2 ]]; then
138*795d594fSAndroid Build Coastguard Worker      usage
139*795d594fSAndroid Build Coastguard Worker      exit
140*795d594fSAndroid Build Coastguard Worker    fi
141*795d594fSAndroid Build Coastguard Worker    TIME_ARGS=( "--times" "${TIME_ARGS[@]}" )
142*795d594fSAndroid Build Coastguard Worker    IFS=$old_ifs
143*795d594fSAndroid Build Coastguard Worker    set +f
144*795d594fSAndroid Build Coastguard Worker    ;;
145*795d594fSAndroid Build Coastguard Worker  p)
146*795d594fSAndroid Build Coastguard Worker    PACKAGE_NAME=$OPTARG
147*795d594fSAndroid Build Coastguard Worker    ;;
148*795d594fSAndroid Build Coastguard Worker  \?)
149*795d594fSAndroid Build Coastguard Worker    usage
150*795d594fSAndroid Build Coastguard Worker    exit
151*795d594fSAndroid Build Coastguard Workeresac
152*795d594fSAndroid Build Coastguard Workerdone
153*795d594fSAndroid Build Coastguard Workershift $((OPTIND -1))
154*795d594fSAndroid Build Coastguard Worker
155*795d594fSAndroid Build Coastguard Workerif [[ $# -lt 1 ]]; then
156*795d594fSAndroid Build Coastguard Worker  usage
157*795d594fSAndroid Build Coastguard Worker  exit
158*795d594fSAndroid Build Coastguard Workerfi
159*795d594fSAndroid Build Coastguard Worker
160*795d594fSAndroid Build Coastguard WorkerLOGCAT_FILE=$1
161*795d594fSAndroid Build Coastguard WorkerNUM_CAT=$(($# - 1))
162*795d594fSAndroid Build Coastguard Worker
163*795d594fSAndroid Build Coastguard Worker# Use a temp directory that will be deleted
164*795d594fSAndroid Build Coastguard Workerif [[ $USE_TEMP = true ]]; then
165*795d594fSAndroid Build Coastguard Worker  OUT_DIR=$(mktemp -d --tmpdir="$PWD")
166*795d594fSAndroid Build Coastguard Worker  DO_REDO=true
167*795d594fSAndroid Build Coastguard Workerfi
168*795d594fSAndroid Build Coastguard Worker
169*795d594fSAndroid Build Coastguard Workerif [[ ! -d "$OUT_DIR" ]]; then
170*795d594fSAndroid Build Coastguard Worker  mkdir "$OUT_DIR"
171*795d594fSAndroid Build Coastguard Worker  DO_REDO=true
172*795d594fSAndroid Build Coastguard Workerfi
173*795d594fSAndroid Build Coastguard Worker
174*795d594fSAndroid Build Coastguard Worker# Note: Steps are skipped if their output exists until -f flag is enabled
175*795d594fSAndroid Build Coastguard Workerecho "Output folder: $OUT_DIR"
176*795d594fSAndroid Build Coastguard Worker# Finds the lines matching pattern criteria and prints out unique instances of
177*795d594fSAndroid Build Coastguard Worker# the 3rd word (PID)
178*795d594fSAndroid Build Coastguard Workerunique_pids=( $(awk '/RegisterDexFile:/ && !/zygote/ {if(!a[$3]++) print $3}' \
179*795d594fSAndroid Build Coastguard Worker  "$LOGCAT_FILE") )
180*795d594fSAndroid Build Coastguard Workerecho "List of pids: ${unique_pids[@]}"
181*795d594fSAndroid Build Coastguard Workerif [[ $ALL_PIDS = false ]]; then
182*795d594fSAndroid Build Coastguard Worker  unique_pids=( ${unique_pids[-1]} )
183*795d594fSAndroid Build Coastguard Workerfi
184*795d594fSAndroid Build Coastguard Worker
185*795d594fSAndroid Build Coastguard Workerfor pid in "${unique_pids[@]}"
186*795d594fSAndroid Build Coastguard Workerdo
187*795d594fSAndroid Build Coastguard Worker  echo
188*795d594fSAndroid Build Coastguard Worker  echo "Current pid: $pid"
189*795d594fSAndroid Build Coastguard Worker  echo
190*795d594fSAndroid Build Coastguard Worker  pid_dir=$OUT_DIR/$pid
191*795d594fSAndroid Build Coastguard Worker  if [[ ! -d "$pid_dir" ]]; then
192*795d594fSAndroid Build Coastguard Worker    mkdir "$pid_dir"
193*795d594fSAndroid Build Coastguard Worker    DO_REDO[$pid]=true
194*795d594fSAndroid Build Coastguard Worker  fi
195*795d594fSAndroid Build Coastguard Worker
196*795d594fSAndroid Build Coastguard Worker  intermediates_dir=$pid_dir/intermediates
197*795d594fSAndroid Build Coastguard Worker  results_dir=$pid_dir/results
198*795d594fSAndroid Build Coastguard Worker  logcat_pid_file=$pid_dir/logcat
199*795d594fSAndroid Build Coastguard Worker
200*795d594fSAndroid Build Coastguard Worker  if [[ ! -f "$logcat_pid_file" ]] || \
201*795d594fSAndroid Build Coastguard Worker     [[ "${DO_REDO[$pid]}" = true ]] || \
202*795d594fSAndroid Build Coastguard Worker     [[ $DO_REDO = true ]]; then
203*795d594fSAndroid Build Coastguard Worker    DO_REDO[$pid]=true
204*795d594fSAndroid Build Coastguard Worker    awk "{if(\$3 == $pid) print \$0}" "$LOGCAT_FILE" > "$logcat_pid_file"
205*795d594fSAndroid Build Coastguard Worker  fi
206*795d594fSAndroid Build Coastguard Worker
207*795d594fSAndroid Build Coastguard Worker  if [[ ! -d "$intermediates_dir" ]]; then
208*795d594fSAndroid Build Coastguard Worker    mkdir "$intermediates_dir"
209*795d594fSAndroid Build Coastguard Worker    DO_REDO[$pid]=true
210*795d594fSAndroid Build Coastguard Worker  fi
211*795d594fSAndroid Build Coastguard Worker
212*795d594fSAndroid Build Coastguard Worker  # Step 1 - Only output lines related to Sanitizer
213*795d594fSAndroid Build Coastguard Worker  # Folder that holds all file output
214*795d594fSAndroid Build Coastguard Worker  asan_out=$intermediates_dir/asan_output
215*795d594fSAndroid Build Coastguard Worker  if [[ ! -f "$asan_out" ]] || \
216*795d594fSAndroid Build Coastguard Worker     [[ "${DO_REDO[$pid]}" = true ]] || \
217*795d594fSAndroid Build Coastguard Worker     [[ $DO_REDO = true ]]; then
218*795d594fSAndroid Build Coastguard Worker    DO_REDO[$pid]=true
219*795d594fSAndroid Build Coastguard Worker    echo "Extracting ASAN output"
220*795d594fSAndroid Build Coastguard Worker    grep "app_process64" "$logcat_pid_file" > "$asan_out"
221*795d594fSAndroid Build Coastguard Worker  else
222*795d594fSAndroid Build Coastguard Worker    echo "Skipped: Extracting ASAN output"
223*795d594fSAndroid Build Coastguard Worker  fi
224*795d594fSAndroid Build Coastguard Worker
225*795d594fSAndroid Build Coastguard Worker  # Step 2 - Only output lines containing Dex File Start Addresses
226*795d594fSAndroid Build Coastguard Worker  dex_start=$intermediates_dir/dex_start
227*795d594fSAndroid Build Coastguard Worker  if [[ ! -f "$dex_start" ]] || \
228*795d594fSAndroid Build Coastguard Worker     [[ "${DO_REDO[$pid]}" = true ]] || \
229*795d594fSAndroid Build Coastguard Worker     [[ $DO_REDO = true ]]; then
230*795d594fSAndroid Build Coastguard Worker    DO_REDO[$pid]=true
231*795d594fSAndroid Build Coastguard Worker    echo "Extracting Start of Dex File(s)"
232*795d594fSAndroid Build Coastguard Worker    if [[ ! -z "$PACKAGE_NAME" ]]; then
233*795d594fSAndroid Build Coastguard Worker      awk '/RegisterDexFile:/ && /'"$PACKAGE_NAME"'/ && /\/data\/app/' \
234*795d594fSAndroid Build Coastguard Worker        "$logcat_pid_file" > "$dex_start"
235*795d594fSAndroid Build Coastguard Worker    else
236*795d594fSAndroid Build Coastguard Worker      grep "RegisterDexFile:" "$logcat_pid_file" > "$dex_start"
237*795d594fSAndroid Build Coastguard Worker    fi
238*795d594fSAndroid Build Coastguard Worker  else
239*795d594fSAndroid Build Coastguard Worker    echo "Skipped: Extracting Start of Dex File(s)"
240*795d594fSAndroid Build Coastguard Worker  fi
241*795d594fSAndroid Build Coastguard Worker
242*795d594fSAndroid Build Coastguard Worker  # Step 3 - Clean Sanitizer output from Step 2 since logcat cannot
243*795d594fSAndroid Build Coastguard Worker  # handle large amounts of output.
244*795d594fSAndroid Build Coastguard Worker  asan_out_filtered=$intermediates_dir/asan_output_filtered
245*795d594fSAndroid Build Coastguard Worker  if [[ ! -f "$asan_out_filtered" ]] || \
246*795d594fSAndroid Build Coastguard Worker     [[ "${DO_REDO[$pid]}" = true ]] || \
247*795d594fSAndroid Build Coastguard Worker     [[ $DO_REDO = true ]]; then
248*795d594fSAndroid Build Coastguard Worker    DO_REDO[$pid]=true
249*795d594fSAndroid Build Coastguard Worker    echo "Filtering/Cleaning ASAN output"
250*795d594fSAndroid Build Coastguard Worker    python "$ANDROID_BUILD_TOP"/art/tools/runtime_memusage/prune_sanitizer_output.py \
251*795d594fSAndroid Build Coastguard Worker      "$EXACT_ARG" "${MIN_ARG[@]}" -d "$intermediates_dir" "$asan_out"
252*795d594fSAndroid Build Coastguard Worker  else
253*795d594fSAndroid Build Coastguard Worker    echo "Skipped: Filtering/Cleaning ASAN output"
254*795d594fSAndroid Build Coastguard Worker  fi
255*795d594fSAndroid Build Coastguard Worker
256*795d594fSAndroid Build Coastguard Worker  # Step 4 - Retrieve symbolized stack traces from Step 3 output
257*795d594fSAndroid Build Coastguard Worker  sym_filtered=$intermediates_dir/sym_filtered
258*795d594fSAndroid Build Coastguard Worker  if [[ ! -f "$sym_filtered" ]] || \
259*795d594fSAndroid Build Coastguard Worker     [[ "${DO_REDO[$pid]}" = true ]] || \
260*795d594fSAndroid Build Coastguard Worker     [[ $DO_REDO = true ]]; then
261*795d594fSAndroid Build Coastguard Worker    DO_REDO[$pid]=true
262*795d594fSAndroid Build Coastguard Worker    echo "Retrieving symbolized traces"
263*795d594fSAndroid Build Coastguard Worker    "$ANDROID_BUILD_TOP"/development/scripts/stack "$asan_out_filtered" \
264*795d594fSAndroid Build Coastguard Worker      > "$sym_filtered"
265*795d594fSAndroid Build Coastguard Worker  else
266*795d594fSAndroid Build Coastguard Worker    echo "Skipped: Retrieving symbolized traces"
267*795d594fSAndroid Build Coastguard Worker  fi
268*795d594fSAndroid Build Coastguard Worker
269*795d594fSAndroid Build Coastguard Worker  # Step 4.5 - Obtain Dex File Format of dex file related to package
270*795d594fSAndroid Build Coastguard Worker  filtered_dex_start=$intermediates_dir/filtered_dex_start
271*795d594fSAndroid Build Coastguard Worker  baksmali_dmp_ctr=0
272*795d594fSAndroid Build Coastguard Worker  baksmali_dmp_prefix=$intermediates_dir"/baksmali_dex_file_"
273*795d594fSAndroid Build Coastguard Worker  baksmali_dmp_files=( $baksmali_dmp_prefix* )
274*795d594fSAndroid Build Coastguard Worker  baksmali_dmp_arg="--dex-file "${baksmali_dmp_files[$BAKSMALI_NUM]}
275*795d594fSAndroid Build Coastguard Worker  apk_dex_files=( )
276*795d594fSAndroid Build Coastguard Worker  if [[ ! -f "$baksmali_dmp_prefix""$BAKSMALI_NUM" ]] || \
277*795d594fSAndroid Build Coastguard Worker     [[ ! -f "$filtered_dex_start" ]] || \
278*795d594fSAndroid Build Coastguard Worker     [[ "${DO_REDO[$pid]}" = true ]] || \
279*795d594fSAndroid Build Coastguard Worker     [[ $DO_REDO = true ]]; then
280*795d594fSAndroid Build Coastguard Worker    if [[ ! -z "$PACKAGE_NAME" ]]; then
281*795d594fSAndroid Build Coastguard Worker      DO_REDO[$pid]=true
282*795d594fSAndroid Build Coastguard Worker      # Extracting Dex File path on device from Dex File related to package
283*795d594fSAndroid Build Coastguard Worker      apk_directory=$(dirname "$(tail -n1 "$dex_start" | awk "{print \$8}")")
284*795d594fSAndroid Build Coastguard Worker      for dex_file in $(awk "{print \$8}" "$dex_start"); do
285*795d594fSAndroid Build Coastguard Worker        apk_dex_files+=( $(basename "$dex_file") )
286*795d594fSAndroid Build Coastguard Worker      done
287*795d594fSAndroid Build Coastguard Worker      apk_oat_files=$(adb shell find "$apk_directory" -name "*.?dex" -type f \
288*795d594fSAndroid Build Coastguard Worker        2> /dev/null)
289*795d594fSAndroid Build Coastguard Worker      # Pulls the .odex and .vdex files associated with the package
290*795d594fSAndroid Build Coastguard Worker      for apk_file in $apk_oat_files; do
291*795d594fSAndroid Build Coastguard Worker        base_name=$(basename "$apk_file")
292*795d594fSAndroid Build Coastguard Worker        adb pull "$apk_file" "$intermediates_dir/base.${base_name#*.}"
293*795d594fSAndroid Build Coastguard Worker      done
294*795d594fSAndroid Build Coastguard Worker      oatdump --oat-file="$intermediates_dir"/base.odex \
295*795d594fSAndroid Build Coastguard Worker        --export-dex-to="$intermediates_dir" --output=/dev/null
296*795d594fSAndroid Build Coastguard Worker      for dex_file in "${apk_dex_files[@]}"; do
297*795d594fSAndroid Build Coastguard Worker        exported_dex_file=$intermediates_dir/$dex_file"_export.dex"
298*795d594fSAndroid Build Coastguard Worker        baksmali_dmp_out="$baksmali_dmp_prefix""$((baksmali_dmp_ctr++))"
299*795d594fSAndroid Build Coastguard Worker        baksmali -JXmx1024M dump "$exported_dex_file" \
300*795d594fSAndroid Build Coastguard Worker          > "$baksmali_dmp_out" 2> "$intermediates_dir"/error
301*795d594fSAndroid Build Coastguard Worker        if ! [[ -s "$baksmali_dmp_out" ]]; then
302*795d594fSAndroid Build Coastguard Worker          rm "$baksmali_dmp_prefix"*
303*795d594fSAndroid Build Coastguard Worker          baksmali_dmp_arg=""
304*795d594fSAndroid Build Coastguard Worker          echo "Failed to retrieve Dex File format"
305*795d594fSAndroid Build Coastguard Worker          break
306*795d594fSAndroid Build Coastguard Worker        fi
307*795d594fSAndroid Build Coastguard Worker      done
308*795d594fSAndroid Build Coastguard Worker      baksmali_dmp_files=( "$baksmali_dmp_prefix"* )
309*795d594fSAndroid Build Coastguard Worker      baksmali_dmp_arg="--dex-file "${baksmali_dmp_files[$BAKSMALI_NUM]}
310*795d594fSAndroid Build Coastguard Worker      # Gets the baksmali dump associated with BAKSMALI_NUM
311*795d594fSAndroid Build Coastguard Worker      awk "NR == $((BAKSMALI_NUM + 1))" "$dex_start" > "$filtered_dex_start"
312*795d594fSAndroid Build Coastguard Worker      results_dir=$results_dir"_"$BAKSMALI_NUM
313*795d594fSAndroid Build Coastguard Worker      echo "Skipped: Retrieving Dex File format from baksmali; no package given"
314*795d594fSAndroid Build Coastguard Worker    else
315*795d594fSAndroid Build Coastguard Worker      cp "$dex_start" "$filtered_dex_start"
316*795d594fSAndroid Build Coastguard Worker      baksmali_dmp_arg=""
317*795d594fSAndroid Build Coastguard Worker    fi
318*795d594fSAndroid Build Coastguard Worker  else
319*795d594fSAndroid Build Coastguard Worker    awk "NR == $((BAKSMALI_NUM + 1))" "$dex_start" > "$filtered_dex_start"
320*795d594fSAndroid Build Coastguard Worker    results_dir=$results_dir"_"$BAKSMALI_NUM
321*795d594fSAndroid Build Coastguard Worker    echo "Skipped: Retrieving Dex File format from baksmali"
322*795d594fSAndroid Build Coastguard Worker  fi
323*795d594fSAndroid Build Coastguard Worker
324*795d594fSAndroid Build Coastguard Worker  if [[ ! -d "$results_dir" ]]; then
325*795d594fSAndroid Build Coastguard Worker    mkdir "$results_dir"
326*795d594fSAndroid Build Coastguard Worker    DO_REDO[$pid]=true
327*795d594fSAndroid Build Coastguard Worker  fi
328*795d594fSAndroid Build Coastguard Worker
329*795d594fSAndroid Build Coastguard Worker  # Step 5 - Using Steps 2, 3, 4 outputs in order to output graph data
330*795d594fSAndroid Build Coastguard Worker  # and trace data
331*795d594fSAndroid Build Coastguard Worker  # Only the category names are needed for the commands giving final output
332*795d594fSAndroid Build Coastguard Worker  shift
333*795d594fSAndroid Build Coastguard Worker  time_output=($results_dir/time_output_*.dat)
334*795d594fSAndroid Build Coastguard Worker  if [[ ! -e ${time_output[0]} ]] || \
335*795d594fSAndroid Build Coastguard Worker     [[ "${DO_REDO[$pid]}" = true ]] || \
336*795d594fSAndroid Build Coastguard Worker     [[ $DO_REDO = true ]]; then
337*795d594fSAndroid Build Coastguard Worker    DO_REDO[$pid]=true
338*795d594fSAndroid Build Coastguard Worker    echo "Creating Categorized Time Table"
339*795d594fSAndroid Build Coastguard Worker    baksmali_dmp_args=( $baksmali_dmp_arg )
340*795d594fSAndroid Build Coastguard Worker    python "$ANDROID_BUILD_TOP"/art/tools/runtime_memusage/symbol_trace_info.py \
341*795d594fSAndroid Build Coastguard Worker      -d "$results_dir" "${OFFSET_ARGS[@]}" "${baksmali_dmp_args[@]}" \
342*795d594fSAndroid Build Coastguard Worker      "${TIME_ARGS[@]}" "$asan_out_filtered" "$sym_filtered" \
343*795d594fSAndroid Build Coastguard Worker      "$filtered_dex_start" "$@"
344*795d594fSAndroid Build Coastguard Worker  else
345*795d594fSAndroid Build Coastguard Worker    echo "Skipped: Creating Categorized Time Table"
346*795d594fSAndroid Build Coastguard Worker  fi
347*795d594fSAndroid Build Coastguard Worker
348*795d594fSAndroid Build Coastguard Worker  # Step 6 - Use graph data from Step 5 to plot graph
349*795d594fSAndroid Build Coastguard Worker  # Contains the category names used for legend of gnuplot
350*795d594fSAndroid Build Coastguard Worker  plot_cats="\"Uncategorized $*\""
351*795d594fSAndroid Build Coastguard Worker  package_string=""
352*795d594fSAndroid Build Coastguard Worker  dex_name=""
353*795d594fSAndroid Build Coastguard Worker  if [[ ! -z "$PACKAGE_NAME" ]]; then
354*795d594fSAndroid Build Coastguard Worker    package_string="Package name: $PACKAGE_NAME "
355*795d594fSAndroid Build Coastguard Worker  fi
356*795d594fSAndroid Build Coastguard Worker  if [[ ! -z "$baksmali_dmp_arg" ]]; then
357*795d594fSAndroid Build Coastguard Worker    dex_file_path="$(awk "{print \$8}" "$filtered_dex_start" | tail -n1)"
358*795d594fSAndroid Build Coastguard Worker    dex_name="Dex File name: $(basename "$dex_file_path") "
359*795d594fSAndroid Build Coastguard Worker  fi
360*795d594fSAndroid Build Coastguard Worker  echo "Plotting Categorized Time Table"
361*795d594fSAndroid Build Coastguard Worker  # Plots the information from logcat
362*795d594fSAndroid Build Coastguard Worker  gnuplot --persist -e \
363*795d594fSAndroid Build Coastguard Worker    'filename(n) = sprintf("'"$results_dir"'/time_output_%d.dat", n);
364*795d594fSAndroid Build Coastguard Worker     catnames = '"$plot_cats"';
365*795d594fSAndroid Build Coastguard Worker     set title "'"$package_string""$dex_name"'PID: '"$pid"'";
366*795d594fSAndroid Build Coastguard Worker     set xlabel "Time (milliseconds)";
367*795d594fSAndroid Build Coastguard Worker     set ylabel "Dex File Offset (bytes)";
368*795d594fSAndroid Build Coastguard Worker     plot for [i=0:'"$NUM_CAT"'] filename(i) using 1:2 title word(catnames, i + 1);'
369*795d594fSAndroid Build Coastguard Worker
370*795d594fSAndroid Build Coastguard Worker  if [[ $USE_TEMP = true ]]; then
371*795d594fSAndroid Build Coastguard Worker    echo "Removing temp directory and files"
372*795d594fSAndroid Build Coastguard Worker    rm -rf "$OUT_DIR"
373*795d594fSAndroid Build Coastguard Worker  fi
374*795d594fSAndroid Build Coastguard Workerdone
375