mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 22:26:06 +00:00
fuchsia: Migrate off launchpad
Rather than using liblaunchpad.so to create processes, we now use fdio_spawn. Bug: crashpad:196 Change-Id: I28a7c12c823f0a0d120962edfce2e2197302b9cb Reviewed-on: https://chromium-review.googlesource.com/1080234 Commit-Queue: Scott Graham <scottmg@chromium.org> Reviewed-by: Scott Graham <scottmg@chromium.org>
This commit is contained in:
parent
dc22f05f61
commit
1299754179
@ -88,14 +88,10 @@ static_library("client") {
|
||||
cflags = [ "/wd4201" ] # nonstandard extension used : nameless struct/union
|
||||
}
|
||||
|
||||
if (crashpad_is_fuchsia) {
|
||||
if (crashpad_is_in_fuchsia) {
|
||||
deps += [
|
||||
"//zircon/public/lib/launchpad",
|
||||
]
|
||||
} else {
|
||||
libs = [ "launchpad" ]
|
||||
}
|
||||
if (crashpad_is_fuchsia && crashpad_is_in_fuchsia) {
|
||||
deps += [
|
||||
"//zircon/public/lib/fdio",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
#include "client/crashpad_client.h"
|
||||
|
||||
#include <launchpad/launchpad.h>
|
||||
#include <fdio/spawn.h>
|
||||
#include <zircon/process.h>
|
||||
#include <zircon/processargs.h>
|
||||
|
||||
@ -69,20 +69,6 @@ bool CrashpadClient::StartHandler(
|
||||
|
||||
std::vector<const char*> argv;
|
||||
ConvertArgvStrings(argv_strings, &argv);
|
||||
// ConvertArgvStrings adds an unnecessary nullptr at the end of the argv list,
|
||||
// which causes launchpad_set_args() to hang.
|
||||
argv.pop_back();
|
||||
|
||||
launchpad_t* lp;
|
||||
launchpad_create(zx_job_default(), argv[0], &lp);
|
||||
launchpad_load_from_file(lp, argv[0]);
|
||||
launchpad_set_args(lp, argv.size(), &argv[0]);
|
||||
|
||||
// TODO(scottmg): https://crashpad.chromium.org/bug/196, this is useful during
|
||||
// bringup, but should probably be made minimal for real usage.
|
||||
launchpad_clone(lp,
|
||||
LP_CLONE_FDIO_NAMESPACE | LP_CLONE_FDIO_STDIO |
|
||||
LP_CLONE_ENVIRON | LP_CLONE_DEFAULT_JOB);
|
||||
|
||||
// Follow the same protocol as devmgr and crashlogger in Zircon (that is,
|
||||
// process handle as handle 0, with type USER0, exception port handle as
|
||||
@ -91,24 +77,39 @@ bool CrashpadClient::StartHandler(
|
||||
// released here. Currently it is assumed that this process's default job
|
||||
// handle is the exception port that should be monitored. In the future, it
|
||||
// might be useful for this to be configurable by the client.
|
||||
zx_handle_t handles[] = {ZX_HANDLE_INVALID, ZX_HANDLE_INVALID};
|
||||
status =
|
||||
zx_handle_duplicate(zx_job_default(), ZX_RIGHT_SAME_RIGHTS, &handles[0]);
|
||||
constexpr size_t kActionCount = 2;
|
||||
fdio_spawn_action_t actions[] = {
|
||||
{.action = FDIO_SPAWN_ACTION_ADD_HANDLE,
|
||||
.h = {.id = PA_HND(PA_USER0, 0), .handle = ZX_HANDLE_INVALID}},
|
||||
{.action = FDIO_SPAWN_ACTION_ADD_HANDLE,
|
||||
.h = {.id = PA_HND(PA_USER0, 1), .handle = ZX_HANDLE_INVALID}},
|
||||
};
|
||||
|
||||
status = zx_handle_duplicate(
|
||||
zx_job_default(), ZX_RIGHT_SAME_RIGHTS, &actions[0].h.handle);
|
||||
if (status != ZX_OK) {
|
||||
ZX_LOG(ERROR, status) << "zx_handle_duplicate";
|
||||
return false;
|
||||
}
|
||||
handles[1] = exception_port.release();
|
||||
uint32_t handle_types[] = {PA_HND(PA_USER0, 0), PA_HND(PA_USER0, 1)};
|
||||
actions[1].h.handle = exception_port.release();
|
||||
|
||||
launchpad_add_handles(lp, arraysize(handles), handles, handle_types);
|
||||
|
||||
const char* error_message;
|
||||
char error_message[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
|
||||
zx_handle_t child_raw;
|
||||
status = launchpad_go(lp, &child_raw, &error_message);
|
||||
// TODO(scottmg): https://crashpad.chromium.org/bug/196, FDIO_SPAWN_CLONE_ALL
|
||||
// is useful during bringup, but should probably be made minimal for real
|
||||
// usage.
|
||||
status = fdio_spawn_etc(ZX_HANDLE_INVALID,
|
||||
FDIO_SPAWN_CLONE_ALL,
|
||||
argv[0],
|
||||
argv.data(),
|
||||
nullptr,
|
||||
kActionCount,
|
||||
actions,
|
||||
&child_raw,
|
||||
error_message);
|
||||
base::ScopedZxHandle child(child_raw);
|
||||
if (status != ZX_OK) {
|
||||
ZX_LOG(ERROR, status) << "launchpad_go: " << error_message;
|
||||
ZX_LOG(ERROR, status) << "fdio_spawn_etc: " << error_message;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -127,14 +127,10 @@ static_library("test") {
|
||||
libs = [ "shell32.lib" ]
|
||||
}
|
||||
|
||||
if (crashpad_is_fuchsia) {
|
||||
if (crashpad_is_in_fuchsia) {
|
||||
deps += [
|
||||
"//zircon/public/lib/launchpad",
|
||||
]
|
||||
} else {
|
||||
libs = [ "launchpad" ]
|
||||
}
|
||||
if (crashpad_is_fuchsia && crashpad_is_in_fuchsia) {
|
||||
deps += [
|
||||
"//zircon/public/lib/fdio",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,8 +14,10 @@
|
||||
|
||||
#include "test/multiprocess_exec.h"
|
||||
|
||||
#include <launchpad/launchpad.h>
|
||||
#include <fdio/io.h>
|
||||
#include <fdio/spawn.h>
|
||||
#include <zircon/process.h>
|
||||
#include <zircon/processargs.h>
|
||||
#include <zircon/syscalls.h>
|
||||
|
||||
#include "base/files/scoped_file.h"
|
||||
@ -26,6 +28,21 @@
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
|
||||
namespace {
|
||||
|
||||
void AddPipe(fdio_spawn_action_t* action, int target_fd, int* fd_out) {
|
||||
zx_handle_t handle;
|
||||
uint32_t id;
|
||||
zx_status_t status = fdio_pipe_half(&handle, &id);
|
||||
ZX_CHECK(status < 0, status) << "Failed to create pipe.";
|
||||
action->action = FDIO_SPAWN_ACTION_ADD_HANDLE;
|
||||
action->h.id = PA_HND(PA_HND_TYPE(id), target_fd);
|
||||
action->h.handle = handle;
|
||||
*fd_out = status;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace internal {
|
||||
|
||||
struct MultiprocessInfo {
|
||||
@ -38,10 +55,7 @@ struct MultiprocessInfo {
|
||||
} // namespace internal
|
||||
|
||||
Multiprocess::Multiprocess()
|
||||
: info_(nullptr),
|
||||
code_(EXIT_SUCCESS),
|
||||
reason_(kTerminationNormal) {
|
||||
}
|
||||
: info_(nullptr), code_(EXIT_SUCCESS), reason_(kTerminationNormal) {}
|
||||
|
||||
void Multiprocess::Run() {
|
||||
// Set up and spawn the child process.
|
||||
@ -122,8 +136,7 @@ void Multiprocess::RunChild() {
|
||||
}
|
||||
|
||||
MultiprocessExec::MultiprocessExec()
|
||||
: Multiprocess(), command_(), arguments_(), argv_() {
|
||||
}
|
||||
: Multiprocess(), command_(), arguments_(), argv_() {}
|
||||
|
||||
void MultiprocessExec::SetChildCommand(
|
||||
const base::FilePath& command,
|
||||
@ -147,37 +160,45 @@ void MultiprocessExec::PreFork() {
|
||||
for (const std::string& argument : arguments_) {
|
||||
argv_.push_back(argument.c_str());
|
||||
}
|
||||
argv_.push_back(nullptr);
|
||||
|
||||
ASSERT_EQ(info(), nullptr);
|
||||
set_info(new internal::MultiprocessInfo());
|
||||
}
|
||||
|
||||
void MultiprocessExec::MultiprocessChild() {
|
||||
launchpad_t* lp;
|
||||
launchpad_create(zx_job_default(), command_.value().c_str(), &lp);
|
||||
launchpad_load_from_file(lp, command_.value().c_str());
|
||||
launchpad_set_args(lp, argv_.size(), &argv_[0]);
|
||||
constexpr size_t kActionCount = 3;
|
||||
fdio_spawn_action_t actions[kActionCount];
|
||||
|
||||
int stdin_parent_side = -1;
|
||||
AddPipe(&actions[0], STDIN_FILENO, &stdin_parent_side);
|
||||
info()->stdin_write.reset(stdin_parent_side);
|
||||
|
||||
int stdout_parent_side = -1;
|
||||
AddPipe(&actions[1], STDOUT_FILENO, &stdout_parent_side);
|
||||
info()->stdout_read.reset(stdout_parent_side);
|
||||
|
||||
actions[2].action = FDIO_SPAWN_ACTION_CLONE_FD;
|
||||
actions[2].fd.local_fd = STDERR_FILENO;
|
||||
actions[2].fd.target_fd = STDERR_FILENO;
|
||||
|
||||
// Pass the filesystem namespace, parent environment, and default job to the
|
||||
// child, but don't include any other file handles, preferring to set them
|
||||
// up explicitly below.
|
||||
launchpad_clone(
|
||||
lp, LP_CLONE_FDIO_NAMESPACE | LP_CLONE_ENVIRON | LP_CLONE_DEFAULT_JOB);
|
||||
uint32_t flags = FDIO_SPAWN_CLONE_ALL & ~FDIO_SPAWN_CLONE_STDIO;
|
||||
|
||||
int stdin_parent_side;
|
||||
launchpad_add_pipe(lp, &stdin_parent_side, STDIN_FILENO);
|
||||
info()->stdin_write.reset(stdin_parent_side);
|
||||
|
||||
int stdout_parent_side;
|
||||
launchpad_add_pipe(lp, &stdout_parent_side, STDOUT_FILENO);
|
||||
info()->stdout_read.reset(stdout_parent_side);
|
||||
|
||||
launchpad_clone_fd(lp, STDERR_FILENO, STDERR_FILENO);
|
||||
|
||||
const char* error_message;
|
||||
char error_message[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
|
||||
zx_handle_t child;
|
||||
zx_status_t status = launchpad_go(lp, &child, &error_message);
|
||||
ZX_CHECK(status == ZX_OK, status) << "launchpad_go: " << error_message;
|
||||
zx_status_t status = fdio_spawn_etc(ZX_HANDLE_INVALID,
|
||||
flags,
|
||||
command_.value().c_str(),
|
||||
argv_.data(),
|
||||
nullptr,
|
||||
kActionCount,
|
||||
actions,
|
||||
&child,
|
||||
error_message);
|
||||
ZX_CHECK(status == ZX_OK, status) << "fdio_spawn_etc: " << error_message;
|
||||
info()->child.reset(child);
|
||||
}
|
||||
|
||||
|
2
third_party/gtest/BUILD.gn
vendored
2
third_party/gtest/BUILD.gn
vendored
@ -49,7 +49,6 @@ if (crashpad_is_in_chromium) {
|
||||
|
||||
if (crashpad_is_fuchsia) {
|
||||
libs = [
|
||||
"launchpad",
|
||||
"zircon",
|
||||
]
|
||||
}
|
||||
@ -272,7 +271,6 @@ if (crashpad_is_in_chromium) {
|
||||
|
||||
if (crashpad_is_fuchsia) {
|
||||
libs = [
|
||||
"launchpad",
|
||||
"zircon",
|
||||
]
|
||||
}
|
||||
|
@ -104,14 +104,6 @@ if (crashpad_is_mac || crashpad_is_fuchsia) {
|
||||
"../third_party/mini_chromium:base",
|
||||
"../util",
|
||||
]
|
||||
|
||||
if (crashpad_is_fuchsia) {
|
||||
if (crashpad_is_in_fuchsia) {
|
||||
deps += [ "//zircon/public/lib/launchpad" ]
|
||||
} else {
|
||||
libs = [ "launchpad" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include "util/string/split_string.h"
|
||||
|
||||
#if defined(OS_FUCHSIA)
|
||||
#include <launchpad/launchpad.h>
|
||||
#include <fdio/spawn.h>
|
||||
#include <zircon/process.h>
|
||||
#include <zircon/syscalls.h>
|
||||
|
||||
@ -48,7 +48,7 @@ void Usage(const std::string& me) {
|
||||
"Start a Crashpad handler and have it handle crashes from COMMAND.\n"
|
||||
"\n"
|
||||
#if defined(OS_FUCHSIA)
|
||||
"COMMAND is run via launchpad, so must be a qualified path to the subprocess to\n"
|
||||
"COMMAND is run via fdio_spawn, so must be a qualified path to the subprocess to\n"
|
||||
"be executed.\n"
|
||||
#else
|
||||
"COMMAND is run via execvp() so the PATH will be searched.\n"
|
||||
@ -190,17 +190,12 @@ int RunWithCrashpadMain(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
#if defined(OS_FUCHSIA)
|
||||
// Fuchsia doesn't implement execvp(), launch with launchpad here.
|
||||
launchpad_t* lp;
|
||||
launchpad_create(zx_job_default(), argv[0], &lp);
|
||||
launchpad_load_from_file(lp, argv[0]);
|
||||
launchpad_set_args(lp, argc, argv);
|
||||
launchpad_clone(lp, LP_CLONE_ALL);
|
||||
const char* error_message;
|
||||
zx_handle_t child;
|
||||
zx_status_t status = launchpad_go(lp, &child, &error_message);
|
||||
// Fuchsia doesn't implement execvp(), launch with fdio_spawn here.
|
||||
zx_handle_t child = ZX_HANDLE_INVALID;
|
||||
zx_status_t status = fdio_spawn(
|
||||
ZX_HANDLE_INVALID, FDIO_SPAWN_CLONE_ALL, argv[0], argv, &child);
|
||||
if (status != ZX_OK) {
|
||||
ZX_LOG(ERROR, status) << "launchpad_go: " << error_message;
|
||||
ZX_LOG(ERROR, status) << "fdio_spawn failed";
|
||||
return status == ZX_ERR_IO ? kExitExecENOENT : kExitExecFailure;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user