Port the util library to Android

With this change, it is possible to build crashpad_util for Android with
clang. I built with NDK 13b (clang 3.8) at API 24 (current), API 21
(used by Chrome in 64-bit builds), and API 16 (used by Chrome in 32-bit
builds).

 - In WeakFileHandleFileWriter::WriteIoVec(): Android does not expose
   the IOV_MAX macro, but its value can be obtained by calling
   sysconf(_SC_IOV_MAX).
 - In CloseMultipleNowOrOnExec(): API 21 removes getdtablesize(). Skip
   it, because it returned the same thing as sysconf(_SC_OPEN_MAX),
   which is already consulted.
 - Throughout: Various #ifdefs checking for OS_LINUX have been extended
   to also check for OS_ANDROID. In Chrome’s build_config.h (and thus
   mini_chromium’s), OS_LINUX is not defined when OS_ANDROID is.

This has not been tested beyond building the crashpad_util target.

BUG=crashpad:30

Change-Id: Ieb0bed736029d2d776c534e30e534f186e6fb663
Reviewed-on: https://chromium-review.googlesource.com/405267
Reviewed-by: Robert Sesek <rsesek@chromium.org>
This commit is contained in:
Mark Mentovai 2016-10-31 11:23:00 -04:00
parent f735d050c4
commit e956a8252f
6 changed files with 30 additions and 12 deletions

View File

@ -73,9 +73,19 @@ bool WeakFileHandleFileWriter::WriteIoVec(std::vector<WritableIoVec>* iovecs) {
iovec* iov = reinterpret_cast<iovec*>(&(*iovecs)[0]);
size_t remaining_iovecs = iovecs->size();
#if defined(OS_ANDROID)
// Android does not expose the IOV_MAX macro, but makes its value available
// via sysconf(). See Android 7.0.0 bionic/libc/bionic/sysconf.cpp sysconf().
// Bionic defines IOV_MAX at bionic/libc/include/limits.h, but does not ship
// this file to the NDK as <limits.h>, substituting
// bionic/libc/include/bits/posix_limits.h.
const size_t kIovMax = sysconf(_SC_IOV_MAX);
#else
const size_t kIovMax = IOV_MAX;
#endif
while (size > 0) {
size_t writev_iovec_count =
std::min(remaining_iovecs, implicit_cast<size_t>(IOV_MAX));
size_t writev_iovec_count = std::min(remaining_iovecs, kIovMax);
ssize_t written =
HANDLE_EINTR(writev(file_handle_, iov, writev_iovec_count));
if (written < 0) {

View File

@ -111,7 +111,7 @@ bool UUID::InitializeWithNew() {
}
InitializeFromSystemUUID(&system_uuid);
return true;
#elif defined(OS_LINUX)
#elif defined(OS_LINUX) || defined(OS_ANDROID)
// Linux does not provide a UUID generator in a widely-available system
// library. uuid_generate() from libuuid is not available everywhere.
base::RandBytes(this, sizeof(*this));

View File

@ -88,7 +88,7 @@ using ScopedDIR = std::unique_ptr<DIR, ScopedDIRCloser>;
bool CloseMultipleNowOrOnExecUsingFDDir(int fd, int preserve_fd) {
#if defined(OS_MACOSX)
const char kFDDir[] = "/dev/fd";
#elif defined(OS_LINUX)
#elif defined(OS_LINUX) || defined(OS_ANDROID)
const char kFDDir[] = "/proc/self/fd";
#endif
@ -167,9 +167,17 @@ void CloseMultipleNowOrOnExec(int fd, int preserve_fd) {
// Libc-1082.50.1/gen/FreeBSD/sysconf.c sysconf() and 10.11.6
// xnu-3248.60.10/bsd/kern/kern_descrip.c getdtablesize(). For Linux glibc,
// see glibc-2.24/sysdeps/posix/sysconf.c __sysconf() and
// glibc-2.24/sysdeps/posix/getdtsz.c __getdtablesize().
// glibc-2.24/sysdeps/posix/getdtsz.c __getdtablesize(). For Android, see
// 7.0.0 bionic/libc/bionic/sysconf.cpp sysconf() and
// bionic/libc/bionic/ndk_cruft.cpp getdtablesize().
int max_fd = implicit_cast<int>(sysconf(_SC_OPEN_MAX));
#if !defined(OS_ANDROID)
// getdtablesize() was removed effective Android 5.0.0 (API 21). Since it
// returns the same thing as the sysconf() above, just skip it. See
// https://android.googlesource.com/platform/bionic/+/462abab12b074c62c0999859e65d5a32ebb41951.
max_fd = std::max(max_fd, getdtablesize());
#endif
#if !defined(OS_LINUX) || defined(OPEN_MAX)
// Linux does not provide OPEN_MAX. See
@ -198,7 +206,7 @@ void CloseMultipleNowOrOnExec(int fd, int preserve_fd) {
} else {
PLOG(WARNING) << "sysctl";
}
#elif defined(OS_LINUX)
#elif defined(OS_LINUX) || defined(OS_ANDROID)
// See linux-4.4.27/fs/file.c sysctl_nr_open, referenced by kernel/sys.c
// do_prlimit() and kernel/sysctl.c fs_table. Inability to open this file is
// not considered an error, because /proc may not be available or usable.

View File

@ -71,7 +71,7 @@ void DropPrivileges() {
CHECK_EQ(setegid(egid), -1);
}
}
#elif defined(OS_LINUX)
#elif defined(OS_LINUX) || defined(OS_ANDROID)
PCHECK(setresgid(gid, gid, gid) == 0) << "setresgid";
PCHECK(setresuid(uid, uid, uid) == 0) << "setresuid";

View File

@ -14,9 +14,9 @@
#include "util/posix/symbolic_constants_posix.h"
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include <sys/signal.h>
#include "base/macros.h"
#include "base/strings/stringprintf.h"
@ -64,7 +64,7 @@ const char* kSignalNames[] = {
"INFO",
"USR1",
"USR2",
#elif defined(OS_LINUX)
#elif defined(OS_LINUX) || defined(OS_ANDROID)
// sed -Ene 's/^#define[[:space:]]SIG([[:alnum:]]+)[[:space:]]+[[:digit:]]{1,2}([[:space:]]|$).*/ "\1",/p'
// /usr/include/asm-generic/signal.h
// and fix up by removing SIGIOT, SIGLOST, SIGUNUSED, and SIGRTMIN.
@ -101,7 +101,7 @@ const char* kSignalNames[] = {
"SYS",
#endif
};
#if defined(OS_LINUX)
#if defined(OS_LINUX) || defined(OS_ANDROID)
// NSIG is 64 to account for real-time signals.
static_assert(arraysize(kSignalNames) == 32, "kSignalNames length");
#else

View File

@ -65,7 +65,7 @@ const struct {
#if defined(OS_MACOSX)
{SIGEMT, "SIGEMT", "EMT"},
{SIGINFO, "SIGINFO", "INFO"},
#elif defined(OS_LINUX)
#elif defined(OS_LINUX) || defined(OS_ANDROID)
{SIGPWR, "SIGPWR", "PWR"},
{SIGSTKFLT, "SIGSTKFLT", "STKFLT"},
#endif
@ -120,7 +120,7 @@ TEST(SymbolicConstantsPOSIX, SignalToString) {
kSignalTestData[index].short_name);
}
#if defined(OS_LINUX)
#if defined(OS_LINUX) || defined(OS_ANDROID)
// NSIG is 64 to account for real-time signals.
const int kSignalCount = 32;
#else