Commit 28bf600d authored by Joshua Peraza's avatar Joshua Peraza Committed by Commit Bot

Update Crashpad to edbbc4609d2d0703ed73ba9293971f1346234313

e97cf7b29c16 update gyp_crashpad_android.py
2bfd3c4edcff [POSIX] stop logging on ENOENT
12bc30cdf58a Check if attachment directories exist before open
edbbc4609d2d chromeos: fix typo

Change-Id: Icb1d0ca0eaf1aa854ac9fcdd083b75f8ec8ec59e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1809512Reviewed-by: default avatarMark Mentovai <mark@chromium.org>
Commit-Queue: Joshua Peraza <jperaza@chromium.org>
Cr-Commit-Position: refs/heads/master@{#697458}
parent 0cc96a73
......@@ -2,7 +2,7 @@ Name: Crashpad
Short Name: crashpad
URL: https://crashpad.chromium.org/
Version: unknown
Revision: 06fdbdecdc5d94989543bcec197752fdea2fbd9d
Revision: edbbc4609d2d0703ed73ba9293971f1346234313
License: Apache 2.0
License File: crashpad/LICENSE
Security Critical: yes
......
......@@ -28,82 +28,45 @@ def main(args):
parser = argparse.ArgumentParser(
description='Set up an Android cross build',
epilog='Additional arguments will be passed to gyp_crashpad.py.')
parser.add_argument('--arch', required=True, help='Target architecture')
parser.add_argument('--api-level', required=True, help='Target API level')
parser.add_argument('--ndk', required=True, help='Standalone NDK toolchain')
parser.add_argument('--compiler',
default='clang',
choices=('clang', 'gcc'),
help='The compiler to use, clang by default')
(parsed, extra_command_line_args) = parser.parse_known_args(args)
NDK_ERROR=(
'NDK must be a valid standalone NDK toolchain.\n' +
'See https://developer.android.com/ndk/guides/standalone_toolchain.html')
arch_dirs = glob.glob(os.path.join(parsed.ndk, '*-linux-android*'))
if len(arch_dirs) != 1:
parser.error(NDK_ERROR)
ndk_bin_dir = os.path.join(parsed.ndk,
'toolchains',
'llvm',
'prebuilt',
'linux-x86_64',
'bin')
if not os.path.exists(ndk_bin_dir):
parser.error("missing toolchain")
arch_triplet = os.path.basename(arch_dirs[0])
ARCH_TRIPLET_TO_ARCH = {
'arm-linux-androideabi': 'arm',
'aarch64-linux-android': 'arm64',
'i686-linux-android': 'ia32',
'x86_64-linux-android': 'x64',
'mipsel-linux-android': 'mips',
'mips64el-linux-android': 'mips64',
ARCH_TO_ARCH_TRIPLET = {
'arm': 'armv7a-linux-androideabi',
'arm64': 'aarch64-linux-android',
'ia32': 'i686-linux-android',
'x64': 'x86_64-linux-android',
}
if arch_triplet not in ARCH_TRIPLET_TO_ARCH:
parser.error(NDK_ERROR)
arch = ARCH_TRIPLET_TO_ARCH[arch_triplet]
ndk_bin_dir = os.path.join(parsed.ndk, 'bin')
clang_prefix = ARCH_TO_ARCH_TRIPLET[parsed.arch] + parsed.api_level
os.environ['CC_target'] = os.path.join(ndk_bin_dir, clang_prefix + '-clang')
os.environ['CXX_target'] = os.path.join(ndk_bin_dir, clang_prefix + '-clang++')
clang_path = os.path.join(ndk_bin_dir, 'clang')
extra_args = []
extra_args = ['-D', 'android_api_level=' + parsed.api_level]
if parsed.compiler == 'clang':
os.environ['CC_target'] = clang_path
os.environ['CXX_target'] = os.path.join(ndk_bin_dir, 'clang++')
elif parsed.compiler == 'gcc':
os.environ['CC_target'] = os.path.join(ndk_bin_dir,
'%s-gcc' % arch_triplet)
os.environ['CXX_target'] = os.path.join(ndk_bin_dir,
'%s-g++' % arch_triplet)
# Unlike the Clang build, when using GCC with unified headers, __ANDROID_API__
# isn’t set automatically and must be pushed in to the build. Fish the correct
# value out of the Clang wrapper script. If deprecated headers are in use, the
# Clang wrapper won’t mention __ANDROID_API__, but the standalone toolchain’s
# <android/api-level.h> will #define it for both Clang and GCC.
#
# android_api_level is extracted in this manner even when compiling with Clang
# so that it’s available for use in GYP conditions that need to test the API
# level, but beware that it’ll only be available when unified headers are in
# use.
#
# Unified headers are the way of the future, according to
# https://android.googlesource.com/platform/ndk/+/ndk-r14/CHANGELOG.md and
# https://android.googlesource.com/platform/ndk/+/master/docs/UnifiedHeaders.md.
# Traditional (deprecated) headers have been removed entirely as of NDK r16.
# https://android.googlesource.com/platform/ndk/+/ndk-release-r16/CHANGELOG.md.
with open(clang_path, 'r') as file:
clang_script_contents = file.read()
matches = re.finditer(r'\s-D__ANDROID_API__=([\d]+)\s',
clang_script_contents)
match = next(matches, None)
if match:
android_api = int(match.group(1))
extra_args.extend(['-D', 'android_api_level=%d' % android_api])
if next(matches, None):
raise AssertionError('__ANDROID_API__ defined too many times')
# ARM only includes 'v7a' in the tool prefix for clang
tool_prefix = ('arm-linux-androideabi' if parsed.arch == 'arm'
else ARCH_TO_ARCH_TRIPLET[parsed.arch])
for tool in ('ar', 'nm', 'readelf'):
os.environ['%s_target' % tool.upper()] = (
os.path.join(ndk_bin_dir, '%s-%s' % (arch_triplet, tool)))
os.path.join(ndk_bin_dir, '%s-%s' % (tool_prefix, tool)))
return gyp_crashpad.main(
['-D', 'OS=android',
'-D', 'target_arch=%s' % arch,
'-D', 'clang=%d' % (1 if parsed.compiler == 'clang' else 0),
'-D', 'target_arch=%s' % parsed.arch,
'-D', 'clang=1',
'-f', 'ninja-android'] +
extra_args +
extra_command_line_args)
......
......@@ -173,8 +173,7 @@ off_t GetFileSize(const base::FilePath& filepath) {
void AddAttachmentSize(const base::FilePath& attachments_dir, uint64_t* size) {
// Early return if the attachment directory does not exist.
struct stat statbuf;
if (stat(attachments_dir.value().c_str(), &statbuf) != 0) {
if (!IsDirectory(attachments_dir, /*allow_symlinks=*/false)) {
return;
}
DirectoryReader reader;
......@@ -334,6 +333,9 @@ void CrashReportDatabase::UploadReport::InitializeAttachments() {
base::FilePath attachments_dir =
static_cast<CrashReportDatabaseGeneric*>(database_)->AttachmentsPath(
uuid);
if (!IsDirectory(attachments_dir, /*allow_symlinks=*/false)) {
return;
}
DirectoryReader reader;
if (!reader.Open(attachments_dir)) {
return;
......@@ -873,7 +875,6 @@ void CrashReportDatabaseGeneric::CleanOrphanedAttachments() {
base::FilePath root_attachments_dir(base_dir_.Append(kAttachmentsDirectory));
DirectoryReader reader;
if (!reader.Open(root_attachments_dir)) {
LOG(ERROR) << "no attachments dir";
return;
}
......@@ -914,6 +915,9 @@ void CrashReportDatabaseGeneric::CleanOrphanedAttachments() {
void CrashReportDatabaseGeneric::RemoveAttachmentsByUUID(const UUID& uuid) {
base::FilePath attachments_dir = AttachmentsPath(uuid);
if (!IsDirectory(attachments_dir, /*allow_symlinks=*/false)) {
return;
}
DirectoryReader reader;
if (!reader.Open(attachments_dir)) {
return;
......
......@@ -135,66 +135,38 @@ target_sysroot = "//third_party/linux/sysroot"
### Android
Crashpad’s Android port is in its early stages. This build relies on
cross-compilation. It’s possible to develop Crashpad for Android on any platform
that the [Android NDK (Native Development
Kit)](https://developer.android.com/ndk/) runs on.
This build relies on cross-compilation. It’s possible to develop Crashpad for
Android on any platform that the [Android NDK (Native Development Kit)]
(https://developer.android.com/ndk/) runs on.
If it’s not already present on your system, [download the NDK package for your
system](https://developer.android.com/ndk/downloads/) and expand it to a
suitable location. These instructions assume that it’s been expanded to
`~/android-ndk-r16`.
To build Crashpad, portions of the NDK must be reassembled into a [standalone
toolchain](https://developer.android.com/ndk/guides/standalone_toolchain.html).
This is a repackaged subset of the NDK suitable for cross-compiling for a single
Android architecture (such as `arm`, `arm64`, `x86`, and `x86_64`) targeting a
specific [Android API
level](https://source.android.com/source/build-numbers.html). The standalone
toolchain only needs to be built from the NDK one time for each set of options
desired. To build a standalone toolchain targeting 64-bit ARM and API level 21
(Android 5.0 “Lollipop”), run:
```
$ cd ~
$ python android-ndk-r16/build/tools/make_standalone_toolchain.py \
--arch=arm64 --api=21 --install-dir=android-ndk-r16_arm64_api21
```
`~/android-ndk-r20`.
Note that Chrome uses Android API level 21 for 64-bit platforms and 16 for
32-bit platforms. See Chrome’s
[`build/config/android/config.gni`](https://chromium.googlesource.com/chromium/src/+/master/build/config/android/config.gni)
which sets `_android_api_level` and `_android64_api_level`.
To configure a Crashpad build for Android using the standalone toolchain
assembled above, use `gyp_crashpad_android.py`. This script is a wrapper for
`gyp_crashpad.py` that sets several environment variables directing the build to
the standalone toolchain, and several GYP options to identify an Android build.
This must be done after any `gclient sync`, or instead of any `gclient runhooks`
operation.
To configure a Crashpad build for Android use `gyp_crashpad_android.py`. This
script is a wrapper for `gyp_crashpad.py` that sets several environment
variables directing the build to the toolchain, and several GYP options to
identify an Android build. This must be done after any `gclient sync`, or
instead of any `gclient runhooks` operation.
```
$ cd ~/crashpad/crashpad
$ python build/gyp_crashpad_android.py \
--ndk ~/android-ndk-r16_arm64_api21 \
--generator-output out/android_arm64_api21
python build/gyp_crashpad_android.py \
--ndk ~/usr/lib/android-ndk-r20 --arch arm64 --api-level 21 \
--generator-output=out/android_arm64_api21 \
```
`gyp_crashpad_android.py` detects the build type based on the characteristics of
the standalone toolchain given in its `--ndk` argument.
`gyp_crashpad_android.py` sets the build up to use Clang by default. It’s also
possible to use GCC by providing the `--compiler=gcc` argument to
`gyp_crashpad_android.py`.
The Android port is incomplete, but targets known to be working include
`crashpad_test`, `crashpad_util`, and their tests. This list will grow over
time. To build, direct `ninja` to the specific `out` directory chosen by the
To build, direct `ninja` to the specific `out` directory chosen by the
`--generator-output` argument to `gyp_crashpad_android.py`.
```
$ ninja -C out/android_arm64_api21/out/Debug \
crashpad_test_test crashpad_util_test
$ ninja -C out/android_arm64_api21/out/Debug all
```
## Testing
......
......@@ -39,6 +39,8 @@
'crash_report_upload_thread.h',
'handler_main.cc',
'handler_main.h',
'linux/capture_snapshot.cc',
'linux/capture_snapshot.h',
'linux/crash_report_exception_handler.cc',
'linux/crash_report_exception_handler.h',
'linux/exception_handler_server.cc',
......
......@@ -644,7 +644,7 @@ int HandlerMain(int argc,
kOptionTraceParentWithException},
#endif // OS_LINUX || OS_ANDROID
{"url", required_argument, nullptr, kOptionURL},
#if defined(OS_CHROEMOS)
#if defined(OS_CHROMEOS)
{"use-cros-crash-reporter",
no_argument,
nullptr,
......
......@@ -73,7 +73,8 @@ bool MoveFileOrDirectory(const base::FilePath& source,
//! failure.
//!
//! On POSIX, this function returns `true` if \a path refers to a file that is
//! not a symbolic link, directory, or other kind of special file.
//! not a symbolic link, directory, or other kind of special file. If this
//! function fails because \a path does not exist, then no message is logged.
//!
//! On Windows, this function returns `true` if \a path refers to a file that
//! is not a symbolic link or directory.
......@@ -85,6 +86,9 @@ bool IsRegularFile(const base::FilePath& path);
//! \brief Determines if a path refers to a directory, logging a message on
//! failure.
//!
//! On POSIX, if this function fails because \a path does not exist, then no
//! message is logged.
//!
//! \param[in] path The path to check.
//! \param[in] allow_symlinks Whether to allow the final component in the path
//! to be a symbolic link to a directory.
......
......@@ -76,7 +76,7 @@ bool MoveFileOrDirectory(const base::FilePath& source,
bool IsRegularFile(const base::FilePath& path) {
struct stat st;
if (lstat(path.value().c_str(), &st) != 0) {
PLOG(ERROR) << "stat " << path.value();
PLOG_IF(ERROR, errno != ENOENT) << "stat " << path.value();
return false;
}
return S_ISREG(st.st_mode);
......@@ -86,11 +86,11 @@ bool IsDirectory(const base::FilePath& path, bool allow_symlinks) {
struct stat st;
if (allow_symlinks) {
if (stat(path.value().c_str(), &st) != 0) {
PLOG(ERROR) << "stat " << path.value();
PLOG_IF(ERROR, errno != ENOENT) << "stat " << path.value();
return false;
}
} else if (lstat(path.value().c_str(), &st) != 0) {
PLOG(ERROR) << "lstat " << path.value();
PLOG_IF(ERROR, errno != ENOENT) << "lstat " << path.value();
return false;
}
return S_ISDIR(st.st_mode);
......
......@@ -395,8 +395,8 @@
['OS=="linux" or OS=="android"', {
'sources': [
'net/http_transport_socket.cc',
'util/process_memory_sanitized.cc',
'util/process_memory_sanitized.h',
'process/process_memory_sanitized.cc',
'process/process_memory_sanitized.h',
],
}, { # else: OS!="linux"
'sources!': [
......
......@@ -156,7 +156,7 @@
}],
['OS=="linux" or OS=="android"', {
'sources': [
'util/process_memory_sanitized_test.cc',
'process/process_memory_sanitized_test.cc',
],
}],
['OS!="linux" and OS!="android"', {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment