This implements the crash helper service used to move child process crash report generation out of the main process and into its own process. This is implemented as a separate executable that is launched on startup by the main process on the desktop platforms and as a service hosted by a separate process on Android. One limitation of the current code is that the crash helper process needs to be running before we can start setting exception handlers in child processes. This limitation is due to how Breakpad exception handlers register themselves with the crash generator and prevents us from lazily starting the helper (or restarting it on Android). IPC with the crash helper is implemented using Unix sockets on Linux and macOS with the former using sequential packets and the latter using stream sockets. On Windows we use named pipes. In all cases the choice of IPC was dictated both by the requirement to eventually talk directly to child processes from within the sandbox, and to external processes in case of Windows as the Windows Error Reporting exception handler must be able to reach out to the helper from within a restricted context. These particular requirements are not used yet but will be as we move more logic out of the main process logic. Differential Revision: https://phabricator.services.mozilla.com/D231083
78 lines
3.0 KiB
C++
78 lines
3.0 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include <errno.h> // For EPERM
|
|
#include <sys/syscall.h> // For syscall()
|
|
#include <unistd.h>
|
|
|
|
#include "mozilla/Assertions.h"
|
|
|
|
extern "C" {
|
|
|
|
#if defined(__ANDROID_API__) && (__ANDROID_API__ < 28)
|
|
|
|
// Bionic introduced support for syncfs only in version 28 (that is
|
|
// Android Pie / 9). Since GeckoView is built with version 21, those functions
|
|
// aren't defined, but nix needs them and the crash helper relies on nix. These
|
|
// functions should never be called in practice hence we implement them only to
|
|
// satisfy nix linking requirements but we crash if we accidentally enter them.
|
|
|
|
int syncfs(int fd) {
|
|
MOZ_CRASH("syncfs() is not available");
|
|
return EPERM;
|
|
}
|
|
|
|
#endif // __ANDROID_API__ && (__ANDROID_API__ < 28)
|
|
|
|
#if defined(__ANDROID_API__) && (__ANDROID_API__ < 24)
|
|
|
|
// Bionic introduced support for getgrgid_r() and getgrnam_r() only in version
|
|
// 24 (that is Android Nougat / 7.0). Since GeckoView is built with version 21,
|
|
// those functions aren't defined, but the nix crate needs them and
|
|
// minidump-writer relies on nix. These functions should never be called in
|
|
// practice hence we implement them only to satisfy nix linking requirements
|
|
// but we crash if we accidentally enter them.
|
|
|
|
int getgrgid_r(gid_t gid, struct group* grp, char* buf, size_t buflen,
|
|
struct group** result) {
|
|
MOZ_CRASH("getgrgid_r() is not available");
|
|
return EPERM;
|
|
}
|
|
|
|
int getgrnam_r(const char* name, struct group* grp, char* buf, size_t buflen,
|
|
struct group** result) {
|
|
MOZ_CRASH("getgrnam_r() is not available");
|
|
return EPERM;
|
|
}
|
|
|
|
#endif // __ANDROID_API__ && (__ANDROID_API__ < 24)
|
|
|
|
#if defined(__ANDROID_API__) && (__ANDROID_API__ < 23)
|
|
|
|
// Bionic introduced support for process_vm_readv() and process_vm_writev() only
|
|
// in version 23 (that is Android Marshmallow / 6.0). Since GeckoView is built
|
|
// on version 21, those functions aren't defined, but nix needs them and
|
|
// minidump-writer actually calls them.
|
|
|
|
ssize_t process_vm_readv(pid_t pid, const struct iovec* local_iov,
|
|
unsigned long int liovcnt,
|
|
const struct iovec* remote_iov,
|
|
unsigned long int riovcnt, unsigned long int flags) {
|
|
return syscall(__NR_process_vm_readv, pid, local_iov, liovcnt, remote_iov,
|
|
riovcnt, flags);
|
|
}
|
|
|
|
ssize_t process_vm_writev(pid_t pid, const struct iovec* local_iov,
|
|
unsigned long int liovcnt,
|
|
const struct iovec* remote_iov,
|
|
unsigned long int riovcnt, unsigned long int flags) {
|
|
return syscall(__NR_process_vm_writev, pid, local_iov, liovcnt, remote_iov,
|
|
riovcnt, flags);
|
|
}
|
|
|
|
#endif // defined(__ANDROID_API__) && (__ANDROID_API__ < 23)
|
|
}
|