diff --git a/client/BUILD.gn b/client/BUILD.gn index a074b503..a82a8dd4 100644 --- a/client/BUILD.gn +++ b/client/BUILD.gn @@ -88,10 +88,11 @@ static_library("client") { cflags = [ "/wd4201" ] # nonstandard extension used : nameless struct/union } - if (crashpad_is_fuchsia && crashpad_is_in_fuchsia) { - deps += [ - "//zircon/public/lib/fdio", - ] + if (crashpad_is_fuchsia) { + deps += [ "../third_party/fuchsia:zx" ] + if (crashpad_is_in_fuchsia) { + deps += [ "//zircon/public/lib/fdio" ] + } } } diff --git a/client/crashpad_client_fuchsia.cc b/client/crashpad_client_fuchsia.cc index 0d1b65bf..0eba01d6 100644 --- a/client/crashpad_client_fuchsia.cc +++ b/client/crashpad_client_fuchsia.cc @@ -15,11 +15,12 @@ #include "client/crashpad_client.h" #include -#include +#include +#include +#include #include #include "base/fuchsia/fuchsia_logging.h" -#include "base/fuchsia/scoped_zx_handle.h" #include "base/logging.h" #include "base/strings/stringprintf.h" #include "client/client_argv_handling.h" @@ -43,16 +44,15 @@ bool CrashpadClient::StartHandler( DCHECK_EQ(restartable, false); // Not used on Fuchsia. DCHECK_EQ(asynchronous_start, false); // Not used on Fuchsia. - zx_handle_t exception_port_raw; - zx_status_t status = zx_port_create(0, &exception_port_raw); + zx::port exception_port; + zx_status_t status = zx::port::create(0, &exception_port); if (status != ZX_OK) { ZX_LOG(ERROR, status) << "zx_port_create"; return false; } - base::ScopedZxHandle exception_port(exception_port_raw); - status = zx_task_bind_exception_port( - zx_job_default(), exception_port.get(), kSystemExceptionPortKey, 0); + status = zx::job::default_job()->bind_exception_port( + exception_port, kSystemExceptionPortKey, 0); if (status != ZX_OK) { ZX_LOG(ERROR, status) << "zx_task_bind_exception_port"; return false; @@ -88,7 +88,7 @@ bool CrashpadClient::StartHandler( actions[1].h.handle = exception_port.release(); char error_message[FDIO_SPAWN_ERR_MSG_MAX_LENGTH]; - zx_handle_t child_raw; + zx::process child; // 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. @@ -99,9 +99,8 @@ bool CrashpadClient::StartHandler( nullptr, kActionCount, actions, - &child_raw, + child.reset_and_get_address(), error_message); - base::ScopedZxHandle child(child_raw); if (status != ZX_OK) { ZX_LOG(ERROR, status) << "fdio_spawn_etc: " << error_message; return false; diff --git a/handler/BUILD.gn b/handler/BUILD.gn index 2eae30b5..93fd540a 100644 --- a/handler/BUILD.gn +++ b/handler/BUILD.gn @@ -80,6 +80,10 @@ static_library("handler") { if (crashpad_is_win) { cflags = [ "/wd4201" ] # nonstandard extension used : nameless struct/union } + + if (crashpad_is_fuchsia) { + deps += [ "../third_party/fuchsia:zx" ] + } } source_set("handler_test") { diff --git a/handler/fuchsia/crash_report_exception_handler.cc b/handler/fuchsia/crash_report_exception_handler.cc index 1da09851..3305fef6 100644 --- a/handler/fuchsia/crash_report_exception_handler.cc +++ b/handler/fuchsia/crash_report_exception_handler.cc @@ -14,6 +14,7 @@ #include "handler/fuchsia/crash_report_exception_handler.h" +#include #include #include "base/fuchsia/fuchsia_logging.h" @@ -22,28 +23,28 @@ #include "minidump/minidump_user_extension_stream_data_source.h" #include "snapshot/fuchsia/process_snapshot_fuchsia.h" #include "util/fuchsia/koid_utilities.h" -#include "util/fuchsia/scoped_task_suspend.h" namespace crashpad { namespace { -struct ScopedZxTaskResumeAfterException { - ScopedZxTaskResumeAfterException(zx_handle_t thread) : thread_(thread) {} - ~ScopedZxTaskResumeAfterException() { - DCHECK_NE(thread_, ZX_HANDLE_INVALID); +class ScopedThreadResumeAfterException { + public: + ScopedThreadResumeAfterException(const zx::thread& thread) + : thread_(thread) {} + ~ScopedThreadResumeAfterException() { + DCHECK(thread_->is_valid()); // Resuming with ZX_RESUME_TRY_NEXT chains to the next handler. In normal // operation, there won't be another beyond this one, which will result in // the kernel terminating the process. zx_status_t status = - zx_task_resume(thread_, ZX_RESUME_EXCEPTION | ZX_RESUME_TRY_NEXT); - if (status != ZX_OK) { - ZX_LOG(ERROR, status) << "zx_task_resume"; - } + thread_->resume(ZX_RESUME_EXCEPTION | ZX_RESUME_TRY_NEXT); + ZX_LOG_IF(ERROR, status != ZX_OK, status) << "zx_task_resume"; } private: - zx_handle_t thread_; // weak + zx::unowned_thread thread_; + DISALLOW_COPY_AND_ASSIGN(ScopedThreadResumeAfterException); }; } // namespace @@ -67,27 +68,28 @@ bool CrashReportExceptionHandler::HandleException(uint64_t process_id, // TODO(scottmg): This function needs to be instrumented with metrics calls, // https://crashpad.chromium.org/bug/230. - base::ScopedZxHandle process(GetProcessFromKoid(process_id)); + zx::process process(GetProcessFromKoid(process_id)); if (!process.is_valid()) { // There's no way to zx_task_resume() the thread if the process retrieval // fails. Assume that the process has been already killed, and bail. return false; } - base::ScopedZxHandle thread(GetChildHandleByKoid(process.get(), thread_id)); + zx::thread thread(GetThreadHandleByKoid(process, thread_id)); if (!thread.is_valid()) { return false; } - return HandleExceptionHandles(process.get(), thread.get()); + return HandleExceptionHandles(process, thread); } -bool CrashReportExceptionHandler::HandleExceptionHandles(zx_handle_t process, - zx_handle_t thread) { +bool CrashReportExceptionHandler::HandleExceptionHandles( + const zx::process& process, + const zx::thread& thread) { // Now that the thread has been successfully retrieved, it is possible to // correctly call zx_task_resume() to continue exception processing, even if // something else during this function fails. - ScopedZxTaskResumeAfterException resume(thread); + ScopedThreadResumeAfterException resume(thread); ProcessSnapshotFuchsia process_snapshot; if (!process_snapshot.Initialize(process)) { @@ -99,12 +101,11 @@ bool CrashReportExceptionHandler::HandleExceptionHandles(zx_handle_t process, if (client_options.crashpad_handler_behavior != TriState::kDisabled) { zx_exception_report_t report; - zx_status_t status = zx_object_get_info(thread, - ZX_INFO_THREAD_EXCEPTION_REPORT, - &report, - sizeof(report), - nullptr, - nullptr); + zx_status_t status = thread.get_info(ZX_INFO_THREAD_EXCEPTION_REPORT, + &report, + sizeof(report), + nullptr, + nullptr); if (status != ZX_OK) { ZX_LOG(ERROR, status) << "zx_object_get_info ZX_INFO_THREAD_EXCEPTION_REPORT"; diff --git a/handler/fuchsia/crash_report_exception_handler.h b/handler/fuchsia/crash_report_exception_handler.h index 5043d7e9..8eacc11f 100644 --- a/handler/fuchsia/crash_report_exception_handler.h +++ b/handler/fuchsia/crash_report_exception_handler.h @@ -15,6 +15,8 @@ #ifndef CRASHPAD_HANDLER_FUCHSIA_CRASH_REPORT_EXCEPTION_HANDLER_H_ #define CRASHPAD_HANDLER_FUCHSIA_CRASH_REPORT_EXCEPTION_HANDLER_H_ +#include +#include #include #include @@ -88,7 +90,8 @@ class CrashReportExceptionHandler { //! \param[in] thread The handle to the thread of \a process which sustained //! the exception. //! \return `true` on success, or `false` with an error logged. - bool HandleExceptionHandles(zx_handle_t process, zx_handle_t thread); + bool HandleExceptionHandles(const zx::process& process, + const zx::thread& thread); private: CrashReportDatabase* database_; // weak diff --git a/handler/fuchsia/exception_handler_server.cc b/handler/fuchsia/exception_handler_server.cc index 63153d28..1b2c829f 100644 --- a/handler/fuchsia/exception_handler_server.cc +++ b/handler/fuchsia/exception_handler_server.cc @@ -14,7 +14,7 @@ #include "handler/fuchsia/exception_handler_server.h" -#include +#include #include #include @@ -26,9 +26,8 @@ namespace crashpad { -ExceptionHandlerServer::ExceptionHandlerServer( - base::ScopedZxHandle root_job, - base::ScopedZxHandle exception_port) +ExceptionHandlerServer::ExceptionHandlerServer(zx::job root_job, + zx::port exception_port) : root_job_(std::move(root_job)), exception_port_(std::move(exception_port)) {} @@ -37,8 +36,7 @@ ExceptionHandlerServer::~ExceptionHandlerServer() = default; void ExceptionHandlerServer::Run(CrashReportExceptionHandler* handler) { while (true) { zx_port_packet_t packet; - zx_status_t status = - zx_port_wait(exception_port_.get(), ZX_TIME_INFINITE, &packet); + zx_status_t status = exception_port_.wait(zx::time::infinite(), &packet); if (status != ZX_OK) { ZX_LOG(ERROR, status) << "zx_port_wait, aborting"; return; diff --git a/handler/fuchsia/exception_handler_server.h b/handler/fuchsia/exception_handler_server.h index 184d1489..1832f02c 100644 --- a/handler/fuchsia/exception_handler_server.h +++ b/handler/fuchsia/exception_handler_server.h @@ -15,8 +15,10 @@ #ifndef CRASHPAD_HANDLER_FUCHSIA_EXCEPTION_HANDLER_SERVER_H_ #define CRASHPAD_HANDLER_FUCHSIA_EXCEPTION_HANDLER_SERVER_H_ +#include +#include + #include "base/macros.h" -#include "base/fuchsia/scoped_zx_handle.h" namespace crashpad { @@ -33,8 +35,7 @@ class ExceptionHandlerServer { //! port of this job. //! \param[in] exception_port The exception port that this server will //! monitor. - ExceptionHandlerServer(base::ScopedZxHandle root_job, - base::ScopedZxHandle exception_port); + ExceptionHandlerServer(zx::job root_job, zx::port exception_port); ~ExceptionHandlerServer(); //! \brief Runs the exception-handling server. @@ -44,8 +45,8 @@ class ExceptionHandlerServer { void Run(CrashReportExceptionHandler* handler); private: - base::ScopedZxHandle root_job_; - base::ScopedZxHandle exception_port_; + zx::job root_job_; + zx::port exception_port_; DISALLOW_COPY_AND_ASSIGN(ExceptionHandlerServer); }; diff --git a/handler/handler_main.cc b/handler/handler_main.cc index 412ee112..b3e0a68a 100644 --- a/handler/handler_main.cc +++ b/handler/handler_main.cc @@ -943,14 +943,13 @@ int HandlerMain(int argc, // owns them in this process. There is currently no "connect-later" mode on // Fuchsia, all the binding must be done by the client before starting // crashpad_handler. - base::ScopedZxHandle root_job(zx_take_startup_handle(PA_HND(PA_USER0, 0))); + zx::job root_job(zx_take_startup_handle(PA_HND(PA_USER0, 0))); if (!root_job.is_valid()) { LOG(ERROR) << "no process handle passed in startup handle 0"; return EXIT_FAILURE; } - base::ScopedZxHandle exception_port( - zx_take_startup_handle(PA_HND(PA_USER0, 1))); + zx::port exception_port(zx_take_startup_handle(PA_HND(PA_USER0, 1))); if (!exception_port.is_valid()) { LOG(ERROR) << "no exception port handle passed in startup handle 1"; return EXIT_FAILURE; diff --git a/snapshot/crashpad_info_client_options_test.cc b/snapshot/crashpad_info_client_options_test.cc index 1fe38acf..d1c5f9d3 100644 --- a/snapshot/crashpad_info_client_options_test.cc +++ b/snapshot/crashpad_info_client_options_test.cc @@ -32,7 +32,7 @@ #include #include "snapshot/win/process_snapshot_win.h" #elif defined(OS_FUCHSIA) -#include +#include #include "snapshot/fuchsia/process_snapshot_fuchsia.h" #endif @@ -86,7 +86,7 @@ CrashpadInfoClientOptions SelfProcessSnapshotAndGetCrashpadOptions() { GetCurrentProcess(), ProcessSuspensionState::kRunning, 0, 0)); #elif defined(OS_FUCHSIA) ProcessSnapshotFuchsia process_snapshot; - EXPECT_TRUE(process_snapshot.Initialize(zx_process_self())); + EXPECT_TRUE(process_snapshot.Initialize(*zx::process::self())); #else #error Port. #endif // OS_MACOSX diff --git a/snapshot/elf/elf_image_reader_test.cc b/snapshot/elf/elf_image_reader_test.cc index 11fb1feb..6d88d817 100644 --- a/snapshot/elf/elf_image_reader_test.cc +++ b/snapshot/elf/elf_image_reader_test.cc @@ -32,8 +32,7 @@ #include "util/process/process_memory_native.h" #if defined(OS_FUCHSIA) - -#include +#include #include "base/fuchsia/fuchsia_logging.h" @@ -61,14 +60,12 @@ namespace { #if defined(OS_FUCHSIA) -void LocateExecutable(ProcessType process, +void LocateExecutable(const ProcessType& process, ProcessMemory* memory, VMAddress* elf_address) { uintptr_t debug_address; - zx_status_t status = zx_object_get_property(process, - ZX_PROP_PROCESS_DEBUG_ADDR, - &debug_address, - sizeof(debug_address)); + zx_status_t status = process->get_property( + ZX_PROP_PROCESS_DEBUG_ADDR, &debug_address, sizeof(debug_address)); ASSERT_EQ(status, ZX_OK) << "zx_object_get_property: ZX_PROP_PROCESS_DEBUG_ADDR"; // Can be 0 if requested before the loader has loaded anything. diff --git a/snapshot/fuchsia/memory_map_fuchsia.cc b/snapshot/fuchsia/memory_map_fuchsia.cc index b60531d0..15867929 100644 --- a/snapshot/fuchsia/memory_map_fuchsia.cc +++ b/snapshot/fuchsia/memory_map_fuchsia.cc @@ -14,8 +14,6 @@ #include "snapshot/fuchsia/memory_map_fuchsia.h" -#include - #include "base/fuchsia/fuchsia_logging.h" #include "util/numeric/checked_range.h" @@ -25,7 +23,7 @@ MemoryMapFuchsia::MemoryMapFuchsia() = default; MemoryMapFuchsia::~MemoryMapFuchsia() = default; -bool MemoryMapFuchsia::Initialize(zx_handle_t process) { +bool MemoryMapFuchsia::Initialize(const zx::process& process) { INITIALIZATION_STATE_SET_INITIALIZING(initialized_); // There's no way to know what an appropriate buffer size is before starting. @@ -40,12 +38,11 @@ bool MemoryMapFuchsia::Initialize(zx_handle_t process) { size_t actual; size_t available; zx_status_t status = - zx_object_get_info(process, - ZX_INFO_PROCESS_MAPS, - &map_entries_[0], - map_entries_.size() * sizeof(map_entries_[0]), - &actual, - &available); + process.get_info(ZX_INFO_PROCESS_MAPS, + &map_entries_[0], + map_entries_.size() * sizeof(map_entries_[0]), + &actual, + &available); if (status != ZX_OK) { ZX_LOG(ERROR, status) << "zx_object_get_info ZX_INFO_PROCESS_MAPS"; map_entries_.clear(); diff --git a/snapshot/fuchsia/memory_map_fuchsia.h b/snapshot/fuchsia/memory_map_fuchsia.h index 88df5695..c3511200 100644 --- a/snapshot/fuchsia/memory_map_fuchsia.h +++ b/snapshot/fuchsia/memory_map_fuchsia.h @@ -15,6 +15,7 @@ #ifndef CRASHPAD_SNAPSHOT_FUCHSIA_MEMORY_MAP_FUCHSIA_H_ #define CRASHPAD_SNAPSHOT_FUCHSIA_MEMORY_MAP_FUCHSIA_H_ +#include #include #include @@ -33,7 +34,7 @@ class MemoryMapFuchsia { //! regions in the given process. //! //! \return `true` on success, or `false`, with an error logged. - bool Initialize(zx_handle_t process); + bool Initialize(const zx::process& process); //! \brief Searches through the previously retrieved memory map for the given //! address. If found, returns the deepest `zx_info_maps_t` mapping that diff --git a/snapshot/fuchsia/process_reader_fuchsia.cc b/snapshot/fuchsia/process_reader_fuchsia.cc index 0a6a84bb..40123018 100644 --- a/snapshot/fuchsia/process_reader_fuchsia.cc +++ b/snapshot/fuchsia/process_reader_fuchsia.cc @@ -14,11 +14,11 @@ #include "snapshot/fuchsia/process_reader_fuchsia.h" +#include #include #include #include "base/fuchsia/fuchsia_logging.h" -#include "base/fuchsia/scoped_zx_handle.h" #include "base/logging.h" #include "util/fuchsia/koid_utilities.h" @@ -83,15 +83,15 @@ ProcessReaderFuchsia::ProcessReaderFuchsia() = default; ProcessReaderFuchsia::~ProcessReaderFuchsia() = default; -bool ProcessReaderFuchsia::Initialize(zx_handle_t process) { +bool ProcessReaderFuchsia::Initialize(const zx::process& process) { INITIALIZATION_STATE_SET_INITIALIZING(initialized_); - process_ = process; + process_ = zx::unowned_process(process); process_memory_.reset(new ProcessMemoryFuchsia()); - process_memory_->Initialize(process_); + process_memory_->Initialize(*process_); - memory_map_.Initialize(process_); + memory_map_.Initialize(*process_); INITIALIZATION_STATE_SET_VALID(initialized_); return true; @@ -134,7 +134,7 @@ void ProcessReaderFuchsia::InitializeModules() { { char name[ZX_MAX_NAME_LEN]; zx_status_t status = - zx_object_get_property(process_, ZX_PROP_NAME, name, sizeof(name)); + process_->get_property(ZX_PROP_NAME, name, sizeof(name)); if (status != ZX_OK) { LOG(ERROR) << "zx_object_get_property ZX_PROP_NAME"; return; @@ -147,10 +147,8 @@ void ProcessReaderFuchsia::InitializeModules() { // walk the list to fill out modules_. uintptr_t debug_address; - zx_status_t status = zx_object_get_property(process_, - ZX_PROP_PROCESS_DEBUG_ADDR, - &debug_address, - sizeof(debug_address)); + zx_status_t status = process_->get_property( + ZX_PROP_PROCESS_DEBUG_ADDR, &debug_address, sizeof(debug_address)); if (status != ZX_OK || debug_address == 0) { LOG(ERROR) << "zx_object_get_property ZX_PROP_PROCESS_DEBUG_ADDR"; return; @@ -250,9 +248,9 @@ void ProcessReaderFuchsia::InitializeThreads() { initialized_threads_ = true; std::vector thread_koids = - GetChildKoids(process_, ZX_INFO_PROCESS_THREADS); - std::vector thread_handles = - GetHandlesForChildKoids(process_, thread_koids); + GetChildKoids(*process_, ZX_INFO_PROCESS_THREADS); + std::vector thread_handles = + GetHandlesForThreadKoids(*process_, thread_koids); DCHECK_EQ(thread_koids.size(), thread_handles.size()); for (size_t i = 0; i < thread_handles.size(); ++i) { @@ -261,8 +259,8 @@ void ProcessReaderFuchsia::InitializeThreads() { if (thread_handles[i].is_valid()) { char name[ZX_MAX_NAME_LEN] = {0}; - zx_status_t status = zx_object_get_property( - thread_handles[i].get(), ZX_PROP_NAME, &name, sizeof(name)); + zx_status_t status = + thread_handles[i].get_property(ZX_PROP_NAME, &name, sizeof(name)); if (status != ZX_OK) { ZX_LOG(WARNING, status) << "zx_object_get_property ZX_PROP_NAME"; } else { @@ -270,12 +268,8 @@ void ProcessReaderFuchsia::InitializeThreads() { } zx_info_thread_t thread_info; - status = zx_object_get_info(thread_handles[i].get(), - ZX_INFO_THREAD, - &thread_info, - sizeof(thread_info), - nullptr, - nullptr); + status = thread_handles[i].get_info( + ZX_INFO_THREAD, &thread_info, sizeof(thread_info), nullptr, nullptr); if (status != ZX_OK) { ZX_LOG(WARNING, status) << "zx_object_get_info ZX_INFO_THREAD"; } else { @@ -283,10 +277,8 @@ void ProcessReaderFuchsia::InitializeThreads() { } zx_thread_state_general_regs_t regs; - status = zx_thread_read_state(thread_handles[i].get(), - ZX_THREAD_STATE_GENERAL_REGS, - ®s, - sizeof(regs)); + status = thread_handles[i].read_state( + ZX_THREAD_STATE_GENERAL_REGS, ®s, sizeof(regs)); if (status != ZX_OK) { ZX_LOG(WARNING, status) << "zx_thread_read_state"; } else { diff --git a/snapshot/fuchsia/process_reader_fuchsia.h b/snapshot/fuchsia/process_reader_fuchsia.h index 2d0878c3..6a6a6509 100644 --- a/snapshot/fuchsia/process_reader_fuchsia.h +++ b/snapshot/fuchsia/process_reader_fuchsia.h @@ -15,6 +15,7 @@ #ifndef CRASHPAD_SNAPSHOT_FUCHSIA_PROCESS_READER_H_ #define CRASHPAD_SNAPSHOT_FUCHSIA_PROCESS_READER_H_ +#include #include #include @@ -94,7 +95,7 @@ class ProcessReaderFuchsia { //! \return `true` on success, indicating that this object will respond //! validly to further method calls. `false` on failure. On failure, no //! further method calls should be made. - bool Initialize(zx_handle_t process); + bool Initialize(const zx::process& process); //! \return The modules loaded in the process. The first element (at index //! `0`) corresponds to the main executable. @@ -121,7 +122,7 @@ class ProcessReaderFuchsia { std::vector> process_memory_ranges_; std::unique_ptr process_memory_; MemoryMapFuchsia memory_map_; - zx_handle_t process_; + zx::unowned_process process_; bool initialized_modules_ = false; bool initialized_threads_ = false; InitializationStateDcheck initialized_; diff --git a/snapshot/fuchsia/process_reader_fuchsia_test.cc b/snapshot/fuchsia/process_reader_fuchsia_test.cc index 546d8290..fe640082 100644 --- a/snapshot/fuchsia/process_reader_fuchsia_test.cc +++ b/snapshot/fuchsia/process_reader_fuchsia_test.cc @@ -31,7 +31,7 @@ namespace { TEST(ProcessReaderFuchsia, SelfBasic) { ProcessReaderFuchsia process_reader; - ASSERT_TRUE(process_reader.Initialize(zx_process_self())); + ASSERT_TRUE(process_reader.Initialize(*zx::process::self())); static constexpr char kTestMemory[] = "Some test memory"; char buffer[arraysize(kTestMemory)]; @@ -82,7 +82,7 @@ class BasicChildTest : public MultiprocessExec { private: void MultiprocessParent() override { ProcessReaderFuchsia process_reader; - ASSERT_TRUE(process_reader.Initialize(ChildProcess())); + ASSERT_TRUE(process_reader.Initialize(*ChildProcess())); zx_vaddr_t addr; ASSERT_TRUE(ReadFileExactly(ReadPipeHandle(), &addr, sizeof(addr))); @@ -149,10 +149,10 @@ class ThreadsChildTest : public MultiprocessExec { ASSERT_TRUE(ReadFileExactly(ReadPipeHandle(), &c, 1)); ASSERT_EQ(c, ' '); - ScopedTaskSuspend suspend(ChildProcess()); + ScopedTaskSuspend suspend(*ChildProcess()); ProcessReaderFuchsia process_reader; - ASSERT_TRUE(process_reader.Initialize(ChildProcess())); + ASSERT_TRUE(process_reader.Initialize(*ChildProcess())); const auto& threads = process_reader.Threads(); EXPECT_EQ(threads.size(), 6u); diff --git a/snapshot/fuchsia/process_snapshot_fuchsia.cc b/snapshot/fuchsia/process_snapshot_fuchsia.cc index cc66db25..6750c3d5 100644 --- a/snapshot/fuchsia/process_snapshot_fuchsia.cc +++ b/snapshot/fuchsia/process_snapshot_fuchsia.cc @@ -14,8 +14,6 @@ #include "snapshot/fuchsia/process_snapshot_fuchsia.h" -#include - #include "base/logging.h" #include "util/fuchsia/koid_utilities.h" @@ -25,7 +23,7 @@ ProcessSnapshotFuchsia::ProcessSnapshotFuchsia() = default; ProcessSnapshotFuchsia::~ProcessSnapshotFuchsia() = default; -bool ProcessSnapshotFuchsia::Initialize(zx_handle_t process) { +bool ProcessSnapshotFuchsia::Initialize(const zx::process& process) { INITIALIZATION_STATE_SET_INITIALIZING(initialized_); if (gettimeofday(&snapshot_time_, nullptr) != 0) { @@ -95,7 +93,7 @@ void ProcessSnapshotFuchsia::GetCrashpadOptions( pid_t ProcessSnapshotFuchsia::ProcessID() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - return GetKoidForHandle(zx_process_self()); + return GetKoidForHandle(*zx::process::self()); } pid_t ProcessSnapshotFuchsia::ParentProcessID() const { diff --git a/snapshot/fuchsia/process_snapshot_fuchsia.h b/snapshot/fuchsia/process_snapshot_fuchsia.h index 2590ed58..237e17df 100644 --- a/snapshot/fuchsia/process_snapshot_fuchsia.h +++ b/snapshot/fuchsia/process_snapshot_fuchsia.h @@ -15,9 +15,10 @@ #ifndef CRASHPAD_SNAPSHOT_FUCHSIA_PROCESS_SNAPSHOT_FUCHSIA_H_ #define CRASHPAD_SNAPSHOT_FUCHSIA_PROCESS_SNAPSHOT_FUCHSIA_H_ +#include #include -#include #include +#include #include #include @@ -50,7 +51,7 @@ class ProcessSnapshotFuchsia : public ProcessSnapshot { //! //! \return `true` if the snapshot could be created, `false` otherwise with //! an appropriate message logged. - bool Initialize(zx_handle_t process); + bool Initialize(const zx::process& process); //! \brief Initializes the object's exception. //! diff --git a/test/BUILD.gn b/test/BUILD.gn index d1e6297e..c9630653 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -101,7 +101,7 @@ static_library("test") { configs += [ "../build:crashpad_is_in_chromium", - "../build:crashpad_is_in_fuchsia" + "../build:crashpad_is_in_fuchsia", ] data = [ @@ -127,10 +127,13 @@ static_library("test") { libs = [ "shell32.lib" ] } - if (crashpad_is_fuchsia && crashpad_is_in_fuchsia) { - deps += [ - "//zircon/public/lib/fdio", + if (crashpad_is_fuchsia) { + public_deps = [ + "../third_party/fuchsia:zx", ] + if (crashpad_is_in_fuchsia) { + deps += [ "//zircon/public/lib/fdio" ] + } } } diff --git a/test/multiprocess_exec_fuchsia.cc b/test/multiprocess_exec_fuchsia.cc index 95436b47..9c68b7fd 100644 --- a/test/multiprocess_exec_fuchsia.cc +++ b/test/multiprocess_exec_fuchsia.cc @@ -16,13 +16,12 @@ #include #include -#include +#include +#include #include -#include #include "base/files/scoped_file.h" #include "base/fuchsia/fuchsia_logging.h" -#include "base/fuchsia/scoped_zx_handle.h" #include "gtest/gtest.h" namespace crashpad { @@ -49,7 +48,7 @@ struct MultiprocessInfo { MultiprocessInfo() {} base::ScopedFD stdin_write; base::ScopedFD stdout_read; - base::ScopedZxHandle child; + zx::process child; }; } // namespace internal @@ -68,19 +67,14 @@ void Multiprocess::Run() { // Wait until the child exits. zx_signals_t signals; ASSERT_EQ( - zx_object_wait_one( - info_->child.get(), ZX_TASK_TERMINATED, ZX_TIME_INFINITE, &signals), + info_->child.wait_one(ZX_TASK_TERMINATED, zx::time::infinite(), &signals), ZX_OK); ASSERT_EQ(signals, ZX_TASK_TERMINATED); // Get the child's exit code. zx_info_process_t proc_info; - zx_status_t status = zx_object_get_info(info_->child.get(), - ZX_INFO_PROCESS, - &proc_info, - sizeof(proc_info), - nullptr, - nullptr); + zx_status_t status = info_->child.get_info( + ZX_INFO_PROCESS, &proc_info, sizeof(proc_info), nullptr, nullptr); if (status != ZX_OK) { ZX_LOG(ERROR, status) << "zx_object_get_info"; ADD_FAILURE() << "Unable to get exit code of child"; @@ -188,7 +182,7 @@ void MultiprocessExec::MultiprocessChild() { uint32_t flags = FDIO_SPAWN_CLONE_ALL & ~FDIO_SPAWN_CLONE_STDIO; char error_message[FDIO_SPAWN_ERR_MSG_MAX_LENGTH]; - zx_handle_t child; + zx::process child; zx_status_t status = fdio_spawn_etc(ZX_HANDLE_INVALID, flags, command_.value().c_str(), @@ -196,14 +190,14 @@ void MultiprocessExec::MultiprocessChild() { nullptr, kActionCount, actions, - &child, + child.reset_and_get_address(), error_message); ZX_CHECK(status == ZX_OK, status) << "fdio_spawn_etc: " << error_message; - info()->child.reset(child); + info()->child = std::move(child); } ProcessType MultiprocessExec::ChildProcess() { - return info()->child.get(); + return zx::unowned_process(info()->child); } } // namespace test diff --git a/test/process_type.cc b/test/process_type.cc index 0e3c9e6d..9fd08dd9 100644 --- a/test/process_type.cc +++ b/test/process_type.cc @@ -15,7 +15,7 @@ #include "test/process_type.h" #if defined(OS_FUCHSIA) -#include +#include #elif defined(OS_POSIX) #include #endif @@ -25,7 +25,7 @@ namespace test { ProcessType GetSelfProcess() { #if defined(OS_FUCHSIA) - return zx_process_self(); + return zx::process::self(); #elif defined(OS_POSIX) return getpid(); #elif defined(OS_WIN) diff --git a/test/process_type.h b/test/process_type.h index a25b1222..240c083d 100644 --- a/test/process_type.h +++ b/test/process_type.h @@ -18,7 +18,7 @@ #include "build/build_config.h" #if defined(OS_FUCHSIA) -#include +#include #elif defined(OS_POSIX) #include #elif defined(OS_WIN) @@ -29,7 +29,7 @@ namespace crashpad { namespace test { #if defined(OS_FUCHSIA) -using ProcessType = zx_handle_t; +using ProcessType = zx::unowned_process; #elif defined(OS_POSIX) || DOXYGEN //! \brief Alias for platform-specific type to represent a process. using ProcessType = pid_t; diff --git a/third_party/fuchsia/BUILD.gn b/third_party/fuchsia/BUILD.gn new file mode 100644 index 00000000..6c2339b9 --- /dev/null +++ b/third_party/fuchsia/BUILD.gn @@ -0,0 +1,82 @@ +# Copyright 2018 The Crashpad Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("../../build/crashpad_buildconfig.gni") + +if (crashpad_is_in_fuchsia) { + group("zx") { + public_deps = [ + "//zircon/public/lib/zx", + ] + } +} else if (crashpad_is_in_chromium) { + group("zx") { + public_deps = [ + "//third_party/fuchsia-sdk:zx", + ] + } +} else { + sdk_pkg_path = "sdk/linux-amd64/pkg" + + config("zx_config") { + visibility = [ ":zx" ] + include_dirs = [ "$sdk_pkg_path/zx/include" ] + } + + static_library("zx") { + sources = [ + "$sdk_pkg_path/zx/channel.cpp", + "$sdk_pkg_path/zx/event.cpp", + "$sdk_pkg_path/zx/eventpair.cpp", + "$sdk_pkg_path/zx/fifo.cpp", + "$sdk_pkg_path/zx/guest.cpp", + "$sdk_pkg_path/zx/include/lib/zx/bti.h", + "$sdk_pkg_path/zx/include/lib/zx/channel.h", + "$sdk_pkg_path/zx/include/lib/zx/event.h", + "$sdk_pkg_path/zx/include/lib/zx/eventpair.h", + "$sdk_pkg_path/zx/include/lib/zx/fifo.h", + "$sdk_pkg_path/zx/include/lib/zx/guest.h", + "$sdk_pkg_path/zx/include/lib/zx/handle.h", + "$sdk_pkg_path/zx/include/lib/zx/interrupt.h", + "$sdk_pkg_path/zx/include/lib/zx/job.h", + "$sdk_pkg_path/zx/include/lib/zx/log.h", + "$sdk_pkg_path/zx/include/lib/zx/object.h", + "$sdk_pkg_path/zx/include/lib/zx/object_traits.h", + "$sdk_pkg_path/zx/include/lib/zx/pmt.h", + "$sdk_pkg_path/zx/include/lib/zx/port.h", + "$sdk_pkg_path/zx/include/lib/zx/process.h", + "$sdk_pkg_path/zx/include/lib/zx/resource.h", + "$sdk_pkg_path/zx/include/lib/zx/socket.h", + "$sdk_pkg_path/zx/include/lib/zx/task.h", + "$sdk_pkg_path/zx/include/lib/zx/thread.h", + "$sdk_pkg_path/zx/include/lib/zx/time.h", + "$sdk_pkg_path/zx/include/lib/zx/timer.h", + "$sdk_pkg_path/zx/include/lib/zx/vmar.h", + "$sdk_pkg_path/zx/include/lib/zx/vmo.h", + "$sdk_pkg_path/zx/interrupt.cpp", + "$sdk_pkg_path/zx/job.cpp", + "$sdk_pkg_path/zx/log.cpp", + "$sdk_pkg_path/zx/port.cpp", + "$sdk_pkg_path/zx/process.cpp", + "$sdk_pkg_path/zx/resource.cpp", + "$sdk_pkg_path/zx/socket.cpp", + "$sdk_pkg_path/zx/thread.cpp", + "$sdk_pkg_path/zx/timer.cpp", + "$sdk_pkg_path/zx/vmar.cpp", + "$sdk_pkg_path/zx/vmo.cpp", + ] + + public_configs = [ ":zx_config" ] + } +} diff --git a/tools/generate_dump.cc b/tools/generate_dump.cc index 2cdaed27..9fb5a961 100644 --- a/tools/generate_dump.cc +++ b/tools/generate_dump.cc @@ -46,7 +46,8 @@ #include "util/win/scoped_process_suspend.h" #include "util/win/xp_compat.h" #elif defined(OS_FUCHSIA) -#include "base/fuchsia/scoped_zx_handle.h" +#include + #include "snapshot/fuchsia/process_snapshot_fuchsia.h" #include "util/fuchsia/koid_utilities.h" #include "util/fuchsia/scoped_task_suspend.h" @@ -165,8 +166,8 @@ int GenerateDumpMain(int argc, char* argv[]) { return EXIT_FAILURE; } #elif defined(OS_FUCHSIA) - base::ScopedZxHandle task = GetProcessFromKoid(options.pid); - if (!task.is_valid()) { + zx::process process = GetProcessFromKoid(options.pid); + if (!process.is_valid()) { LOG(ERROR) << "could not open process " << options.pid; return EXIT_FAILURE; } @@ -190,7 +191,7 @@ int GenerateDumpMain(int argc, char* argv[]) { #elif defined(OS_FUCHSIA) std::unique_ptr suspend; if (options.suspend) { - suspend.reset(new ScopedTaskSuspend(task.get())); + suspend.reset(new ScopedTaskSuspend(process)); } #endif // OS_MACOSX @@ -211,7 +212,7 @@ int GenerateDumpMain(int argc, char* argv[]) { } #elif defined(OS_FUCHSIA) ProcessSnapshotFuchsia process_snapshot; - if (!process_snapshot.Initialize(task.get())) { + if (!process_snapshot.Initialize(process)) { return EXIT_FAILURE; } #elif defined(OS_LINUX) || defined(OS_ANDROID) diff --git a/util/BUILD.gn b/util/BUILD.gn index 03220c9e..ec117573 100644 --- a/util/BUILD.gn +++ b/util/BUILD.gn @@ -454,6 +454,10 @@ static_library("util") { asmflags = [ "/safeseh" ] } } + + if (crashpad_is_fuchsia) { + public_deps += [ "../third_party/fuchsia:zx" ] + } } if (use_boringssl_for_http_transport_socket) { diff --git a/util/fuchsia/koid_utilities.cc b/util/fuchsia/koid_utilities.cc index 0d44f4af..65d3d94e 100644 --- a/util/fuchsia/koid_utilities.cc +++ b/util/fuchsia/koid_utilities.cc @@ -14,6 +14,8 @@ #include "util/fuchsia/koid_utilities.h" +#include +#include #include #include @@ -26,62 +28,104 @@ namespace crashpad { namespace { -base::ScopedZxHandle GetRootJob() { +// Casts |handle| into a container of type T, returning a null handle if the +// actual handle type does not match that of T. +template +T CastHandle(zx::handle handle) { + zx_info_handle_basic_t actual = {}; + zx_status_t status = handle.get_info( + ZX_INFO_HANDLE_BASIC, &actual, sizeof(actual), nullptr, nullptr); + if (status != ZX_OK) { + ZX_LOG(ERROR, status) << "zx_object_get_info"; + return T(); + } + if (actual.type != T::TYPE) { + LOG(ERROR) << "Wrong type: " << actual.type << ", expected " << T::TYPE; + return T(); + } + return T(std::move(handle)); +} + +zx::job GetRootJob() { ScopedFileHandle sysinfo( LoggingOpenFileForRead(base::FilePath("/dev/misc/sysinfo"))); if (!sysinfo.is_valid()) - return base::ScopedZxHandle(); + return zx::job(); - zx_handle_t root_job; - size_t n = ioctl_sysinfo_get_root_job(sysinfo.get(), &root_job); - if (n != sizeof(root_job)) { + zx::handle root_job; + size_t n = ioctl_sysinfo_get_root_job(sysinfo.get(), + root_job.reset_and_get_address()); + if (n != sizeof(zx_handle_t)) { LOG(ERROR) << "unexpected root job size"; - return base::ScopedZxHandle(); + return zx::job(); } - return base::ScopedZxHandle(root_job); + return CastHandle(std::move(root_job)); } -bool FindProcess(const base::ScopedZxHandle& job, - zx_koid_t koid, - base::ScopedZxHandle* out) { - for (auto& proc : GetChildHandles(job.get(), ZX_INFO_JOB_PROCESSES)) { - if (GetKoidForHandle(proc.get()) == koid) { - *out = std::move(proc); - return true; - } +// Returns null handle if |koid| is not found or an error occurs. If |was_found| +// is non-null then it will be set, to distinguish not-found from other errors. +template +T GetChildHandleByKoid(const U& parent, zx_koid_t child_koid, bool* was_found) { + zx::handle handle; + zx_status_t status = + parent.get_child(child_koid, ZX_RIGHT_SAME_RIGHTS, &handle); + if (was_found) + *was_found = (status != ZX_ERR_NOT_FOUND); + if (status != ZX_OK) { + ZX_LOG(ERROR, status) << "zx_object_get_child"; + return T(); } - // TODO(scottmg): As this is recursing down the job tree all the handles are - // kept open, so this could be very expensive in terms of number of open - // handles. This function should be replaced by a syscall in the - // not-too-distant future, so hopefully OK for now. - for (const auto& child_job : - GetChildHandles(job.get(), ZX_INFO_JOB_CHILDREN)) { - if (FindProcess(child_job, koid, out)) - return true; + return CastHandle(std::move(handle)); +} + +// Returns an invalid handle if the |koid| was found, but was of the wrong +// type, or we could not open a handle to it. +zx::process FindProcess(const zx::job& job, zx_koid_t koid, bool* was_found) { + DCHECK(!*was_found); + + // Look for |koid| as a direct descendent of |job|. + auto process = GetChildHandleByKoid(job, koid, was_found); + if (*was_found) { + // |koid| was found. |process| may still be null, e.g. if a handle could not + // be opened to it. + return process; } - return false; + // |koid| was not found under |job|, so search child jobs, if any. + // Since we only hold a handle to the job we are currently enumerating, child + // jobs may go away mid-enumeration. + for (auto child_koid : GetChildKoids(job, ZX_INFO_JOB_CHILDREN)) { + zx::job child_job = GetChildHandleByKoid(job, child_koid, nullptr); + if (!child_job.is_valid()) + continue; + zx::process process = FindProcess(child_job, koid, was_found); + if (*was_found) + return process; + } + + DCHECK(!*was_found); + return zx::process(); } } // namespace -std::vector GetChildKoids(zx_handle_t parent, +std::vector GetChildKoids(const zx::object_base& parent_object, zx_object_info_topic_t child_kind) { size_t actual = 0; size_t available = 0; std::vector result(100); + zx::unowned_handle parent(parent_object.get()); // This is inherently racy. Better if the process is suspended, but there's // still no guarantee that a thread isn't externally created. As a result, // must be in a retry loop. for (;;) { - zx_status_t status = zx_object_get_info(parent, - child_kind, - result.data(), - result.size() * sizeof(zx_koid_t), - &actual, - &available); + zx_status_t status = parent->get_info(child_kind, + result.data(), + result.size() * sizeof(zx_koid_t), + &actual, + &available); // If the buffer is too small (even zero), the result is still ZX_OK, not // ZX_ERR_BUFFER_TOO_SMALL. if (status != ZX_OK) { @@ -102,42 +146,38 @@ std::vector GetChildKoids(zx_handle_t parent, return result; } -std::vector GetChildHandles(zx_handle_t parent, - zx_object_info_topic_t type) { - auto koids = GetChildKoids(parent, type); - return GetHandlesForChildKoids(parent, koids); +std::vector GetThreadHandles(const zx::process& parent) { + auto koids = GetChildKoids(parent, ZX_INFO_PROCESS_THREADS); + return GetHandlesForThreadKoids(parent, koids); } -std::vector GetHandlesForChildKoids( - zx_handle_t parent, +std::vector GetHandlesForThreadKoids( + const zx::process& parent, const std::vector& koids) { - std::vector result; + std::vector result; result.reserve(koids.size()); for (zx_koid_t koid : koids) { - result.emplace_back(GetChildHandleByKoid(parent, koid)); + result.emplace_back(GetThreadHandleByKoid(parent, koid)); } return result; } -base::ScopedZxHandle GetChildHandleByKoid(zx_handle_t parent, - zx_koid_t child_koid) { - zx_handle_t handle; - zx_status_t status = - zx_object_get_child(parent, child_koid, ZX_RIGHT_SAME_RIGHTS, &handle); - if (status != ZX_OK) { - ZX_LOG(ERROR, status) << "zx_object_get_child"; - return base::ScopedZxHandle(); - } - return base::ScopedZxHandle(handle); +zx::thread GetThreadHandleByKoid(const zx::process& parent, + zx_koid_t child_koid) { + return GetChildHandleByKoid(parent, child_koid, nullptr); } -zx_koid_t GetKoidForHandle(zx_handle_t object) { +zx_koid_t GetKoidForHandle(const zx::object_base& object) { zx_info_handle_basic_t info; - zx_status_t status = zx_object_get_info( - object, ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr); + zx_status_t status = zx_object_get_info(object.get(), + ZX_INFO_HANDLE_BASIC, + &info, + sizeof(info), + nullptr, + nullptr); if (status != ZX_OK) { ZX_LOG(ERROR, status) << "zx_object_get_info"; - return ZX_HANDLE_INVALID; + return ZX_KOID_INVALID; } return info.koid; } @@ -146,11 +186,11 @@ zx_koid_t GetKoidForHandle(zx_handle_t object) { // ioctls that are currently the only way to go from pid to handle. This should // hopefully eventually be replaced by more or less a single // zx_debug_something() syscall. -base::ScopedZxHandle GetProcessFromKoid(zx_koid_t koid) { - base::ScopedZxHandle result; - if (!FindProcess(GetRootJob(), koid, &result)) { +zx::process GetProcessFromKoid(zx_koid_t koid) { + bool was_found = false; + zx::process result = FindProcess(GetRootJob(), koid, &was_found); + if (!result.is_valid()) LOG(ERROR) << "process " << koid << " not found"; - } return result; } diff --git a/util/fuchsia/koid_utilities.h b/util/fuchsia/koid_utilities.h index 5bcea105..9848dced 100644 --- a/util/fuchsia/koid_utilities.h +++ b/util/fuchsia/koid_utilities.h @@ -15,13 +15,14 @@ #ifndef CRASHPAD_UTIL_FUCHSIA_KOID_UTILITIES_H_ #define CRASHPAD_UTIL_FUCHSIA_KOID_UTILITIES_H_ +#include +#include +#include #include #include #include -#include "base/fuchsia/scoped_zx_handle.h" - namespace crashpad { //! \brief Get a list of child koids for a parent handle. @@ -38,57 +39,50 @@ namespace crashpad { //! \return A vector of the koids representing the child objects. //! //! \sa GetChildHandles -std::vector GetChildKoids(zx_handle_t parent, +std::vector GetChildKoids(const zx::object_base& parent, zx_object_info_topic_t child_kind); //! \brief Get handles representing a list of child objects of a given parent. //! //! \param[in] parent The handle to the parent object. -//! \param[in] child_kind The type of children to retrieve from \a parent. Valid -//! values depend on the type of \a parent, but include -//! `ZX_INFO_JOB_CHILDREN` (child jobs of a job), `ZX_INFO_JOB_PROCESSES` -//! (child processes of a job), and `ZX_INFO_PROCESS_THREADS` (child threads -//! of a process). //! \return The resulting list of handles corresponding to the child objects. //! //! \sa GetChildKoids -std::vector GetChildHandles( - zx_handle_t parent, - zx_object_info_topic_t child_kind); +std::vector GetThreadHandles(const zx::process& parent); -//! \brief Convert a list of koids that are all children of a particular object -//! into handles. +//! \brief Convert a list of koids that are all children of a particular process +//! into thread handles. //! //! \param[in] parent The parent object to which the koids belong. //! \param[in] koids The list of koids. //! \return The resulting list of handles corresponding to the koids. If an //! element of \a koids is invalid or can't be retrieved, there will be a //! corresponding `ZX_HANDLE_INVALID` entry in the return. -std::vector GetHandlesForChildKoids( - zx_handle_t parent, +std::vector GetHandlesForThreadKoids( + const zx::process& parent, const std::vector& koids); -//! \brief Retrieve the child of a parent handle, based on koid. +//! \brief Retrieve the handle of a process' thread, based on koid. //! //! \param[in] parent The parent object to which the child belongs. //! \param[in] child_koid The koid of the child to retrieve. //! \return A handle representing \a child_koid, or `ZX_HANDLE_INVALID` if the //! handle could not be retrieved, in which case an error will be logged. -base::ScopedZxHandle GetChildHandleByKoid(zx_handle_t parent, - zx_koid_t child_koid); +zx::thread GetThreadHandleByKoid(const zx::process& parent, + zx_koid_t child_koid); //! \brief Gets a process handle given the process' koid. //! //! \param[in] koid The process id. //! \return A zx_handle_t (owned by a base::ScopedZxHandle) for the process. If //! the handle is invalid, an error will have been logged. -base::ScopedZxHandle GetProcessFromKoid(zx_koid_t koid); +zx::process GetProcessFromKoid(zx_koid_t koid); //! \brief Retrieves the koid for a given object handle. //! //! \param[in] object The handle for which the koid is to be retrieved. //! \return The koid of \a handle, or `ZX_HANDLE_INVALID` with an error logged. -zx_koid_t GetKoidForHandle(zx_handle_t object); +zx_koid_t GetKoidForHandle(const zx::object_base& object); } // namespace crashpad diff --git a/util/fuchsia/scoped_task_suspend.cc b/util/fuchsia/scoped_task_suspend.cc index ca0fd564..0daaf635 100644 --- a/util/fuchsia/scoped_task_suspend.cc +++ b/util/fuchsia/scoped_task_suspend.cc @@ -14,14 +14,11 @@ #include "util/fuchsia/scoped_task_suspend.h" -#include -#include -#include +#include #include #include "base/fuchsia/fuchsia_logging.h" -#include "base/fuchsia/scoped_zx_handle.h" #include "base/logging.h" #include "util/fuchsia/koid_utilities.h" @@ -29,53 +26,37 @@ namespace crashpad { namespace { -zx_obj_type_t GetHandleType(zx_handle_t handle) { - zx_info_handle_basic_t basic; - zx_status_t status = zx_object_get_info( - handle, ZX_INFO_HANDLE_BASIC, &basic, sizeof(basic), nullptr, nullptr); - if (status != ZX_OK) { - ZX_LOG(ERROR, status) << "zx_object_get_info"; - return ZX_OBJ_TYPE_NONE; - } - return basic.type; -} - // Returns the suspend token of the suspended thread. This function attempts // to wait a short time for the thread to actually suspend before returning // but this is not guaranteed. -base::ScopedZxHandle SuspendThread(zx_handle_t thread) { - zx_handle_t token = ZX_HANDLE_INVALID; - zx_status_t status = zx_task_suspend_token(thread, &token); +zx::suspend_token SuspendThread(const zx::thread& thread) { + zx::suspend_token token; + zx_status_t status = thread.suspend(&token); if (status != ZX_OK) { ZX_LOG(ERROR, status) << "zx_task_suspend"; - base::ScopedZxHandle(); + return zx::suspend_token(); } zx_signals_t observed = 0u; - if (zx_object_wait_one(thread, ZX_THREAD_SUSPENDED, - zx_deadline_after(ZX_MSEC(50)), &observed) != ZX_OK) { + if (thread.wait_one(ZX_THREAD_SUSPENDED, + zx::deadline_after(zx::msec(50)), + &observed) != ZX_OK) { LOG(ERROR) << "thread failed to suspend"; } - return base::ScopedZxHandle(token); + return token; } } // namespace -ScopedTaskSuspend::ScopedTaskSuspend(zx_handle_t task) { - DCHECK_NE(task, zx_process_self()); - DCHECK_NE(task, zx_thread_self()); - - zx_obj_type_t type = GetHandleType(task); - if (type == ZX_OBJ_TYPE_THREAD) { - suspend_tokens_.push_back(SuspendThread(task)); - } else if (type == ZX_OBJ_TYPE_PROCESS) { - for (const auto& thread : GetChildHandles(task, ZX_INFO_PROCESS_THREADS)) - suspend_tokens_.push_back(SuspendThread(thread.get())); - } else { - LOG(ERROR) << "unexpected handle type"; - } +ScopedTaskSuspend::ScopedTaskSuspend(const zx::process& process) { + DCHECK_NE(process.get(), zx::process::self()->get()); + for (const auto& thread : GetThreadHandles(process)) + suspend_tokens_.push_back(SuspendThread(thread)); } -ScopedTaskSuspend::~ScopedTaskSuspend() = default; +ScopedTaskSuspend::ScopedTaskSuspend(const zx::thread& thread) { + DCHECK_NE(thread.get(), zx::thread::self()->get()); + suspend_tokens_.push_back(SuspendThread(thread)); +} } // namespace crashpad diff --git a/util/fuchsia/scoped_task_suspend.h b/util/fuchsia/scoped_task_suspend.h index f817364d..251904a8 100644 --- a/util/fuchsia/scoped_task_suspend.h +++ b/util/fuchsia/scoped_task_suspend.h @@ -15,11 +15,12 @@ #ifndef CRASHPAD_UTIL_FUCHSIA_SCOPED_TASK_SUSPEND_H_ #define CRASHPAD_UTIL_FUCHSIA_SCOPED_TASK_SUSPEND_H_ -#include +#include +#include +#include #include -#include "base/fuchsia/scoped_zx_handle.h" #include "base/macros.h" namespace crashpad { @@ -40,12 +41,13 @@ namespace crashpad { //! `zx_process_self()`. class ScopedTaskSuspend { public: - explicit ScopedTaskSuspend(zx_handle_t task); - ~ScopedTaskSuspend(); + explicit ScopedTaskSuspend(const zx::process& process); + explicit ScopedTaskSuspend(const zx::thread& thread); + ~ScopedTaskSuspend() = default; private: - // Could be one (for a thread) or many (for every process in a thread). - std::vector suspend_tokens_; + // Could be one (for a thread) or many (for every thread in a process). + std::vector suspend_tokens_; DISALLOW_COPY_AND_ASSIGN(ScopedTaskSuspend); }; diff --git a/util/process/process_memory_fuchsia.cc b/util/process/process_memory_fuchsia.cc index 212e1c6f..b9c4a0c3 100644 --- a/util/process/process_memory_fuchsia.cc +++ b/util/process/process_memory_fuchsia.cc @@ -14,8 +14,6 @@ #include "util/process/process_memory_fuchsia.h" -#include - #include #include "base/logging.h" @@ -28,9 +26,13 @@ ProcessMemoryFuchsia::ProcessMemoryFuchsia() ProcessMemoryFuchsia::~ProcessMemoryFuchsia() {} -bool ProcessMemoryFuchsia::Initialize(zx_handle_t process) { +bool ProcessMemoryFuchsia::Initialize(const zx::unowned_process& process) { + return Initialize(*process); +} + +bool ProcessMemoryFuchsia::Initialize(const zx::process& process) { INITIALIZATION_STATE_SET_INITIALIZING(initialized_); - process_ = process; + process_ = zx::unowned_process(process); INITIALIZATION_STATE_SET_VALID(initialized_); return true; } @@ -42,8 +44,7 @@ ssize_t ProcessMemoryFuchsia::ReadUpTo(VMAddress address, DCHECK_LE(size, size_t{std::numeric_limits::max()}); size_t actual; - zx_status_t status = - zx_process_read_memory(process_, address, buffer, size, &actual); + zx_status_t status = process_->read_memory(address, buffer, size, &actual); if (status != ZX_OK) { ZX_LOG(ERROR, status) << "zx_process_read_memory"; diff --git a/util/process/process_memory_fuchsia.h b/util/process/process_memory_fuchsia.h index e6cdd3e8..6c9cebaa 100644 --- a/util/process/process_memory_fuchsia.h +++ b/util/process/process_memory_fuchsia.h @@ -15,7 +15,7 @@ #ifndef CRASHPAD_UTIL_PROCESS_PROCESS_MEMORY_FUCHSIA_H_ #define CRASHPAD_UTIL_PROCESS_PROCESS_MEMORY_FUCHSIA_H_ -#include +#include #include @@ -40,12 +40,15 @@ class ProcessMemoryFuchsia final : public ProcessMemory { //! \param[in] process The handle to the target process. //! //! \return `true` on success, `false` on failure with a message logged. - bool Initialize(zx_handle_t process); + bool Initialize(const zx::process& process); + // TODO(wez): Remove this overload when zx::unowned_process allows implicit + // copy. + bool Initialize(const zx::unowned_process& process); private: ssize_t ReadUpTo(VMAddress address, size_t size, void* buffer) const override; - zx_handle_t process_; + zx::unowned_process process_; InitializationStateDcheck initialized_; DISALLOW_COPY_AND_ASSIGN(ProcessMemoryFuchsia); diff --git a/util/process/process_memory_range_test.cc b/util/process/process_memory_range_test.cc index 1c785068..3784e95d 100644 --- a/util/process/process_memory_range_test.cc +++ b/util/process/process_memory_range_test.cc @@ -24,7 +24,7 @@ #include "util/misc/from_pointer_cast.h" #if defined(OS_FUCHSIA) -#include +#include #include "util/process/process_memory_fuchsia.h" #else @@ -43,7 +43,7 @@ struct TestObject { TEST(ProcessMemoryRange, Basic) { #if defined(OS_FUCHSIA) ProcessMemoryFuchsia memory; - ASSERT_TRUE(memory.Initialize(zx_process_self())); + ASSERT_TRUE(memory.Initialize(*zx::process::self())); constexpr bool is_64_bit = true; #else pid_t pid = getpid();