|
1 #!/bin/sh |
|
2 # Copyright (c) 2012 Google Inc. |
|
3 # All rights reserved. |
|
4 # |
|
5 # Redistribution and use in source and binary forms, with or without |
|
6 # modification, are permitted provided that the following conditions are |
|
7 # met: |
|
8 # |
|
9 # * Redistributions of source code must retain the above copyright |
|
10 # notice, this list of conditions and the following disclaimer. |
|
11 # * Redistributions in binary form must reproduce the above |
|
12 # copyright notice, this list of conditions and the following disclaimer |
|
13 # in the documentation and/or other materials provided with the |
|
14 # distribution. |
|
15 # * Neither the name of Google Inc. nor the names of its |
|
16 # contributors may be used to endorse or promote products derived from |
|
17 # this software without specific prior written permission. |
|
18 # |
|
19 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
20 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
21 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
22 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
23 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
24 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
25 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
26 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
27 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
28 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
30 |
|
31 # Sanitize the environment |
|
32 export LANG=C |
|
33 export LC_ALL=C |
|
34 |
|
35 if [ "$BASH_VERSION" ]; then |
|
36 set -o posix |
|
37 fi |
|
38 |
|
39 PROGDIR=$(dirname "$0") |
|
40 PROGDIR=$(cd "$PROGDIR" && pwd) |
|
41 PROGNAME=$(basename "$0") |
|
42 |
|
43 . $PROGDIR/common-functions.sh |
|
44 |
|
45 DEFAULT_ABI="armeabi" |
|
46 VALID_ABIS="armeabi armeabi-v7a x86 mips" |
|
47 |
|
48 ABI= |
|
49 ADB= |
|
50 ALL_TESTS= |
|
51 ENABLE_M32= |
|
52 HELP= |
|
53 HELP_ALL= |
|
54 NDK_DIR= |
|
55 NO_CLEANUP= |
|
56 NO_DEVICE= |
|
57 NUM_JOBS=$(get_core_count) |
|
58 TMPDIR= |
|
59 |
|
60 for opt do |
|
61 # The following extracts the value if the option is like --name=<value>. |
|
62 optarg=$(expr -- $opt : '^--[^=]*=\(.*\)$') |
|
63 case $opt in |
|
64 --abi=*) ABI=$optarg;; |
|
65 --adb=*) ADB=$optarg;; |
|
66 --all-tests) ALL_TESTS=true;; |
|
67 --enable-m32) ENABLE_M32=true;; |
|
68 --help|-h|-?) HELP=TRUE;; |
|
69 --help-all) HELP_ALL=true;; |
|
70 --jobs=*) NUM_JOBS=$optarg;; |
|
71 --ndk-dir=*) NDK_DIR=$optarg;; |
|
72 --tmp-dir=*) TMPDIR=$optarg;; |
|
73 --no-cleanup) NO_CLEANUP=true;; |
|
74 --no-device) NO_DEVICE=true;; |
|
75 --quiet) decrease_verbosity;; |
|
76 --verbose) increase_verbosity;; |
|
77 -*) panic "Invalid option '$opt', see --help for details.";; |
|
78 *) panic "This script doesn't take any parameters. See --help for details." |
|
79 ;; |
|
80 esac |
|
81 done |
|
82 |
|
83 if [ "$HELP" -o "$HELP_ALL" ]; then |
|
84 echo "\ |
|
85 Usage: $PROGNAME [options] |
|
86 |
|
87 This script is used to check that your Google Breakpad source tree can |
|
88 be properly built for Android, and that the client library and host tools |
|
89 work properly together. |
|
90 " |
|
91 if [ "$HELP_ALL" ]; then |
|
92 echo "\ |
|
93 In more details, this script will: |
|
94 |
|
95 - Rebuild the host version of Google Breakpad in a temporary |
|
96 directory (with the Auto-tools based build system). |
|
97 |
|
98 - Rebuild the Android client library with the Google Breakpad build |
|
99 system (using autotools/configure). This requires that you define |
|
100 ANDROID_NDK_ROOT in your environment to point to a valid Android NDK |
|
101 installation directory, or use the --ndk-dir=<path> option. |
|
102 |
|
103 - Rebuild the Android client library and a test crashing program with the |
|
104 Android NDK build system (ndk-build). |
|
105 |
|
106 - Require an Android device connected to your machine, and the 'adb' |
|
107 tool in your path. They are used to: |
|
108 |
|
109 - Install and run a test crashing program. |
|
110 - Extract the corresponding minidump from the device. |
|
111 - Dump the symbols from the test program on the host with 'dump_syms' |
|
112 - Generate a stack trace with 'minidump_stackwalk' |
|
113 - Check the stack trace content for valid source file locations. |
|
114 |
|
115 You can however skip this requirement and only test the builds by using |
|
116 the --no-device flag. |
|
117 |
|
118 By default, all generated files will be created in a temporary directory |
|
119 that is removed when the script completion. If you want to inspect the |
|
120 files, use the --no-cleanup option. |
|
121 |
|
122 Finally, use --verbose to increase the verbosity level, this will help |
|
123 you see which exact commands are being issues and their result. Use the |
|
124 flag twice for even more output. Use --quiet to decrease verbosity |
|
125 instead and run the script silently. |
|
126 |
|
127 If you have a device connected, the script will probe it to determine |
|
128 its primary CPU ABI, and build the test program for it. You can however |
|
129 use the --abi=<name> option to override this (this can be useful to check |
|
130 the secondary ABI, e.g. using --abi=armeabi to check that such a program |
|
131 works correctly on an ARMv7-A device). |
|
132 |
|
133 If you don't have a device connected, the test program will be built (but |
|
134 not run) with the default '$DEFAULT_ABI' ABI. Again, you can use |
|
135 --abi=<name> to override this. Valid ABI names are: |
|
136 |
|
137 $VALID_ABIS |
|
138 |
|
139 The script will only run the client library unit test on the device |
|
140 by default. You can use --all-tests to also build and run the unit |
|
141 tests for the Breakpad tools and processor, but be warned that this |
|
142 adds several minutes of testing time. --all-tests will also run the |
|
143 host unit tests suite. |
|
144 " |
|
145 |
|
146 fi # HELP_ALL |
|
147 |
|
148 echo "\ |
|
149 Valid options: |
|
150 |
|
151 --help|-h|-? Display this message. |
|
152 --help-all Display extended help. |
|
153 --enable-m32 Build 32-bit version of host tools. |
|
154 --abi=<name> Specify target CPU ABI [auto-detected]. |
|
155 --jobs=<count> Run <count> build tasks in parallel [$NUM_JOBS]. |
|
156 --ndk-dir=<path> Specify NDK installation directory. |
|
157 --tmp-dir=<path> Specify temporary directory (will be wiped-out). |
|
158 --adb=<path> Specify adb program path. |
|
159 --no-cleanup Don't remove temporary directory after completion. |
|
160 --no-device Do not try to detect devices, nor run crash test. |
|
161 --all-tests Run all unit tests (i.e. tools and processor ones too). |
|
162 --verbose Increase verbosity. |
|
163 --quiet Decrease verbosity." |
|
164 |
|
165 exit 0 |
|
166 fi |
|
167 |
|
168 TESTAPP_DIR=$PROGDIR/sample_app |
|
169 |
|
170 # Select NDK install directory. |
|
171 if [ -z "$NDK_DIR" ]; then |
|
172 if [ -z "$ANDROID_NDK_ROOT" ]; then |
|
173 panic "Please define ANDROID_NDK_ROOT in your environment, or use \ |
|
174 --ndk-dir=<path>." |
|
175 fi |
|
176 NDK_DIR="$ANDROID_NDK_ROOT" |
|
177 log "Found NDK directory: $NDK_DIR" |
|
178 else |
|
179 log "Using NDK directory: $NDK_DIR" |
|
180 fi |
|
181 # Small sanity check. |
|
182 NDK_BUILD="$NDK_DIR/ndk-build" |
|
183 if [ ! -f "$NDK_BUILD" ]; then |
|
184 panic "Your NDK directory is not valid (missing ndk-build): $NDK_DIR" |
|
185 fi |
|
186 |
|
187 # Ensure the temporary directory is deleted on exit, except if the --no-cleanup |
|
188 # option is used. |
|
189 |
|
190 clean_tmpdir () { |
|
191 if [ "$TMPDIR" ]; then |
|
192 if [ -z "$NO_CLEANUP" ]; then |
|
193 log "Cleaning up: $TMPDIR" |
|
194 rm -rf "$TMPDIR" |
|
195 else |
|
196 dump "Temporary directory contents preserved: $TMPDIR" |
|
197 fi |
|
198 fi |
|
199 exit "$@" |
|
200 } |
|
201 |
|
202 atexit clean_tmpdir |
|
203 |
|
204 # If --tmp-dir=<path> is not used, create a temporary directory. |
|
205 # Otherwise, start by cleaning up the user-provided path. |
|
206 if [ -z "$TMPDIR" ]; then |
|
207 TMPDIR=$(mktemp -d /tmp/$PROGNAME.XXXXXXXX) |
|
208 fail_panic "Can't create temporary directory!" |
|
209 log "Using temporary directory: $TMPDIR" |
|
210 else |
|
211 if [ ! -d "$TMPDIR" ]; then |
|
212 mkdir -p "$TMPDIR" |
|
213 fail_panic "Can't create temporary directory: $TMPDIR" |
|
214 else |
|
215 log "Cleaning up temporary directory: $TMPDIR" |
|
216 rm -rf "$TMPDIR"/* |
|
217 fail_panic "Cannot cleanup temporary directory!" |
|
218 fi |
|
219 fi |
|
220 |
|
221 if [ -z "$NO_DEVICE" ]; then |
|
222 if ! adb_check_device $ADB; then |
|
223 echo "$(adb_get_error)" |
|
224 echo "Use --no-device to build the code without running any tests." |
|
225 exit 1 |
|
226 fi |
|
227 fi |
|
228 |
|
229 BUILD_LOG="$TMPDIR/build.log" |
|
230 RUN_LOG="$TMPDIR/run.log" |
|
231 CRASH_LOG="$TMPDIR/crash.log" |
|
232 |
|
233 set_run_log "$RUN_LOG" |
|
234 |
|
235 TMPHOST="$TMPDIR/host-local" |
|
236 |
|
237 cd "$TMPDIR" |
|
238 |
|
239 # Build host version of the tools |
|
240 dump "Building host binaries." |
|
241 CONFIGURE_FLAGS= |
|
242 if [ "$ENABLE_M32" ]; then |
|
243 CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-m32" |
|
244 fi |
|
245 ( |
|
246 run mkdir "$TMPDIR/build-host" && |
|
247 run cd "$TMPDIR/build-host" && |
|
248 run2 "$PROGDIR/../configure" --prefix="$TMPHOST" $CONFIGURE_FLAGS && |
|
249 run2 make -j$NUM_JOBS install |
|
250 ) |
|
251 fail_panic "Can't build host binaries!" |
|
252 |
|
253 if [ "$ALL_TESTS" ]; then |
|
254 dump "Running host unit tests." |
|
255 ( |
|
256 run cd "$TMPDIR/build-host" && |
|
257 run2 make -j$NUM_JOBS check |
|
258 ) |
|
259 fail_panic "Host unit tests failed!!" |
|
260 fi |
|
261 |
|
262 TMPBIN=$TMPHOST/bin |
|
263 |
|
264 # Generate a stand-alone NDK toolchain |
|
265 |
|
266 # Extract CPU ABI and architecture from device, if any. |
|
267 if adb_check_device; then |
|
268 DEVICE_ABI=$(adb_shell getprop ro.product.cpu.abi) |
|
269 DEVICE_ABI2=$(adb_shell getprop ro.product.cpu.abi2) |
|
270 if [ -z "$DEVICE_ABI" ]; then |
|
271 panic "Can't extract ABI from connected device!" |
|
272 fi |
|
273 if [ "$DEVICE_ABI2" ]; then |
|
274 dump "Found device ABIs: $DEVICE_ABI $DEVICE_ABI2" |
|
275 else |
|
276 dump "Found device ABI: $DEVICE_ABI" |
|
277 DEVICE_ABI2=$DEVICE_ABI |
|
278 fi |
|
279 |
|
280 # If --abi=<name> is used, check that the device supports it. |
|
281 if [ "$ABI" -a "$DEVICE_ABI" != "$ABI" -a "$DEVICE_ABI2" != "$ABI" ]; then |
|
282 dump "ERROR: Device ABI(s) do not match --abi command-line value ($ABI)!" |
|
283 panic "Please use --no-device to skip device tests." |
|
284 fi |
|
285 |
|
286 if [ -z "$ABI" ]; then |
|
287 ABI=$DEVICE_ABI |
|
288 dump "Using CPU ABI: $ABI (device)" |
|
289 else |
|
290 dump "Using CPU ABI: $ABI (command-line)" |
|
291 fi |
|
292 else |
|
293 if [ -z "$ABI" ]; then |
|
294 # No device connected, choose default ABI |
|
295 ABI=$DEFAULT_ABI |
|
296 dump "Using CPU ABI: $ABI (default)" |
|
297 else |
|
298 dump "Using CPU ABI: $ABI (command-line)" |
|
299 fi |
|
300 fi |
|
301 |
|
302 # Check the ABI value |
|
303 VALID= |
|
304 for VALID_ABI in $VALID_ABIS; do |
|
305 if [ "$ABI" = "$VALID_ABI" ]; then |
|
306 VALID=true |
|
307 break |
|
308 fi |
|
309 done |
|
310 |
|
311 if [ -z "$VALID" ]; then |
|
312 panic "Unknown CPU ABI '$ABI'. Valid values are: $VALID_ABIS" |
|
313 fi |
|
314 |
|
315 # Extract architecture name from ABI |
|
316 case $ABI in |
|
317 armeabi*) ARCH=arm;; |
|
318 *) ARCH=$ABI;; |
|
319 esac |
|
320 |
|
321 # Extract GNU configuration name |
|
322 case $ARCH in |
|
323 arm) |
|
324 GNU_CONFIG=arm-linux-androideabi |
|
325 ;; |
|
326 x86) |
|
327 GNU_CONFIG=i686-linux-android |
|
328 ;; |
|
329 *) |
|
330 GNU_CONFIG="$ARCH-linux-android" |
|
331 ;; |
|
332 esac |
|
333 |
|
334 # Generate standalone NDK toolchain installation |
|
335 NDK_STANDALONE="$TMPDIR/ndk-$ARCH-toolchain" |
|
336 echo "Generating NDK standalone toolchain installation" |
|
337 mkdir -p "$NDK_STANDALONE" |
|
338 # NOTE: The --platform=android-9 is required to provide <regex.h> for GTest. |
|
339 run "$NDK_DIR/build/tools/make-standalone-toolchain.sh" \ |
|
340 --arch="$ARCH" \ |
|
341 --platform=android-9 \ |
|
342 --install-dir="$NDK_STANDALONE" |
|
343 fail_panic "Can't generate standalone NDK toolchain installation!" |
|
344 |
|
345 # Rebuild the client library, processor and tools with the auto-tools based |
|
346 # build system. Even though it's not going to be used, this checks that this |
|
347 # still works correctly. |
|
348 echo "Building full Android binaries with configure/make" |
|
349 TMPTARGET="$TMPDIR/target-local" |
|
350 ( |
|
351 PATH="$NDK_STANDALONE/bin:$PATH" |
|
352 run mkdir "$TMPTARGET" && |
|
353 run mkdir "$TMPDIR"/build-target && |
|
354 run cd "$TMPDIR"/build-target && |
|
355 run2 "$PROGDIR"/../configure --prefix="$TMPTARGET" \ |
|
356 --host="$GNU_CONFIG" && |
|
357 run2 make -j$NUM_JOBS install |
|
358 ) |
|
359 fail_panic "Could not rebuild Android binaries!" |
|
360 |
|
361 # Build and/or run unit test suite. |
|
362 # If --no-device is used, only rebuild it, otherwise, run in on the |
|
363 # connected device. |
|
364 if [ "$NO_DEVICE" ]; then |
|
365 ACTION="Building" |
|
366 # This is a trick to force the Makefile to ignore running the scripts. |
|
367 TESTS_ENVIRONMENT="TESTS_ENVIRONMENT=true" |
|
368 else |
|
369 ACTION="Running" |
|
370 TESTS_ENVIRONMENT= |
|
371 fi |
|
372 |
|
373 ( |
|
374 PATH="$NDK_STANDALONE/bin:$PATH" |
|
375 run cd "$TMPDIR"/build-target && |
|
376 # Reconfigure to only run the client unit test suite. |
|
377 # This one should _never_ fail. |
|
378 dump "$ACTION Android client library unit tests." |
|
379 run2 "$PROGDIR"/../configure --prefix="$TMPTARGET" \ |
|
380 --host="$GNU_CONFIG" \ |
|
381 --disable-tools \ |
|
382 --disable-processor && |
|
383 run make -j$NUM_JOBS check $TESTS_ENVIRONMENT || exit $? |
|
384 |
|
385 if [ "$ALL_TESTS" ]; then |
|
386 dump "$ACTION Tools and processor unit tests." |
|
387 # Reconfigure to run the processor and tools tests. |
|
388 # Most of these fail for now, so do not worry about it. |
|
389 run2 "$PROGDIR"/../configure --prefix="$TMPTARGET" \ |
|
390 --host="$GNU_CONFIG" && |
|
391 run make -j$NUM_JOBS check $TESTS_ENVIRONMENT |
|
392 if [ $? != 0 ]; then |
|
393 dump "Tools and processor unit tests failed as expected. \ |
|
394 Use --verbose for results." |
|
395 fi |
|
396 fi |
|
397 ) |
|
398 fail_panic "Client library unit test suite failed!" |
|
399 |
|
400 # Copy sources to temporary directory |
|
401 PROJECT_DIR=$TMPDIR/project |
|
402 dump "Copying test program sources to: $PROJECT_DIR" |
|
403 run cp -r "$TESTAPP_DIR" "$PROJECT_DIR" && |
|
404 run rm -rf "$PROJECT_DIR/obj" && |
|
405 run rm -rf "$PROJECT_DIR/libs" |
|
406 fail_panic "Could not copy test program sources to: $PROJECT_DIR" |
|
407 |
|
408 # Build the test program with ndk-build. |
|
409 dump "Building test program with ndk-build" |
|
410 export NDK_MODULE_PATH="$PROGDIR" |
|
411 NDK_BUILD_FLAGS="-j$NUM_JOBS" |
|
412 if verbosity_is_higher_than 1; then |
|
413 NDK_BUILD_FLAGS="$NDK_BUILD_FLAGS NDK_LOG=1 V=1" |
|
414 fi |
|
415 run "$NDK_DIR/ndk-build" -C "$PROJECT_DIR" $NDK_BUILD_FLAGS APP_ABI=$ABI |
|
416 fail_panic "Can't build test program!" |
|
417 |
|
418 # Unless --no-device was used, stop right here if ADB isn't in the path, |
|
419 # or there is no connected device. |
|
420 if [ "$NO_DEVICE" ]; then |
|
421 dump "Done. Please connect a device to run all tests!" |
|
422 clean_exit 0 |
|
423 fi |
|
424 |
|
425 # Push the program to the device. |
|
426 TESTAPP=test_google_breakpad |
|
427 TESTAPP_FILE="$PROJECT_DIR/libs/$ABI/test_google_breakpad" |
|
428 if [ ! -f "$TESTAPP_FILE" ]; then |
|
429 panic "Device requires '$ABI' binaries. None found!" |
|
430 fi |
|
431 |
|
432 # Run the program there |
|
433 dump "Installing test program on device" |
|
434 DEVICE_TMP=/data/local/tmp |
|
435 adb_push "$TESTAPP_FILE" "$DEVICE_TMP/" |
|
436 fail_panic "Cannot push test program to device!" |
|
437 |
|
438 dump "Running test program on device" |
|
439 adb_shell cd "$DEVICE_TMP" "&&" ./$TESTAPP > "$CRASH_LOG" 2>/dev/null |
|
440 if [ $? = 0 ]; then |
|
441 panic "Test program did *not* crash as expected!" |
|
442 fi |
|
443 if verbosity_is_higher_than 0; then |
|
444 echo -n "Crash log: " |
|
445 cat "$CRASH_LOG" |
|
446 fi |
|
447 |
|
448 # Extract minidump from device |
|
449 MINIDUMP_NAME=$(awk '$1 == "Dump" && $2 == "path:" { print $3; }' "$CRASH_LOG") |
|
450 MINIDUMP_NAME=$(basename "$MINIDUMP_NAME") |
|
451 if [ -z "$MINIDUMP_NAME" ]; then |
|
452 panic "Test program didn't write minidump properly!" |
|
453 fi |
|
454 |
|
455 dump "Extracting minidump: $MINIDUMP_NAME" |
|
456 adb_pull "$DEVICE_TMP/$MINIDUMP_NAME" . |
|
457 fail_panic "Can't extract minidump!" |
|
458 |
|
459 dump "Parsing test program symbols" |
|
460 if verbosity_is_higher_than 1; then |
|
461 log "COMMAND: $TMPBIN/dump_syms \ |
|
462 $PROJECT_DIR/obj/local/$ABI/$TESTAPP >$TESTAPP.sym" |
|
463 fi |
|
464 "$TMPBIN/dump_syms" "$PROJECT_DIR/obj/local/$ABI/$TESTAPP" > $TESTAPP.sym |
|
465 fail_panic "dump_syms doesn't work!" |
|
466 |
|
467 VERSION=$(awk '$1 == "MODULE" { print $4; }' $TESTAPP.sym) |
|
468 dump "Found module version: $VERSION" |
|
469 if [ -z "$VERSION" ]; then |
|
470 echo "ERROR: Can't find proper module version from symbol dump!" |
|
471 head -n5 $TESTAPP.sym |
|
472 clean_exit 1 |
|
473 fi |
|
474 |
|
475 run mkdir -p "$TMPDIR/symbols/$TESTAPP/$VERSION" |
|
476 run mv $TESTAPP.sym "$TMPDIR/symbols/$TESTAPP/$VERSION/" |
|
477 |
|
478 dump "Generating stack trace" |
|
479 # Don't use 'run' to be able to send stdout and stderr to two different files. |
|
480 log "COMMAND: $TMPBIN/minidump_stackwalk $MINIDUMP_NAME symbols" |
|
481 "$TMPBIN/minidump_stackwalk" $MINIDUMP_NAME \ |
|
482 "$TMPDIR/symbols" \ |
|
483 > "$BUILD_LOG" 2>>"$RUN_LOG" |
|
484 fail_panic "minidump_stackwalk doesn't work!" |
|
485 |
|
486 dump "Checking stack trace content" |
|
487 |
|
488 if verbosity_is_higher_than 1; then |
|
489 cat "$BUILD_LOG" |
|
490 fi |
|
491 |
|
492 # The generated stack trace should look like the following: |
|
493 # |
|
494 # Thread 0 (crashed) |
|
495 # 0 test_google_breakpad!crash [test_breakpad.cpp : 17 + 0x4] |
|
496 # r4 = 0x00015530 r5 = 0xbea2cbe4 r6 = 0xffffff38 r7 = 0xbea2cb5c |
|
497 # r8 = 0x00000000 r9 = 0x00000000 r10 = 0x00000000 fp = 0x00000000 |
|
498 # sp = 0xbea2cb50 lr = 0x00009025 pc = 0x00008f84 |
|
499 # Found by: given as instruction pointer in context |
|
500 # 1 test_google_breakpad!main [test_breakpad.cpp : 25 + 0x3] |
|
501 # r4 = 0x00015530 r5 = 0xbea2cbe4 r6 = 0xffffff38 r7 = 0xbea2cb5c |
|
502 # r8 = 0x00000000 r9 = 0x00000000 r10 = 0x00000000 fp = 0x00000000 |
|
503 # sp = 0xbea2cb50 pc = 0x00009025 |
|
504 # Found by: call frame info |
|
505 # 2 libc.so + 0x164e5 |
|
506 # r4 = 0x00008f64 r5 = 0xbea2cc34 r6 = 0x00000001 r7 = 0xbea2cc3c |
|
507 # r8 = 0x00000000 r9 = 0x00000000 r10 = 0x00000000 fp = 0x00000000 |
|
508 # sp = 0xbea2cc18 pc = 0x400c34e7 |
|
509 # Found by: call frame info |
|
510 # ... |
|
511 # |
|
512 # The most important part for us is ensuring that the source location could |
|
513 # be extracted, so look at the 'test_breakpad.cpp' references here. |
|
514 # |
|
515 # First, extract all the lines with test_google_breakpad! in them, and |
|
516 # dump the corresponding crash location. |
|
517 # |
|
518 # Note that if the source location can't be extracted, the second field |
|
519 # will only be 'test_google_breakpad' without the exclamation mark. |
|
520 # |
|
521 LOCATIONS=$(awk '$2 ~ "^test_google_breakpad!.*" { print $3; }' "$BUILD_LOG") |
|
522 |
|
523 if [ -z "$LOCATIONS" ]; then |
|
524 if verbosity_is_lower_than 1; then |
|
525 cat "$BUILD_LOG" |
|
526 fi |
|
527 panic "No source location found in stack trace!" |
|
528 fi |
|
529 |
|
530 # Now check that they all match "[<source file>" |
|
531 BAD_LOCATIONS= |
|
532 for LOCATION in $LOCATIONS; do |
|
533 case $LOCATION in |
|
534 # Escape the opening bracket, or some shells like Dash will not |
|
535 # match them properly. |
|
536 \[*.cpp|\[*.cc|\[*.h) # These are valid source locations in our executable |
|
537 ;; |
|
538 *) # Everything else is not! |
|
539 BAD_LOCATIONS="$BAD_LOCATIONS $LOCATION" |
|
540 ;; |
|
541 esac |
|
542 done |
|
543 |
|
544 if [ "$BAD_LOCATIONS" ]; then |
|
545 dump "ERROR: Generated stack trace doesn't contain valid source locations:" |
|
546 cat "$BUILD_LOG" |
|
547 echo "Bad locations are: $BAD_LOCATIONS" |
|
548 exit 1 |
|
549 fi |
|
550 |
|
551 echo "All clear! Congratulations." |
|
552 |