Add Android NDK module definition + sample application
This patch adds a new directory named "android/" which contains the following: - A NDK build system module definition for the Google Breakpad client library. This can be used by developers using the ndk-build build system to more easily build and use the client library in their own programs. - A sample application demonstrating how to use the module, as well as test that the library works properly during a crash. - A shell script (run-checks.sh) that will check everything for you automatically, including: - Rebuilding the host Google Breakpad host package with configure/make - Rebuilding the Android client library with configure/make - Rebuilding the Android client library and test program with ndk-build - Running the crashing test program, extract minidump, dump symbols, generate a stack trace and check that it has correct source file locations. For more details, run android/run-checks.sh --help-all + Updates to the README.ANDROID documentation. Review URL: https://breakpad.appspot.com/407002 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@983 4c0a9323-5329-0410-9bdc-e9ce6186880e
This commit is contained in:
parent
47e34e6f07
commit
0bed408b15
7 changed files with 986 additions and 0 deletions
134
README.ANDROID
Normal file
134
README.ANDROID
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
Google Breakpad for Android
|
||||||
|
===========================
|
||||||
|
|
||||||
|
This document explains how to use the Google Breakpad client library
|
||||||
|
on Android, and later generate valid stack traces from the minidumps
|
||||||
|
it generates.
|
||||||
|
|
||||||
|
Note that this release only supports ARM-based Android systems.
|
||||||
|
We're working on adding support for x86 and MIPS, but that might
|
||||||
|
require an udpated NDK release.
|
||||||
|
|
||||||
|
|
||||||
|
I. Building the client library:
|
||||||
|
===============================
|
||||||
|
|
||||||
|
The Android client is built as a static library that you can
|
||||||
|
link into your own Android native code. There are two ways to
|
||||||
|
build it:
|
||||||
|
|
||||||
|
I.1. Building with ndk-build:
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
If you're using the ndk-build build system, you can follow
|
||||||
|
these simple steps:
|
||||||
|
|
||||||
|
1/ Include android/google_breakpad/Android.mk from your own
|
||||||
|
project's Android.mk
|
||||||
|
|
||||||
|
This can be done either directly, or using ndk-build's
|
||||||
|
import-module feature.
|
||||||
|
|
||||||
|
2/ Link the library to one of your modules by using:
|
||||||
|
|
||||||
|
LOCAL_STATIC_LIBRARIES += breakpad_client
|
||||||
|
|
||||||
|
NOTE: The client library requires a C++ STL implementation,
|
||||||
|
which you can select with APP_STL in your Application.mk
|
||||||
|
|
||||||
|
It has been tested succesfully with both STLport and GNU libstdc++
|
||||||
|
|
||||||
|
|
||||||
|
II.1. Building with a standalone Android toolchain:
|
||||||
|
---------------------------------------------------
|
||||||
|
|
||||||
|
All you need to do is configure your build with the right 'host'
|
||||||
|
value, and disable the processor and tools, as in:
|
||||||
|
|
||||||
|
$GOOGLE_BREAKPAD_PATH/configure --host=arm-linux-androideabi \
|
||||||
|
--disable-processor \
|
||||||
|
--disable-tools
|
||||||
|
make -j4
|
||||||
|
|
||||||
|
The library will be under src/client/linux/libbreakpad_client.a
|
||||||
|
|
||||||
|
|
||||||
|
II. Using the client library in Android:
|
||||||
|
========================================
|
||||||
|
|
||||||
|
The usage instructions are very similar to the Linux ones that are
|
||||||
|
found at http://code.google.com/p/google-breakpad/wiki/LinuxStarterGuide
|
||||||
|
|
||||||
|
1/ You need to include "client/linux/handler/exception_handler.h" from a C++
|
||||||
|
source file.
|
||||||
|
|
||||||
|
2/ If you're not using ndk-build, you also need to:
|
||||||
|
|
||||||
|
- add $GOOGLE_BREAKPAD_PATH to your compiler include path
|
||||||
|
- add -llog to your linker flags
|
||||||
|
|
||||||
|
Note that ndk-build does that for your automatically.
|
||||||
|
|
||||||
|
3/ Keep in mind that there is no /tmp directory on Android.
|
||||||
|
|
||||||
|
If you use the library from a regular Android applications, specify a
|
||||||
|
path under your app-specific storage directory. An alternative is to
|
||||||
|
store them on the SDCard, but this requires a specific permission.
|
||||||
|
|
||||||
|
For a concrete example, see the sample test application under
|
||||||
|
android/sample_app. See its README for more information.
|
||||||
|
|
||||||
|
|
||||||
|
III. Getting a stack trace on the host:
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
This process is similar to other platforms, but here's a quick example:
|
||||||
|
|
||||||
|
1/ Retrieve the minidumps on your development machine.
|
||||||
|
|
||||||
|
2/ Dump the symbols for your native libraries with the 'dump_syms' tool.
|
||||||
|
This first requires building the host version of Google Breakpad, then
|
||||||
|
calling:
|
||||||
|
|
||||||
|
dump_syms $PROJECT_PATH/obj/local/$ABI/libfoo.so > libfoo.so.sym
|
||||||
|
|
||||||
|
3/ Create the symbol directory hierarchy.
|
||||||
|
|
||||||
|
The first line of the generated libfoo.so.sym will have a "MODULE"
|
||||||
|
entry that carries a hexadecimal version number, e.g.:
|
||||||
|
|
||||||
|
MODULE Linux arm D51B4A5504974FA6ECC1869CAEE3603B0 test_google_breakpad
|
||||||
|
|
||||||
|
Note: The second field could be either 'Linux' or 'Android'.
|
||||||
|
|
||||||
|
Extract the version number, and a 'symbol' directory, for example:
|
||||||
|
|
||||||
|
$PROJECT_PATH/symbols/libfoo.so/$VERSION/
|
||||||
|
|
||||||
|
Copy/Move your libfoo.sym file there.
|
||||||
|
|
||||||
|
4/ Invoke minidump_stackwalk to create the stack trace:
|
||||||
|
|
||||||
|
minidump_stackwalk $MINIDUMP_FILE $PROJECT_PATH/symbols
|
||||||
|
|
||||||
|
Note that various helper scripts can be found on the web to automate these
|
||||||
|
steps.
|
||||||
|
|
||||||
|
IV. Verifying the Android build library:
|
||||||
|
========================================
|
||||||
|
|
||||||
|
If you modify Google Breakpad and want to check that it still works correctly
|
||||||
|
on Android, please run the android/run-test-program.sh script which will do all
|
||||||
|
necessary verifications for you. This includes:
|
||||||
|
|
||||||
|
- Rebuilding the full host package
|
||||||
|
- Rebuilding the client library with configure/make
|
||||||
|
- Rebuilding the client library with ndk-build
|
||||||
|
- Building, installing and running a test crasher program on a device
|
||||||
|
- Extracting the corresponding minidump, dumping the test program symbols
|
||||||
|
and generating a stack trace.
|
||||||
|
- Checking the stack trace for valid source locations.
|
||||||
|
|
||||||
|
For more details, please run:
|
||||||
|
|
||||||
|
android/run-test-program.sh --help-all
|
96
android/google_breakpad/Android.mk
Normal file
96
android/google_breakpad/Android.mk
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
# Copyright (c) 2012, Google Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are
|
||||||
|
# met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above
|
||||||
|
# copyright notice, this list of conditions and the following disclaimer
|
||||||
|
# in the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# * Neither the name of Google Inc. nor the names of its
|
||||||
|
# contributors may be used to endorse or promote products derived from
|
||||||
|
# this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
# ndk-build module definition for the Google Breakpad client library
|
||||||
|
#
|
||||||
|
# To use this file, do the following:
|
||||||
|
#
|
||||||
|
# 1/ Include this file from your own Android.mk, either directly
|
||||||
|
# or with through the NDK's import-module function.
|
||||||
|
#
|
||||||
|
# 2/ Use the client static library in your project with:
|
||||||
|
#
|
||||||
|
# LOCAL_STATIC_LIBRARIES += breakpad_client
|
||||||
|
#
|
||||||
|
# 3/ In your source code, include "src/client/linux/exception_handler.h"
|
||||||
|
# and use the Linux instructions to use it.
|
||||||
|
#
|
||||||
|
# This module works with either the STLport or GNU libstdc++, but you need
|
||||||
|
# to select one in your Application.mk
|
||||||
|
#
|
||||||
|
|
||||||
|
# Sanity check. We can only build for ARM for now.
|
||||||
|
ifneq (,$(filter-out armeabi armeabi-v7a,$(TARGET_ARCH_ABI)))
|
||||||
|
$(error Sorry, Google Breakpad only works on Android ARM for now!)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# The top Google Breakpad directory.
|
||||||
|
# We assume this Android.mk to be under 'android/google_breakpad'
|
||||||
|
|
||||||
|
LOCAL_PATH := $(call my-dir)/../..
|
||||||
|
|
||||||
|
# Defube the client library module, as a simple static library that
|
||||||
|
# exports the right include path / linker flags to its users.
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_MODULE := breakpad_client
|
||||||
|
|
||||||
|
LOCAL_CPP_EXTENSION := .cc
|
||||||
|
|
||||||
|
# Breakpad uses inline ARM assembly that requires the library
|
||||||
|
# to be built in ARM mode. Otherwise, the build will fail with
|
||||||
|
# cryptic assembler messages like:
|
||||||
|
# Compile++ thumb : google_breakpad_client <= crash_generation_client.cc
|
||||||
|
# /tmp/cc8aMSoD.s: Assembler messages:
|
||||||
|
# /tmp/cc8aMSoD.s:132: Error: invalid immediate: 288 is out of range
|
||||||
|
# /tmp/cc8aMSoD.s:244: Error: invalid immediate: 296 is out of range
|
||||||
|
LOCAL_ARM_MODE := arm
|
||||||
|
|
||||||
|
# List of client source files, directly taken from Makefile.am
|
||||||
|
LOCAL_SRC_FILES := \
|
||||||
|
src/client/linux/crash_generation/crash_generation_client.cc \
|
||||||
|
src/client/linux/handler/exception_handler.cc \
|
||||||
|
src/client/linux/log/log.cc \
|
||||||
|
src/client/linux/minidump_writer/linux_dumper.cc \
|
||||||
|
src/client/linux/minidump_writer/linux_ptrace_dumper.cc \
|
||||||
|
src/client/linux/minidump_writer/minidump_writer.cc \
|
||||||
|
src/client/minidump_file_writer.cc src/common/convert_UTF.c \
|
||||||
|
src/common/md5.cc src/common/string_conversion.cc \
|
||||||
|
src/common/linux/file_id.cc src/common/linux/guid_creator.cc \
|
||||||
|
src/common/linux/memory_mapped_file.cc \
|
||||||
|
src/common/linux/safe_readlink.cc
|
||||||
|
|
||||||
|
LOCAL_C_INCLUDES := $(LOCAL_PATH)/src
|
||||||
|
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES)
|
||||||
|
LOCAL_EXPORT_LDLIBS := -llog
|
||||||
|
|
||||||
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
|
# Done.
|
594
android/run-checks.sh
Executable file
594
android/run-checks.sh
Executable file
|
@ -0,0 +1,594 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Copyright (c) 2012 Google Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are
|
||||||
|
# met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above
|
||||||
|
# copyright notice, this list of conditions and the following disclaimer
|
||||||
|
# in the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# * Neither the name of Google Inc. nor the names of its
|
||||||
|
# contributors may be used to endorse or promote products derived from
|
||||||
|
# this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
# Sanitize the environment
|
||||||
|
export LANG=C
|
||||||
|
export LC_ALL=C
|
||||||
|
|
||||||
|
if [ "$BASH_VERSION" ]; then
|
||||||
|
set -o posix
|
||||||
|
fi
|
||||||
|
|
||||||
|
PROGDIR=$(dirname "$0")
|
||||||
|
PROGDIR=$(cd "$PROGDIR" && pwd)
|
||||||
|
PROGNAME=$(basename "$0")
|
||||||
|
|
||||||
|
# Utility functions
|
||||||
|
|
||||||
|
TMPDIR=
|
||||||
|
|
||||||
|
# Used to exit the program after removing the temporary directory.
|
||||||
|
clean_exit () {
|
||||||
|
if [ "$TMPDIR" ]; then
|
||||||
|
if [ -z "$NO_CLEANUP" ]; then
|
||||||
|
log "Cleaning up: $TMPDIR"
|
||||||
|
rm -rf "$TMPDIR"
|
||||||
|
else
|
||||||
|
dump "Temporary directory contents preserved: $TMPDIR"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
exit "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Dump a panic message then exit.
|
||||||
|
panic () {
|
||||||
|
echo "ERROR: $@"
|
||||||
|
clean_exit 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
# If the previous command failed, dump a panic message then exit.
|
||||||
|
fail_panic () {
|
||||||
|
if [ $? != 0 ]; then
|
||||||
|
panic "$@"
|
||||||
|
fi;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Extract number of cores to speed up the builds
|
||||||
|
get_core_count () {
|
||||||
|
case $(uname -s) in
|
||||||
|
Linux)
|
||||||
|
grep -c -e '^processor' /proc/cpuinfo
|
||||||
|
;;
|
||||||
|
Darwin)
|
||||||
|
sysctl -n hw.ncpu
|
||||||
|
;;
|
||||||
|
CYGWIN*|*_NT-*)
|
||||||
|
echo $NUMBER_OF_PROCESSORS
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
ADB=
|
||||||
|
ENABLE_M32=
|
||||||
|
HELP=
|
||||||
|
HELP_ALL=
|
||||||
|
NDK_DIR=
|
||||||
|
NO_CLEANUP=
|
||||||
|
NO_DEVICE=
|
||||||
|
NUM_JOBS=$(get_core_count)
|
||||||
|
TMPDIR=
|
||||||
|
VERBOSE=0
|
||||||
|
|
||||||
|
for opt do
|
||||||
|
# The following extracts the value if the option is like --name=<value>.
|
||||||
|
optarg=$(expr -- $opt : '^--[^=]*=\(.*\)$')
|
||||||
|
case $opt in
|
||||||
|
--adb=*) ADB=$optarg;;
|
||||||
|
--enable-m32) ENABLE_M32=true;;
|
||||||
|
--help|-h|-?) HELP=TRUE;;
|
||||||
|
--help-all) HELP_ALL=true;;
|
||||||
|
--jobs=*) NUM_JOBS=$optarg;;
|
||||||
|
--ndk-dir=*) NDK_DIR=$optarg;;
|
||||||
|
--tmp-dir=*) TMPDIR=$optarg;;
|
||||||
|
--no-cleanup) NO_CLEANUP=true;;
|
||||||
|
--no-device) NO_DEVICE=true;;
|
||||||
|
--quiet) VERBOSE=$(( $VERBOSE - 1 ));;
|
||||||
|
--verbose) VERBOSE=$(( $VERBOSE + 1 ));;
|
||||||
|
-*) panic "Invalid option '$opt', see --help for details.";;
|
||||||
|
*) panic "This script doesn't take any parameters. See --help for details."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$HELP" -o "$HELP_ALL" ]; then
|
||||||
|
echo "\
|
||||||
|
Usage: $PROGNAME [options]
|
||||||
|
|
||||||
|
This script is used to check that your Google Breakpad source tree can
|
||||||
|
be properly built for Android, and that the client library and host tools
|
||||||
|
work properly together.
|
||||||
|
"
|
||||||
|
if [ "$HELP_ALL" ]; then
|
||||||
|
echo "\
|
||||||
|
In more details, this script will:
|
||||||
|
|
||||||
|
- Rebuild the host version of Google Breakpad in a temporary
|
||||||
|
directory (with the Auto-tools based build system).
|
||||||
|
|
||||||
|
- Rebuild the Android client library with the Google Breakpad build
|
||||||
|
system (using autotools/configure). This requires that you define
|
||||||
|
ANDROID_NDK_ROOT in your environment to point to a valid Android NDK
|
||||||
|
installation directory, or use the --ndk-dir=<path> option.
|
||||||
|
|
||||||
|
- Rebuild the Android client library and a test crashing program with the
|
||||||
|
Android NDK build system (ndk-build).
|
||||||
|
|
||||||
|
- Require an Android device connected to your machine, and the 'adb'
|
||||||
|
tool in your path. They are used to:
|
||||||
|
|
||||||
|
- Install and run a test crashing program.
|
||||||
|
- Extract the corresponding minidump from the device.
|
||||||
|
- Dump the symbols from the test program on the host with 'dump_syms'
|
||||||
|
- Generate a stack trace with 'minidump_stackwalk'
|
||||||
|
- Check the stack trace content for valid source file locations.
|
||||||
|
|
||||||
|
You can however skip this requirement and only test the builds by using
|
||||||
|
the --no-device flag.
|
||||||
|
|
||||||
|
By default, all generated files will be created in a temporary directory
|
||||||
|
that is removed when the script completion. If you want to inspect the
|
||||||
|
files, use the --no-cleanup option.
|
||||||
|
|
||||||
|
Finally, use --verbose to increase the verbosity level, this will help
|
||||||
|
you see which exact commands are being issues and their result. Use the
|
||||||
|
flag twice for even more output. Use --quiet to decrease verbosity
|
||||||
|
instead and run the script silently.
|
||||||
|
"
|
||||||
|
|
||||||
|
fi # HELP_ALL
|
||||||
|
|
||||||
|
echo "\
|
||||||
|
Valid options:
|
||||||
|
|
||||||
|
--help|-h|-? Display this message.
|
||||||
|
--help-all Display extended help.
|
||||||
|
--enable-m32 Build 32-bit version of host tools.
|
||||||
|
--jobs=<count> Run <count> build tasks in parallel [$NUM_JOBS].
|
||||||
|
--ndk-dir=<path> Specify NDK installation directory.
|
||||||
|
--tmp-dir=<path> Specify temporary directory (will be wiped-out).
|
||||||
|
--adb=<path> Specify adb program path.
|
||||||
|
--no-cleanup Don't remove temporary directory after completion.
|
||||||
|
--no-device Do not try to detect devices, nor run crash test.
|
||||||
|
--verbose Increase verbosity.
|
||||||
|
--quiet Decrease verbosity."
|
||||||
|
|
||||||
|
clean_exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Dump message to stdout, unless verbosity is < 0, i.e. --quiet was called
|
||||||
|
dump () {
|
||||||
|
if [ "$VERBOSE" -ge 0 ]; then
|
||||||
|
echo "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# If --verbose was used, dump a message to stdout.
|
||||||
|
log () {
|
||||||
|
if [ "$VERBOSE" -ge 1 ]; then
|
||||||
|
echo "$@"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run a command. Output depends on $VERBOSE:
|
||||||
|
# $VERBOSE <= 0: Run command, store output into the run log
|
||||||
|
# $VERBOSE >= 1: Dump command, run it, output goest to stdout
|
||||||
|
# Note: Ideally, the command's output would go to the run log for $VERBOSE >= 1
|
||||||
|
# but the 'tee' tool doesn't preserve the status code of its input pipe
|
||||||
|
# in case of error.
|
||||||
|
run () {
|
||||||
|
local LOGILE
|
||||||
|
if [ "$RUN_LOG" ]; then
|
||||||
|
LOGFILE=$RUN_LOG
|
||||||
|
else
|
||||||
|
LOGFILE=/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$VERBOSE" -ge 1 ]; then
|
||||||
|
echo "COMMAND: $@"
|
||||||
|
"$@"
|
||||||
|
else
|
||||||
|
"$@" >>$LOGFILE 2>&1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Same as run(), but only dump command output for $VERBOSE >= 2
|
||||||
|
run2 () {
|
||||||
|
local LOGILE
|
||||||
|
if [ "$RUN_LOG" ]; then
|
||||||
|
LOGFILE=$RUN_LOG
|
||||||
|
else
|
||||||
|
LOGFILE=/dev/null
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$VERBOSE" -ge 1 ]; then
|
||||||
|
echo "COMMAND: $@"
|
||||||
|
fi
|
||||||
|
if [ "$VERBOSE" -ge 2 ]; then
|
||||||
|
"$@"
|
||||||
|
else
|
||||||
|
"$@" >>$LOGFILE 2>&1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
TESTAPP_DIR=$PROGDIR/sample_app
|
||||||
|
|
||||||
|
# Select NDK install directory.
|
||||||
|
if [ -z "$NDK_DIR" ]; then
|
||||||
|
if [ -z "$ANDROID_NDK_ROOT" ]; then
|
||||||
|
panic "Please define ANDROID_NDK_ROOT in your environment, or use \
|
||||||
|
--ndk-dir=<path>."
|
||||||
|
fi
|
||||||
|
NDK_DIR="$ANDROID_NDK_ROOT"
|
||||||
|
log "Found NDK directory: $NDK_DIR"
|
||||||
|
else
|
||||||
|
log "Using NDK directory: $NDK_DIR"
|
||||||
|
fi
|
||||||
|
# Small sanity check.
|
||||||
|
NDK_BUILD="$NDK_DIR/ndk-build"
|
||||||
|
if [ ! -f "$NDK_BUILD" ]; then
|
||||||
|
panic "Your NDK directory is not valid (missing ndk-build): $NDK_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If --tmp-dir=<path> is not used, create a temporary directory.
|
||||||
|
# Otherwise, start by cleaning up the user-provided path.
|
||||||
|
if [ -z "$TMPDIR" ]; then
|
||||||
|
TMPDIR=$(mktemp -d /tmp/$PROGNAME.XXXXXXXX)
|
||||||
|
fail_panic "Can't create temporary directory!"
|
||||||
|
log "Using temporary directory: $TMPDIR"
|
||||||
|
else
|
||||||
|
if [ ! -d "$TMPDIR" ]; then
|
||||||
|
mkdir -p "$TMPDIR"
|
||||||
|
fail_panic "Can't create temporary directory: $TMPDIR"
|
||||||
|
else
|
||||||
|
log "Cleaning up temporary directory: $TMPDIR"
|
||||||
|
rm -rf "$TMPDIR"/*
|
||||||
|
fail_panic "Cannot cleanup temporary directory!"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Ensure a clean exit when the script is:
|
||||||
|
# - Interrupted by Ctrl-C (INT)
|
||||||
|
# - Interrupted by log out (HUP)
|
||||||
|
# - Being asked to quit nicely (TERM)
|
||||||
|
# - Being asked to quit and dump core (QUIT)
|
||||||
|
trap "clean_exit 1" INT HUP TERM QUIT
|
||||||
|
|
||||||
|
# The 'adb shell' command is pretty hopeless, try to make sense of it by:
|
||||||
|
# 1/ Removing trailing \r from line endings.
|
||||||
|
# 2/ Ensuring the function returns the command's status code.
|
||||||
|
#
|
||||||
|
adb_shell () {
|
||||||
|
local RET ADB_LOG
|
||||||
|
ADB_LOG=$(mktemp "$TMPDIR/adb-XXXXXXXX")
|
||||||
|
"$ADB" shell "$@" ";" echo \$? > "$ADB_LOG" 2>&1
|
||||||
|
sed -i -e 's![[:cntrl:]]!!g' "$ADB_LOG" # Remove \r.
|
||||||
|
RET=$(sed -e '$!d' "$ADB_LOG") # Last line contains status code.
|
||||||
|
sed -e '$d' "$ADB_LOG" # Print everything except last line.
|
||||||
|
rm -f "$ADB_LOG"
|
||||||
|
return $RET
|
||||||
|
}
|
||||||
|
|
||||||
|
check_for_adb () {
|
||||||
|
local ADB_VERSION ADB_DEVICES NUM_DEVICES FINGERPRINT
|
||||||
|
|
||||||
|
# Auto-detect ADB in current path when needed.
|
||||||
|
if [ -z "$ADB" ]; then
|
||||||
|
ADB=$(which adb 2>/dev/null)
|
||||||
|
if [ -z "$ADB" ]; then
|
||||||
|
panic "The 'adb' tool is not in your path! Use either --no-device to\
|
||||||
|
only check the builds, or --adb=<path> to specify the tool path."
|
||||||
|
fi
|
||||||
|
log "Found ADB path: $ADB"
|
||||||
|
else
|
||||||
|
log "Using ADB path: $ADB"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check that it works.
|
||||||
|
ADB_VERSION=$("$ADB" version 2>/dev/null)
|
||||||
|
case $ADB_VERSION in
|
||||||
|
"Android Debug Bridge "*) # Pass.
|
||||||
|
log "Found ADB version: $ADB_VERSION"
|
||||||
|
;;
|
||||||
|
*) # Fail.
|
||||||
|
panic "Your ADB binary does not seem to work: $ADB"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Count the number of connected devices.
|
||||||
|
ADB_DEVICES=$("$ADB" devices 2>/dev/null | awk '$2 == "device" { print $1; }')
|
||||||
|
if [ "$ADB_DEVICES" ]; then
|
||||||
|
NUM_DEVICES=$(echo "$ADB_DEVICES" | wc -l)
|
||||||
|
else
|
||||||
|
NUM_DEVICES=0
|
||||||
|
fi
|
||||||
|
case $NUM_DEVICES in
|
||||||
|
0)
|
||||||
|
panic "No Android device connected! Connect one, or use --no-device \
|
||||||
|
to only check the builds."
|
||||||
|
;;
|
||||||
|
1)
|
||||||
|
export ANDROID_SERIAL=$ADB_DEVICES
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if [ "$ANDROID_SERIAL" ]; then
|
||||||
|
ADB_DEVICES=$ANDROID_SERIAL
|
||||||
|
NUM_DEVICES=1
|
||||||
|
else
|
||||||
|
dump "ERROR: More than one Android device connected. Please define \
|
||||||
|
ANDROID_SERIAL"
|
||||||
|
dump " in your environment, or use --no-device to only check \
|
||||||
|
the builds."
|
||||||
|
clean_exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
FINGERPRINT=$(adb_shell getprop ro.build.fingerprint)
|
||||||
|
dump "Using device: $ANDROID_SERIAL ($FINGERPRINT)"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -z "$NO_DEVICE" ]; then
|
||||||
|
check_for_adb
|
||||||
|
fi
|
||||||
|
|
||||||
|
BUILD_LOG="$TMPDIR/build.log"
|
||||||
|
RUN_LOG="$TMPDIR/run.log"
|
||||||
|
CRASH_LOG="$TMPDIR/crash.log"
|
||||||
|
|
||||||
|
TMPHOST="$TMPDIR/host-local"
|
||||||
|
|
||||||
|
cd "$TMPDIR"
|
||||||
|
|
||||||
|
# Build host version of the tools
|
||||||
|
dump "Building host tools."
|
||||||
|
CONFIGURE_FLAGS=
|
||||||
|
if [ "$ENABLE_M32" ]; then
|
||||||
|
CONFIGURE_FLAGS="$CONFIGURE_FLAGS --enable-m32"
|
||||||
|
fi
|
||||||
|
(
|
||||||
|
run mkdir "$TMPDIR/build-host" &&
|
||||||
|
run cd "$TMPDIR/build-host" &&
|
||||||
|
run2 "$PROGDIR/../configure" --prefix="$TMPHOST" $CONFIGURE_FLAGS &&
|
||||||
|
run2 make -j$NUM_JOBS install
|
||||||
|
)
|
||||||
|
fail_panic "Can't build host-tools!"
|
||||||
|
|
||||||
|
TMPBIN=$TMPHOST/bin
|
||||||
|
|
||||||
|
# Generate a stand-alone NDK toolchain
|
||||||
|
|
||||||
|
# Extract ABI and architecture from device, if any.
|
||||||
|
if [ "$ADB" ]; then
|
||||||
|
ABI=$(adb_shell getprop ro.product.cpu.abi)
|
||||||
|
if [ -z "$ABI" ]; then
|
||||||
|
panic "Can't extract ABI from connected device!"
|
||||||
|
fi
|
||||||
|
dump "Found device ABI: $ABI"
|
||||||
|
else
|
||||||
|
# No device connected, choose default ABI
|
||||||
|
ABI=armeabi
|
||||||
|
dump "Default ABI: $ABI"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Compute architecture name
|
||||||
|
case $ABI in
|
||||||
|
arm*) ARCH=arm;;
|
||||||
|
*) ARCH="$ABI";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Extract GNU configuration name
|
||||||
|
case $ARCH in
|
||||||
|
arm) GNU_CONFIG=arm-linux-androideabi;;
|
||||||
|
*) GNU_CONFIG="$ARCH-linux-android";;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Generate standalone NDK toolchain installation
|
||||||
|
NDK_STANDALONE="$TMPDIR/ndk-$ARCH-toolchain"
|
||||||
|
echo "Generating NDK standalone toolchain installation"
|
||||||
|
mkdir -p "$NDK_STANDALONE"
|
||||||
|
run "$NDK_DIR/build/tools/make-standalone-toolchain.sh" \
|
||||||
|
--arch="$ARCH" \
|
||||||
|
--install-dir="$NDK_STANDALONE"
|
||||||
|
fail_panic "Can't generate standalone NDK toolchain installation!"
|
||||||
|
|
||||||
|
# Rebuild the client library with the auto-tools base build system.
|
||||||
|
# Even though it's not going to be used, this checks that this still
|
||||||
|
# works correctly.
|
||||||
|
echo "Building client Android library with configure/make"
|
||||||
|
TMPTARGET="$TMPDIR/target-local"
|
||||||
|
(
|
||||||
|
PATH="$NDK_STANDALONE/bin:$PATH"
|
||||||
|
run mkdir "$TMPTARGET" &&
|
||||||
|
run mkdir "$TMPDIR"/build-target &&
|
||||||
|
run cd "$TMPDIR"/build-target &&
|
||||||
|
run2 "$PROGDIR"/../configure --prefix="$TMPTARGET" \
|
||||||
|
--host="$GNU_CONFIG" \
|
||||||
|
--disable-tools \
|
||||||
|
--disable-processor &&
|
||||||
|
run2 make -j$NUM_JOBS install
|
||||||
|
)
|
||||||
|
fail_panic "Could not rebuild Android client library!"
|
||||||
|
|
||||||
|
# Copy sources to temporary directory
|
||||||
|
PROJECT_DIR=$TMPDIR/project
|
||||||
|
dump "Copying test program sources to: $PROJECT_DIR"
|
||||||
|
run cp -r "$TESTAPP_DIR" "$PROJECT_DIR" &&
|
||||||
|
run rm -rf "$PROJECT_DIR/obj" &&
|
||||||
|
run rm -rf "$PROJECT_DIR/libs"
|
||||||
|
fail_panic "Could not copy test program sources to: $PROJECT_DIR"
|
||||||
|
|
||||||
|
# Build the test program with ndk-build.
|
||||||
|
dump "Building test program with ndk-build"
|
||||||
|
export NDK_MODULE_PATH="$PROGDIR"
|
||||||
|
NDK_BUILD_FLAGS="-j$NUM_JOBS"
|
||||||
|
if [ "$VERBOSE" -ge 2 ]; then
|
||||||
|
NDK_BUILD_FLAGS="$NDK_BUILD_FLAGS NDK_LOG=1 V=1"
|
||||||
|
fi
|
||||||
|
run "$NDK_DIR/ndk-build" -C "$PROJECT_DIR" $NDK_BUILD_FLAGS
|
||||||
|
fail_panic "Can't build test program!"
|
||||||
|
|
||||||
|
# Unless --no-device was used, stop right here if ADB isn't in the path,
|
||||||
|
# or there is no connected device.
|
||||||
|
if [ "$NO_DEVICE" ]; then
|
||||||
|
dump "Done. Please connect a device to run all tests!"
|
||||||
|
clean_exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Push the program to the device.
|
||||||
|
TESTAPP=test_google_breakpad
|
||||||
|
TESTAPP_FILE="$PROJECT_DIR/libs/$ABI/test_google_breakpad"
|
||||||
|
if [ ! -f "$TESTAPP_FILE" ]; then
|
||||||
|
panic "Device requires '$ABI' binaries. None found!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run the program there
|
||||||
|
dump "Installing test program on device"
|
||||||
|
DEVICE_TMP=/data/local/tmp
|
||||||
|
run "$ADB" push "$TESTAPP_FILE" "$DEVICE_TMP/"
|
||||||
|
fail_panic "Cannot push test program to device!"
|
||||||
|
|
||||||
|
dump "Running test program on device"
|
||||||
|
adb_shell cd "$DEVICE_TMP" "&&" ./$TESTAPP > "$CRASH_LOG" 2>/dev/null
|
||||||
|
if [ $? = 0 ]; then
|
||||||
|
panic "Test program did *not* crash as expected!"
|
||||||
|
fi
|
||||||
|
if [ "$VERBOSE" -ge 1 ]; then
|
||||||
|
echo -n "Crash log: "
|
||||||
|
cat "$CRASH_LOG"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract minidump from device
|
||||||
|
MINIDUMP_NAME=$(awk '$1 == "Dump" && $2 == "path:" { print $3; }' "$CRASH_LOG")
|
||||||
|
MINIDUMP_NAME=$(basename "$MINIDUMP_NAME")
|
||||||
|
if [ -z "$MINIDUMP_NAME" ]; then
|
||||||
|
panic "Test program didn't write minidump properly!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
dump "Extracting minidump: $MINIDUMP_NAME"
|
||||||
|
run "$ADB" pull "$DEVICE_TMP/$MINIDUMP_NAME" .
|
||||||
|
fail_panic "Can't extract minidump!"
|
||||||
|
|
||||||
|
dump "Parsing test program symbols"
|
||||||
|
if [ "$VERBOSE" -ge 1 ]; then
|
||||||
|
log "COMMAND: $TMPBIN/dump_syms \
|
||||||
|
$PROJECT_DIR/obj/local/$ABI/$TESTAPP >$TESTAPP.sym"
|
||||||
|
fi
|
||||||
|
"$TMPBIN/dump_syms" "$PROJECT_DIR/obj/local/$ABI/$TESTAPP" > $TESTAPP.sym
|
||||||
|
fail_panic "dump_syms doesn't work!"
|
||||||
|
|
||||||
|
VERSION=$(awk '$1 == "MODULE" { print $4; }' $TESTAPP.sym)
|
||||||
|
dump "Found module version: $VERSION"
|
||||||
|
if [ -z "$VERSION" ]; then
|
||||||
|
echo "ERROR: Can't find proper module version from symbol dump!"
|
||||||
|
head -n5 $TESTAPP.sym
|
||||||
|
clean_exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
run mkdir -p "$TMPDIR/symbols/$TESTAPP/$VERSION"
|
||||||
|
run mv $TESTAPP.sym "$TMPDIR/symbols/$TESTAPP/$VERSION/"
|
||||||
|
|
||||||
|
dump "Generating stack trace"
|
||||||
|
# Don't use 'run' to be able to send stdout and stderr to two different files.
|
||||||
|
log "COMMAND: $TMPBIN/minidump_stackwalk $MINIDUMP_NAME symbols"
|
||||||
|
"$TMPBIN/minidump_stackwalk" $MINIDUMP_NAME \
|
||||||
|
"$TMPDIR/symbols" \
|
||||||
|
> "$BUILD_LOG" 2>>"$RUN_LOG"
|
||||||
|
fail_panic "minidump_stackwalk doesn't work!"
|
||||||
|
|
||||||
|
dump "Checking stack trace content"
|
||||||
|
|
||||||
|
if [ "$VERBOSE" -ge 1 ]; then
|
||||||
|
cat "$BUILD_LOG"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# The generated stack trace should look like the following:
|
||||||
|
#
|
||||||
|
# Thread 0 (crashed)
|
||||||
|
# 0 test_google_breakpad!crash [test_breakpad.cpp : 17 + 0x4]
|
||||||
|
# r4 = 0x00015530 r5 = 0xbea2cbe4 r6 = 0xffffff38 r7 = 0xbea2cb5c
|
||||||
|
# r8 = 0x00000000 r9 = 0x00000000 r10 = 0x00000000 fp = 0x00000000
|
||||||
|
# sp = 0xbea2cb50 lr = 0x00009025 pc = 0x00008f84
|
||||||
|
# Found by: given as instruction pointer in context
|
||||||
|
# 1 test_google_breakpad!main [test_breakpad.cpp : 25 + 0x3]
|
||||||
|
# r4 = 0x00015530 r5 = 0xbea2cbe4 r6 = 0xffffff38 r7 = 0xbea2cb5c
|
||||||
|
# r8 = 0x00000000 r9 = 0x00000000 r10 = 0x00000000 fp = 0x00000000
|
||||||
|
# sp = 0xbea2cb50 pc = 0x00009025
|
||||||
|
# Found by: call frame info
|
||||||
|
# 2 libc.so + 0x164e5
|
||||||
|
# r4 = 0x00008f64 r5 = 0xbea2cc34 r6 = 0x00000001 r7 = 0xbea2cc3c
|
||||||
|
# r8 = 0x00000000 r9 = 0x00000000 r10 = 0x00000000 fp = 0x00000000
|
||||||
|
# sp = 0xbea2cc18 pc = 0x400c34e7
|
||||||
|
# Found by: call frame info
|
||||||
|
# ...
|
||||||
|
#
|
||||||
|
# The most important part for us is ensuring that the source location could
|
||||||
|
# be extracted, so look at the 'test_breakpad.cpp' references here.
|
||||||
|
#
|
||||||
|
# First, extract all the lines with test_google_breakpad! in them, and
|
||||||
|
# dump the corresponding crash location.
|
||||||
|
#
|
||||||
|
# Note that if the source location can't be extracted, the second field
|
||||||
|
# will only be 'test_google_breakpad' without the exclamation mark.
|
||||||
|
#
|
||||||
|
LOCATIONS=$(awk '$2 ~ "^test_google_breakpad!.*" { print $3; }' "$BUILD_LOG")
|
||||||
|
|
||||||
|
if [ -z "$LOCATIONS" ]; then
|
||||||
|
if [ "$VERBOSE" -lt 1 ]; then
|
||||||
|
cat "$BUILD_LOG"
|
||||||
|
fi
|
||||||
|
panic "No source location found in stack trace!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Now check that they all match "[<source file>"
|
||||||
|
BAD_LOCATIONS=
|
||||||
|
for LOCATION in $LOCATIONS; do
|
||||||
|
case $LOCATION in
|
||||||
|
# Escape the opening bracket, or some shells like Dash will not
|
||||||
|
# match them properly.
|
||||||
|
\[*.cpp|\[*.cc|\[*.h) # These are valid source locations in our executable
|
||||||
|
;;
|
||||||
|
*) # Everything else is not!
|
||||||
|
BAD_LOCATIONS="$BAD_LOCATIONS $LOCATION"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$BAD_LOCATIONS" ]; then
|
||||||
|
dump "ERROR: Generated stack trace doesn't contain valid source locations:"
|
||||||
|
cat "$BUILD_LOG"
|
||||||
|
echo "Bad locations are: $BAD_LOCATIONS"
|
||||||
|
clean_exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "All clear! Congratulations."
|
||||||
|
clean_exit 0
|
32
android/sample_app/README
Normal file
32
android/sample_app/README
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
This is a sample Android executable that can be used to test the
|
||||||
|
Google Breakpad client library on Android.
|
||||||
|
|
||||||
|
Its purpose is simply to crash and generate a minidump under /data/local/tmp.
|
||||||
|
|
||||||
|
Build instructions:
|
||||||
|
|
||||||
|
cd android/sample_app
|
||||||
|
$NDK/ndk-build
|
||||||
|
|
||||||
|
Where $NDK points to a valid Android NDK installation.
|
||||||
|
|
||||||
|
Usage instructions:
|
||||||
|
|
||||||
|
After buildind the test program, send it to a device, then run it as
|
||||||
|
the shell UID:
|
||||||
|
|
||||||
|
adb push libs/armeabi/test_google_breakpad /data/local/tmp
|
||||||
|
adb shell /data/local/tmp/test_google_breakpad
|
||||||
|
|
||||||
|
This will simply crash after dumping the name of the generated minidump
|
||||||
|
file.
|
||||||
|
|
||||||
|
See jni/test_breakpad.cpp for details.
|
||||||
|
|
||||||
|
Use 'armeabi-v7a' instead of 'armeabi' above to test the ARMv7-A version
|
||||||
|
of the binary.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
If you plan to use the library in a regular Android application, store
|
||||||
|
the minidump files either to your app-specific directory, or to the SDCard
|
||||||
|
(the latter requiring a specific permission).
|
44
android/sample_app/jni/Android.mk
Normal file
44
android/sample_app/jni/Android.mk
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# Copyright (c) 2012, Google Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are
|
||||||
|
# met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above
|
||||||
|
# copyright notice, this list of conditions and the following disclaimer
|
||||||
|
# in the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# * Neither the name of Google Inc. nor the names of its
|
||||||
|
# contributors may be used to endorse or promote products derived from
|
||||||
|
# this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
LOCAL_PATH := $(call my-dir)
|
||||||
|
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
LOCAL_MODULE := test_google_breakpad
|
||||||
|
LOCAL_SRC_FILES := test_breakpad.cpp
|
||||||
|
LOCAL_STATIC_LIBRARIES += breakpad_client
|
||||||
|
include $(BUILD_EXECUTABLE)
|
||||||
|
|
||||||
|
# If NDK_MODULE_PATH is defined, import the module, otherwise do a direct
|
||||||
|
# includes. This allows us to build in all scenarios easily.
|
||||||
|
ifneq ($(NDK_MODULE_PATH),)
|
||||||
|
$(call import-module,google_breakpad)
|
||||||
|
else
|
||||||
|
include $(LOCAL_PATH)/../../google_breakpad/Android.mk
|
||||||
|
endif
|
31
android/sample_app/jni/Application.mk
Normal file
31
android/sample_app/jni/Application.mk
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
# Copyright (c) 2012, Google Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are
|
||||||
|
# met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above
|
||||||
|
# copyright notice, this list of conditions and the following disclaimer
|
||||||
|
# in the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# * Neither the name of Google Inc. nor the names of its
|
||||||
|
# contributors may be used to endorse or promote products derived from
|
||||||
|
# this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
APP_STL := stlport_static
|
||||||
|
APP_ABI := armeabi armeabi-v7a
|
55
android/sample_app/jni/test_breakpad.cpp
Normal file
55
android/sample_app/jni/test_breakpad.cpp
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
// Copyright (c) 2012, Google Inc.
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following disclaimer
|
||||||
|
// in the documentation and/or other materials provided with the
|
||||||
|
// distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived from
|
||||||
|
// this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "client/linux/handler/exception_handler.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool DumpCallback(const char* dump_path,
|
||||||
|
const char* minidump_id,
|
||||||
|
void* context,
|
||||||
|
bool succeeded) {
|
||||||
|
printf("Dump path: %s/%s.dmp\n", dump_path, minidump_id);
|
||||||
|
return succeeded;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Crash() {
|
||||||
|
volatile int* a = reinterpret_cast<volatile int*>(NULL);
|
||||||
|
*a = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
google_breakpad::ExceptionHandler eh(".", NULL, DumpCallback, NULL, true);
|
||||||
|
Crash();
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in a new issue