diff --git a/configure b/configure index ac9dc080..eaa623f7 100755 --- a/configure +++ b/configure @@ -5092,7 +5092,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu # Only build Linux client libs when compiling for Linux case $host in - *-*-linux*) + *-*-linux* | *-android* ) LINUX_HOST=true ;; esac diff --git a/configure.ac b/configure.ac index 73cee881..1b30b062 100644 --- a/configure.ac +++ b/configure.ac @@ -52,7 +52,7 @@ AX_PTHREAD # Only build Linux client libs when compiling for Linux case $host in - *-*-linux*) + *-*-linux* | *-android* ) LINUX_HOST=true ;; esac diff --git a/src/client/linux/android_link.h b/src/client/linux/android_link.h new file mode 100644 index 00000000..430ac3b6 --- /dev/null +++ b/src/client/linux/android_link.h @@ -0,0 +1,44 @@ +// Copyright (c) 2010, 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. + +// The Android NDK doesn't have link.h. Fortunately, the only thing +// that Breakpad uses from it is the ElfW macro, so define it here. + +#ifndef GOOGLE_BREAKPAD_CLIENT_LINUX_ANDROID_LINK_H_ +#define GOOGLE_BREAKPAD_CLIENT_LINUX_ANDROID_LINK_H_ + +#include + +#ifndef ElfW +#define ElfW(type) _ElfW (Elf, ELFSIZE, type) +#define _ElfW(e,w,t) _ElfW_1 (e, w, _##t) +#define _ElfW_1(e,w,t) e##w##t +#endif + +#endif // GOOGLE_BREAKPAD_CLIENT_LINUX_ANDROID_LINK_H_ diff --git a/src/client/linux/android_ucontext.h b/src/client/linux/android_ucontext.h new file mode 100644 index 00000000..30a4e6c2 --- /dev/null +++ b/src/client/linux/android_ucontext.h @@ -0,0 +1,77 @@ +// Copyright (c) 2009, 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. + +// Android runs a fairly new Linux kernel, so signal info is there, +// but the NDK doesn't have the structs defined, so define +// them here. +// Adapted from platform-linux.cc in V8 + +#ifndef GOOGLE_BREAKPAD_CLIENT_LINUX_ANDROID_UCONTEXT_H_ +#define GOOGLE_BREAKPAD_CLIENT_LINUX_ANDROID_UCONTEXT_H_ + +#include + +#if !defined(__GLIBC__) && (defined(__arm__) || defined(__thumb__)) + +struct sigcontext { + uint32_t trap_no; + uint32_t error_code; + uint32_t oldmask; + uint32_t arm_r0; + uint32_t arm_r1; + uint32_t arm_r2; + uint32_t arm_r3; + uint32_t arm_r4; + uint32_t arm_r5; + uint32_t arm_r6; + uint32_t arm_r7; + uint32_t arm_r8; + uint32_t arm_r9; + uint32_t arm_r10; + uint32_t arm_fp; + uint32_t arm_ip; + uint32_t arm_sp; + uint32_t arm_lr; + uint32_t arm_pc; + uint32_t arm_cpsr; + uint32_t fault_address; +}; +typedef uint32_t __sigset_t; +typedef struct sigcontext mcontext_t; +typedef struct ucontext { + uint32_t uc_flags; + struct ucontext* uc_link; + stack_t uc_stack; + mcontext_t uc_mcontext; + __sigset_t uc_sigmask; +} ucontext_t; + +#endif + +#endif // GOOGLE_BREAKPAD_CLIENT_LINUX_ANDROID_UCONTEXT_H_ diff --git a/src/client/linux/handler/exception_handler.cc b/src/client/linux/handler/exception_handler.cc index 57da0c56..592c9e5b 100644 --- a/src/client/linux/handler/exception_handler.cc +++ b/src/client/linux/handler/exception_handler.cc @@ -73,12 +73,18 @@ #include #include #include +#if !defined(__ANDROID__) #include +#endif #include +#if !defined(__ANDROID__) #include #include +#endif #include +#if !defined(__ANDROID__) #include +#endif #include #include @@ -186,7 +192,7 @@ bool ExceptionHandler::InstallHandlers() { stack.ss_sp = signal_stack; stack.ss_size = kSigStackSize; - if (sigaltstack(&stack, NULL) == -1) + if (sys_sigaltstack(&stack, NULL) == -1) return false; struct sigaction sa; @@ -322,7 +328,7 @@ bool ExceptionHandler::HandleSignal(int sig, siginfo_t* info, void* uc) { return false; // Allow ourselves to be dumped. - prctl(PR_SET_DUMPABLE, 1); + sys_prctl(PR_SET_DUMPABLE, 1); CrashContext context; memcpy(&context.siginfo, info, sizeof(siginfo_t)); memcpy(&context.context, uc, sizeof(struct ucontext)); diff --git a/src/client/linux/handler/exception_handler.h b/src/client/linux/handler/exception_handler.h index b450403a..82f7fb4c 100644 --- a/src/client/linux/handler/exception_handler.h +++ b/src/client/linux/handler/exception_handler.h @@ -33,9 +33,13 @@ #include #include +#include #include #include +#if defined(__ANDROID__) +#include "client/linux/android_ucontext.h" +#endif #include "client/linux/crash_generation/crash_generation_client.h" #include "processor/scoped_ptr.h" diff --git a/src/client/linux/handler/exception_handler_unittest.cc b/src/client/linux/handler/exception_handler_unittest.cc index c8879fcb..e1186698 100644 --- a/src/client/linux/handler/exception_handler_unittest.cc +++ b/src/client/linux/handler/exception_handler_unittest.cc @@ -36,6 +36,7 @@ #include #include #include +#include #include "breakpad_googletest_includes.h" #include "client/linux/handler/exception_handler.h" @@ -47,6 +48,12 @@ using namespace google_breakpad; +#if !defined(__ANDROID__) +#define TEMPDIR "/tmp" +#else +#define TEMPDIR "/data/local/tmp" +#endif + static void sigchld_handler(int signo) { } class ExceptionHandlerTest : public ::testing::Test { @@ -67,7 +74,7 @@ class ExceptionHandlerTest : public ::testing::Test { }; TEST(ExceptionHandlerTest, Simple) { - ExceptionHandler handler("/tmp", NULL, NULL, NULL, true); + ExceptionHandler handler(TEMPDIR, NULL, NULL, NULL, true); } static bool DoneCallback(const char* dump_path, @@ -93,7 +100,7 @@ TEST(ExceptionHandlerTest, ChildCrash) { const pid_t child = fork(); if (child == 0) { close(fds[0]); - ExceptionHandler handler("/tmp", NULL, DoneCallback, (void*) fds[1], + ExceptionHandler handler(TEMPDIR, NULL, DoneCallback, (void*) fds[1], true); *reinterpret_cast(NULL) = 0; } @@ -121,7 +128,7 @@ TEST(ExceptionHandlerTest, ChildCrash) { filename[len] = 0; close(fds[0]); - const std::string minidump_filename = std::string("/tmp/") + filename + + const std::string minidump_filename = std::string(TEMPDIR) + "/" + filename + ".dmp"; struct stat st; @@ -146,7 +153,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemory) { const pid_t child = fork(); if (child == 0) { close(fds[0]); - ExceptionHandler handler("/tmp", NULL, DoneCallback, (void*) fds[1], + ExceptionHandler handler(TEMPDIR, NULL, DoneCallback, (void*) fds[1], true); // Get some executable memory. char* memory = @@ -194,7 +201,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemory) { filename[len] = 0; close(fds[0]); - const std::string minidump_filename = std::string("/tmp/") + filename + + const std::string minidump_filename = std::string(TEMPDIR) + "/" + filename + ".dmp"; struct stat st; @@ -270,7 +277,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryMinBound) { const pid_t child = fork(); if (child == 0) { close(fds[0]); - ExceptionHandler handler("/tmp", NULL, DoneCallback, (void*) fds[1], + ExceptionHandler handler(TEMPDIR, NULL, DoneCallback, (void*) fds[1], true); // Get some executable memory. char* memory = @@ -318,7 +325,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryMinBound) { filename[len] = 0; close(fds[0]); - const std::string minidump_filename = std::string("/tmp/") + filename + + const std::string minidump_filename = std::string(TEMPDIR) + "/" + filename + ".dmp"; struct stat st; @@ -394,7 +401,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryMaxBound) { const pid_t child = fork(); if (child == 0) { close(fds[0]); - ExceptionHandler handler("/tmp", NULL, DoneCallback, (void*) fds[1], + ExceptionHandler handler(TEMPDIR, NULL, DoneCallback, (void*) fds[1], true); // Get some executable memory. char* memory = @@ -442,7 +449,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryMaxBound) { filename[len] = 0; close(fds[0]); - const std::string minidump_filename = std::string("/tmp/") + filename + + const std::string minidump_filename = std::string(TEMPDIR) + "/" + filename + ".dmp"; struct stat st; @@ -510,7 +517,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryNullPointer) { const pid_t child = fork(); if (child == 0) { close(fds[0]); - ExceptionHandler handler("/tmp", NULL, DoneCallback, (void*) fds[1], + ExceptionHandler handler(TEMPDIR, NULL, DoneCallback, (void*) fds[1], true); // Try calling a NULL pointer. typedef void (*void_function)(void); @@ -542,7 +549,7 @@ TEST(ExceptionHandlerTest, InstructionPointerMemoryNullPointer) { filename[len] = 0; close(fds[0]); - const std::string minidump_filename = std::string("/tmp/") + filename + + const std::string minidump_filename = std::string(TEMPDIR) + "/" + filename + ".dmp"; struct stat st; @@ -663,7 +670,7 @@ TEST(ExceptionHandlerTest, ExternalDumper) { ASSERT_NE(crashing_pid, -1); ASSERT_NE(signal_fd, -1); - char templ[] = "/tmp/exception-handler-unittest-XXXXXX"; + char templ[] = TEMPDIR "/exception-handler-unittest-XXXXXX"; mktemp(templ); ASSERT_TRUE(WriteMinidump(templ, crashing_pid, context, kCrashContextSize)); diff --git a/src/client/linux/minidump_writer/line_reader_unittest.cc b/src/client/linux/minidump_writer/line_reader_unittest.cc index 7c4c3ced..a2ea17f7 100644 --- a/src/client/linux/minidump_writer/line_reader_unittest.cc +++ b/src/client/linux/minidump_writer/line_reader_unittest.cc @@ -36,8 +36,14 @@ using namespace google_breakpad; +#if !defined(__ANDROID__) +#define TEMPDIR "/tmp" +#else +#define TEMPDIR "/data/local/tmp" +#endif + static int TemporaryFile() { - static const char templ[] = "/tmp/line-reader-unittest-XXXXXX"; + static const char templ[] = TEMPDIR "/line-reader-unittest-XXXXXX"; char templ_copy[sizeof(templ)]; memcpy(templ_copy, templ, sizeof(templ)); const int fd = mkstemp(templ_copy); diff --git a/src/client/linux/minidump_writer/linux_dumper.cc b/src/client/linux/minidump_writer/linux_dumper.cc index b7ee1c4d..11b6a18b 100644 --- a/src/client/linux/minidump_writer/linux_dumper.cc +++ b/src/client/linux/minidump_writer/linux_dumper.cc @@ -45,7 +45,9 @@ #include #include #include +#if !defined(__ANDROID__) #include +#endif #include #include @@ -388,11 +390,16 @@ bool LinuxDumper::ThreadInfoGet(pid_t tid, ThreadInfo* info) { if (info->ppid == -1 || info->tgid == -1) return false; - if (sys_ptrace(PTRACE_GETREGS, tid, NULL, &info->regs) == -1 || - sys_ptrace(PTRACE_GETFPREGS, tid, NULL, &info->fpregs) == -1) { + if (sys_ptrace(PTRACE_GETREGS, tid, NULL, &info->regs) == -1) { return false; } +#if !defined(__ANDROID__) + if (sys_ptrace(PTRACE_GETFPREGS, tid, NULL, &info->fpregs) == -1) { + return false; + } +#endif + #if defined(__i386) if (sys_ptrace(PTRACE_GETFPXREGS, tid, NULL, &info->fpxregs) == -1) return false; @@ -417,7 +424,7 @@ bool LinuxDumper::ThreadInfoGet(pid_t tid, ThreadInfo* info) { #elif defined(__x86_64) memcpy(&stack_pointer, &info->regs.rsp, sizeof(info->regs.rsp)); #elif defined(__ARM_EABI__) - memcpy(&stack_pointer, &info->regs.uregs[R13], sizeof(info->regs.uregs[R13])); + memcpy(&stack_pointer, &info->regs.ARM_sp, sizeof(info->regs.ARM_sp)); #else #error "This code hasn't been ported to your platform yet." #endif diff --git a/src/client/linux/minidump_writer/linux_dumper.h b/src/client/linux/minidump_writer/linux_dumper.h index b0c479a9..71d1188f 100644 --- a/src/client/linux/minidump_writer/linux_dumper.h +++ b/src/client/linux/minidump_writer/linux_dumper.h @@ -34,18 +34,38 @@ #include #include #include +#if !defined(__ANDROID__) #include +#endif #include "common/memory.h" #include "google_breakpad/common/minidump_format.h" namespace google_breakpad { +#if defined(__i386) || defined(__x86_64) typedef typeof(((struct user*) 0)->u_debugreg[0]) debugreg_t; +#endif // Typedef for our parsing of the auxv variables in /proc/pid/auxv. #if defined(__i386) || defined(__ARM_EABI__) +#if !defined(__ANDROID__) typedef Elf32_auxv_t elf_aux_entry; +#else +// Android is missing this structure definition +typedef struct +{ + uint32_t a_type; /* Entry type */ + union + { + uint32_t a_val; /* Integer value */ + } a_un; +} elf_aux_entry; + +#if !defined(AT_SYSINFO_EHDR) +#define AT_SYSINFO_EHDR 33 +#endif +#endif // __ANDROID__ #elif defined(__x86_64__) typedef Elf64_auxv_t elf_aux_entry; #endif @@ -76,8 +96,12 @@ struct ThreadInfo { #elif defined(__ARM_EABI__) // Mimicking how strace does this(see syscall.c, search for GETREGS) +#if defined(__ANDROID__) + struct pt_regs regs; +#else struct user_regs regs; struct user_fpregs fpregs; +#endif // __ANDROID__ #endif }; diff --git a/src/client/linux/minidump_writer/linux_dumper_unittest.cc b/src/client/linux/minidump_writer/linux_dumper_unittest.cc index 8cfb6004..b81291b6 100644 --- a/src/client/linux/minidump_writer/linux_dumper_unittest.cc +++ b/src/client/linux/minidump_writer/linux_dumper_unittest.cc @@ -27,6 +27,8 @@ // (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 + #include #include #include @@ -37,6 +39,7 @@ #include "common/linux/file_id.h" #include "common/memory.h" +using std::string; using namespace google_breakpad; // This provides a wrapper around system calls which may be @@ -87,21 +90,36 @@ TEST(LinuxDumperTest, VerifyStackReadWithMultipleThreads) { pid_t child_pid = fork(); if (child_pid == 0) { + // Locate helper binary next to the current binary. + char self_path[PATH_MAX]; + if (readlink("/proc/self/exe", self_path, sizeof(self_path) - 1) == -1) { + FAIL() << "readlink failed: " << strerror(errno); + exit(1); + } + string helper_path(self_path); + size_t pos = helper_path.rfind('/'); + if (pos == string::npos) { + FAIL() << "no trailing slash in path: " << helper_path; + exit(1); + } + helper_path.erase(pos + 1); + helper_path += "linux_dumper_unittest_helper"; + // Set the number of threads - execl("src/client/linux/linux_dumper_unittest_helper", + execl(helper_path.c_str(), "linux_dumper_unittest_helper", kNumberOfThreadsArgument, NULL); // Kill if we get here. printf("Errno from exec: %d", errno); - FAIL() << "Exec failed: " << strerror(errno); + FAIL() << "Exec of " << helper_path << " failed: " << strerror(errno); exit(0); } // The sleep is flaky, but prevents us from reading // the child process before all threads have been created. sleep(1); LinuxDumper dumper(child_pid); - EXPECT_TRUE(dumper.Init()); + ASSERT_TRUE(dumper.Init()); EXPECT_EQ((size_t)kNumberOfThreadsInHelperProgram, dumper.threads().size()); EXPECT_TRUE(dumper.ThreadsSuspend()); diff --git a/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc b/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc index e91e9767..6b7ad5a2 100644 --- a/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc +++ b/src/client/linux/minidump_writer/linux_dumper_unittest_helper.cc @@ -37,6 +37,8 @@ #include #include +#include "third_party/lss/linux_syscall_support.h" + #if defined(__ARM_EABI__) #define TID_PTR_REGISTER "r3" #elif defined(__i386) @@ -48,7 +50,7 @@ #endif void *thread_function(void *data) { - volatile pid_t thread_id = syscall(SYS_gettid); + volatile pid_t thread_id = syscall(__NR_gettid); register volatile pid_t *thread_id_ptr asm(TID_PTR_REGISTER) = &thread_id; while (true) asm volatile ("" : : "r" (thread_id_ptr)); diff --git a/src/client/linux/minidump_writer/minidump_writer.cc b/src/client/linux/minidump_writer/minidump_writer.cc index d629ee81..9deed20b 100644 --- a/src/client/linux/minidump_writer/minidump_writer.cc +++ b/src/client/linux/minidump_writer/minidump_writer.cc @@ -50,11 +50,15 @@ #include #include +#if !defined(__ANDROID__) #include +#endif #include #include +#if !defined(__ANDROID__) #include #include +#endif #include #include "client/minidump_file_writer.h" @@ -62,6 +66,10 @@ #include "google_breakpad/common/minidump_cpu_amd64.h" #include "google_breakpad/common/minidump_cpu_x86.h" +#if defined(__ANDROID__) +#include "client/linux/android_link.h" +#include "client/linux/android_ucontext.h" +#endif #include "client/linux/handler/exception_handler.h" #include "client/linux/minidump_writer/line_reader.h" #include "client/linux/minidump_writer/linux_dumper.h" @@ -311,11 +319,13 @@ static void CPUFillFromThreadInfo(MDRawContextARM *out, out->iregs[i] = info.regs.uregs[i]; // No CPSR register in ThreadInfo(it's not accessible via ptrace) out->cpsr = 0; +#if !defined(__ANDROID__) out->float_save.fpscr = info.fpregs.fpsr | (static_cast(info.fpregs.fpcr) << 32); //TODO: sort this out, actually collect floating point registers memset(&out->float_save.regs, 0, sizeof(out->float_save.regs)); memset(&out->float_save.extra, 0, sizeof(out->float_save.extra)); +#endif } static void CPUFillFromUContext(MDRawContextARM *out, const ucontext *uc, @@ -389,7 +399,9 @@ class MinidumpWriter { // it to a MD_LINUX_DSO_DEBUG stream. struct r_debug* r_debug = NULL; uint32_t dynamic_length = 0; - +#if !defined(__ANDROID__) + // The Android NDK is missing structure definitions for most of this. + // For now, it's simpler just to skip it. for (int i = 0;;) { ElfW(Dyn) dyn; dynamic_length += sizeof(dyn); @@ -400,6 +412,7 @@ class MinidumpWriter { } else if (dyn.d_tag == DT_NULL) break; } +#endif // A minidump file contains a number of tagged streams. This is the number // of stream which we write. @@ -866,6 +879,9 @@ class MinidumpWriter { bool WriteDSODebugStream(MDRawDirectory* dirent, struct r_debug* r_debug, uint32_t dynamic_length) { +#if defined(__ANDROID__) + return false; +#else // The caller provided us with a pointer to "struct r_debug". We can // look up the "r_map" field to get a linked list of all loaded DSOs. // Our list of DSOs potentially is different from the ones in the crashing @@ -939,6 +955,7 @@ class MinidumpWriter { delete[] dso_debug_data; return true; +#endif } private: diff --git a/src/client/linux/minidump_writer/minidump_writer_unittest.cc b/src/client/linux/minidump_writer/minidump_writer_unittest.cc index 0c02f587..e7a62145 100644 --- a/src/client/linux/minidump_writer/minidump_writer_unittest.cc +++ b/src/client/linux/minidump_writer/minidump_writer_unittest.cc @@ -37,6 +37,12 @@ using namespace google_breakpad; +#if !defined(__ANDROID__) +#define TEMPDIR "/tmp" +#else +#define TEMPDIR "/data/local/tmp" +#endif + namespace { typedef testing::Test MinidumpWriterTest; } @@ -58,7 +64,7 @@ TEST(MinidumpWriterTest, Setup) { ExceptionHandler::CrashContext context; memset(&context, 0, sizeof(context)); - char templ[] = "/tmp/minidump-writer-unittest-XXXXXX"; + char templ[] = TEMPDIR "/minidump-writer-unittest-XXXXXX"; mktemp(templ); ASSERT_TRUE(WriteMinidump(templ, child, &context, sizeof(context))); struct stat st; diff --git a/src/common/linux/file_id.cc b/src/common/linux/file_id.cc index b04c831e..2227c83b 100644 --- a/src/common/linux/file_id.cc +++ b/src/common/linux/file_id.cc @@ -38,7 +38,11 @@ #include #include #include +#if defined(__ANDROID__) +#include "client/linux/android_link.h" +#else #include +#endif #include #include #include