• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/bash
2#
3# Copyright 2016 Google Inc. All Rights Reserved.
4#
5# This is an example script to show users the steps for bisecting an NDK
6# application for Android. Our example is the Teapot app that comes bundled with
7# the NDK as a sample app.
8#
9# Our Teapot app only has 12 or so object files generated per build. Bisection
10# for just 12 object files is overkill, but this bisection process easily scales
11# to thousands of object files (as seen with the Android source).
12#
13# Setup:
14#   1. Install NDK (make sure it is in your PATH)
15#   2. Install compiler_wrapper.py
16#   3. Connect an arm7 device (tested with Nexus 5X)
17#     a. See README for supporting other device archs
18#
19# Tested in bash on Linux.
20
21# Set CWD to where this script lives
22pushd "$(dirname "$0")"
23
24# If Teapot dir already exists remove it.
25if [[ -d Teapot ]]; then
26  rm -rf Teapot
27fi
28
29# Unzip our repository we'll be testing with.
30tar -xzf Teapot.tar.gz
31
32# Apply small setup patch. This patch makes a small change to the build system
33# to make this bisecting example a little easier. It inserts the option to only
34# build for an arm7. See the patch file for details.
35# (This patch file was generated with git, -p1 will remove the a/ and b/)
36patch -p1 -i PATCH1
37
38# We want all of our cached files to be stored in ~/NDK_EXAMPLE_BISECT
39# Remove directory if already exists
40export BISECT_DIR=~/NDK_EXAMPLE_BISECT
41if [[ -d ${BISECT_DIR} ]]; then
42  rm -rf ${BISECT_DIR}
43fi
44
45# We will now take our normal "good compiler" and do a full build of the app. We
46# need to clean before building. This ensures that all objects are generated and
47# can be cached.
48pushd Teapot
49export BISECT_STAGE=POPULATE_GOOD
50./gradlew clean
51./gradlew installArm7Debug
52popd
53
54# Inserting "compiler error". Really this is just a patch that inserts a simple
55# error in the code, but this is used to simulate our compiler error. This patch
56# will simply cause the app to crash as soon as it starts. See the patch file
57# for details.
58# (This patch file was generated with git, -p1 will remove the a/ and b/)
59patch -p1 -i PATCH2
60
61# Now that we have installed our bad compiler (i.e. applied the above patch that
62# acts like a compiler error), we want to enumerate and cache all objects
63# generated by this "bad compiler". So again, we clean the build tree so that
64# all objects are regenerated and can be cached.
65pushd Teapot
66export BISECT_STAGE=POPULATE_BAD
67./gradlew clean
68./gradlew installArm7Debug
69popd
70
71# Now ~/NDK_EXAMPLE_BISECT holds the caches for both good and bad compiler
72# outputs. We will now use these to bisect our problem. We should find that
73# TeapotRenderer.o is the bad file (because this is where PATCH2 inserted the
74# "compiler error").
75
76# Tell the compiler wrapper to not cache outputs, and instead begin bisecting.
77export BISECT_STAGE=TRIAGE
78
79# Run the actual bisection tool. This will automatically narrow down which
80# object file has the error. The test_setup.sh script will rebuild our app
81# with gradle, and boot_test.sh will ping the device to see if the app crashed
82# or not.
83cd ..
84./binary_search_state.py \
85  --get_initial_items=ndk/get_initial_items.sh \
86  --switch_to_good=ndk/switch_to_good.sh \
87  --switch_to_bad=ndk/switch_to_bad.sh \
88  --test_setup_script=ndk/test_setup.sh \
89  --test_script=ndk/boot_test.sh \
90  --file_args
91
92popd
93