Commit 8424720a authored by Vlad Tsyrklevich's avatar Vlad Tsyrklevich Committed by Commit Bot

Update Crashpad to abfad376ab08dfa42a984353004d72a38cadb198

f2a07982ff52 Change edge case handling in ReadCStringInternal
ffd666e16c5f fuchsia: Update Paths::Executable documentation
bf6d2e028376 Refactor TaskMemory initialization
7018a80b36be Simplify test set-up
8b2ec2aae4b2 Make TaskMemory a child class of ProcessMemory
4e3be595f360 Delete redundant TaskMemory tests
3f7d4d7d093c Break out redundant tests into a routine
3b9e3aad1b99 Move and rename TaskMemory to ProcessMemoryMac
fccd9c09c0b6 Implement ProcessSnapshotMac::Memory()
abfad376ab08 Add missing build/build_config.h includes

Bug: 912286
Change-Id: I23457a5a6dba367da94288654868f8663641316a
Reviewed-on: https://chromium-review.googlesource.com/c/1388064Reviewed-by: default avatarMark Mentovai <mark@chromium.org>
Commit-Queue: Vlad Tsyrklevich <vtsyrklevich@chromium.org>
Cr-Commit-Position: refs/heads/master@{#618420}
parent f536b926
...@@ -2,7 +2,7 @@ Name: Crashpad ...@@ -2,7 +2,7 @@ Name: Crashpad
Short Name: crashpad Short Name: crashpad
URL: https://crashpad.chromium.org/ URL: https://crashpad.chromium.org/
Version: unknown Version: unknown
Revision: 83867d52343b9657ad1263c2a6d5571dbc350b0c Revision: abfad376ab08dfa42a984353004d72a38cadb198
License: Apache 2.0 License: Apache 2.0
License File: crashpad/LICENSE License File: crashpad/LICENSE
Security Critical: yes Security Critical: yes
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include "snapshot/mac/mach_o_image_reader.h" #include "snapshot/mac/mach_o_image_reader.h"
#include "snapshot/mac/process_reader_mac.h" #include "snapshot/mac/process_reader_mac.h"
#include "snapshot/snapshot_constants.h" #include "snapshot/snapshot_constants.h"
#include "util/mach/task_memory.h"
#include "util/stdlib/strnlen.h" #include "util/stdlib/strnlen.h"
namespace crashpad { namespace crashpad {
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "util/mac/checked_mach_address_range.h" #include "util/mac/checked_mach_address_range.h"
#include "util/mach/task_memory.h" #include "util/process/process_memory_mac.h"
namespace crashpad { namespace crashpad {
...@@ -108,7 +108,7 @@ class MachOImageSymbolTableReaderInitializer { ...@@ -108,7 +108,7 @@ class MachOImageSymbolTableReaderInitializer {
return false; return false;
} }
std::unique_ptr<TaskMemory::MappedMemory> string_table; std::unique_ptr<ProcessMemoryMac::MappedMemory> string_table;
for (size_t symbol_index = 0; symbol_index < symbol_count; ++symbol_index) { for (size_t symbol_index = 0; symbol_index < symbol_count; ++symbol_index) {
const process_types::nlist& symbol = symbols[symbol_index]; const process_types::nlist& symbol = symbols[symbol_index];
std::string symbol_info = base::StringPrintf(", symbol index %zu%s", std::string symbol_info = base::StringPrintf(", symbol index %zu%s",
......
...@@ -58,7 +58,7 @@ class MachOImageSymbolTableReader { ...@@ -58,7 +58,7 @@ class MachOImageSymbolTableReader {
// there aren’t expected to be very many of those that performance would // there aren’t expected to be very many of those that performance would
// become a problem. In reality, std::unordered_map does not appear to provide // become a problem. In reality, std::unordered_map does not appear to provide
// a performance advantage. It appears that the memory copies currently done // a performance advantage. It appears that the memory copies currently done
// by TaskMemory::Read() have substantially more impact on symbol table // by ProcessMemoryMac::Read() have substantially more impact on symbol table
// operations. // operations.
// //
// This is public so that the type is available to // This is public so that the type is available to
......
...@@ -92,7 +92,7 @@ ProcessReaderMac::ProcessReaderMac() ...@@ -92,7 +92,7 @@ ProcessReaderMac::ProcessReaderMac()
threads_(), threads_(),
modules_(), modules_(),
module_readers_(), module_readers_(),
task_memory_(), process_memory_(),
task_(TASK_NULL), task_(TASK_NULL),
initialized_(), initialized_(),
is_64_bit_(false), is_64_bit_(false),
...@@ -113,9 +113,11 @@ bool ProcessReaderMac::Initialize(task_t task) { ...@@ -113,9 +113,11 @@ bool ProcessReaderMac::Initialize(task_t task) {
return false; return false;
} }
is_64_bit_ = process_info_.Is64Bit(); if (!process_memory_.Initialize(task)) {
return false;
}
task_memory_.reset(new TaskMemory(task)); is_64_bit_ = process_info_.Is64Bit();
task_ = task; task_ = task;
INITIALIZATION_STATE_SET_VALID(initialized_); INITIALIZATION_STATE_SET_VALID(initialized_);
...@@ -441,7 +443,7 @@ void ProcessReaderMac::InitializeModules() { ...@@ -441,7 +443,7 @@ void ProcessReaderMac::InitializeModules() {
Module module; Module module;
module.timestamp = image_info.imageFileModDate; module.timestamp = image_info.imageFileModDate;
if (!task_memory_->ReadCString(image_info.imageFilePath, &module.name)) { if (!process_memory_.ReadCString(image_info.imageFilePath, &module.name)) {
LOG(WARNING) << "could not read dyld_image_info::imageFilePath"; LOG(WARNING) << "could not read dyld_image_info::imageFilePath";
// Proceed anyway with an empty module name. // Proceed anyway with an empty module name.
} }
......
...@@ -27,9 +27,9 @@ ...@@ -27,9 +27,9 @@
#include "base/macros.h" #include "base/macros.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "util/mach/task_memory.h"
#include "util/misc/initialization_state_dcheck.h" #include "util/misc/initialization_state_dcheck.h"
#include "util/posix/process_info.h" #include "util/posix/process_info.h"
#include "util/process/process_memory_mac.h"
namespace crashpad { namespace crashpad {
...@@ -138,7 +138,7 @@ class ProcessReaderMac { ...@@ -138,7 +138,7 @@ class ProcessReaderMac {
bool CPUTimes(timeval* user_time, timeval* system_time) const; bool CPUTimes(timeval* user_time, timeval* system_time) const;
//! \return Accesses the memory of the target task. //! \return Accesses the memory of the target task.
TaskMemory* Memory() { return task_memory_.get(); } const ProcessMemoryMac* Memory() const { return &process_memory_; }
//! \return The threads that are in the task (process). The first element (at //! \return The threads that are in the task (process). The first element (at
//! index `0`) corresponds to the main thread. //! index `0`) corresponds to the main thread.
...@@ -232,7 +232,7 @@ class ProcessReaderMac { ...@@ -232,7 +232,7 @@ class ProcessReaderMac {
std::vector<Thread> threads_; // owns send rights std::vector<Thread> threads_; // owns send rights
std::vector<Module> modules_; std::vector<Module> modules_;
std::vector<std::unique_ptr<MachOImageReader>> module_readers_; std::vector<std::unique_ptr<MachOImageReader>> module_readers_;
std::unique_ptr<TaskMemory> task_memory_; ProcessMemoryMac process_memory_;
task_t task_; // weak task_t task_; // weak
InitializationStateDcheck initialized_; InitializationStateDcheck initialized_;
......
...@@ -219,8 +219,7 @@ std::vector<const MemorySnapshot*> ProcessSnapshotMac::ExtraMemory() const { ...@@ -219,8 +219,7 @@ std::vector<const MemorySnapshot*> ProcessSnapshotMac::ExtraMemory() const {
const ProcessMemory* ProcessSnapshotMac::Memory() const { const ProcessMemory* ProcessSnapshotMac::Memory() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_); INITIALIZATION_STATE_DCHECK_VALID(initialized_);
NOTREACHED(); // https://crashpad.chromium.org/bug/263 return process_reader_.Memory();
return nullptr;
} }
void ProcessSnapshotMac::InitializeThreads() { void ProcessSnapshotMac::InitializeThreads() {
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "snapshot/mac/process_types/internal.h" #include "snapshot/mac/process_types/internal.h"
#include "util/mach/task_memory.h" #include "util/process/process_memory_mac.h"
namespace crashpad { namespace crashpad {
namespace { namespace {
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include "base/numerics/safe_math.h" #include "base/numerics/safe_math.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "snapshot/mac/process_types/internal.h" #include "snapshot/mac/process_types/internal.h"
#include "util/mach/task_memory.h" #include "util/process/process_memory_mac.h"
#if !DOXYGEN #if !DOXYGEN
...@@ -36,13 +36,13 @@ namespace internal { ...@@ -36,13 +36,13 @@ namespace internal {
namespace { namespace {
template <typename T> template <typename T>
bool ReadIntoAndZero(TaskMemory* task_memory, bool ReadIntoAndZero(const ProcessMemoryMac* process_memory,
mach_vm_address_t address, mach_vm_address_t address,
mach_vm_size_t size, mach_vm_size_t size,
T* specific) { T* specific) {
DCHECK_LE(size, sizeof(*specific)); DCHECK_LE(size, sizeof(*specific));
if (!task_memory->Read(address, size, specific)) { if (!process_memory->Read(address, size, specific)) {
return false; return false;
} }
...@@ -84,14 +84,14 @@ bool ReadIntoVersioned(ProcessReaderMac* process_reader, ...@@ -84,14 +84,14 @@ bool ReadIntoVersioned(ProcessReaderMac* process_reader,
return false; return false;
} }
TaskMemory* task_memory = process_reader->Memory(); const ProcessMemoryMac* process_memory = process_reader->Memory();
decltype(specific->version) version; decltype(specific->version) version;
if (!task_memory->Read(field_address, sizeof(version), &version)) { if (!process_memory->Read(field_address, sizeof(version), &version)) {
return false; return false;
} }
const size_t size = T::ExpectedSizeForVersion(version); const size_t size = T::ExpectedSizeForVersion(version);
return ReadIntoAndZero(task_memory, address, size, specific); return ReadIntoAndZero(process_memory, address, size, specific);
} }
template <typename T> template <typename T>
...@@ -103,9 +103,9 @@ bool ReadIntoSized(ProcessReaderMac* process_reader, ...@@ -103,9 +103,9 @@ bool ReadIntoSized(ProcessReaderMac* process_reader,
return false; return false;
} }
TaskMemory* task_memory = process_reader->Memory(); const ProcessMemoryMac* process_memory = process_reader->Memory();
decltype(specific->size) size; decltype(specific->size) size;
if (!task_memory->Read(address + offsetof(T, size), sizeof(size), &size)) { if (!process_memory->Read(address + offsetof(T, size), sizeof(size), &size)) {
return false; return false;
} }
...@@ -115,7 +115,7 @@ bool ReadIntoSized(ProcessReaderMac* process_reader, ...@@ -115,7 +115,7 @@ bool ReadIntoSized(ProcessReaderMac* process_reader,
} }
size = std::min(static_cast<size_t>(size), sizeof(*specific)); size = std::min(static_cast<size_t>(size), sizeof(*specific));
return ReadIntoAndZero(task_memory, address, size, specific); return ReadIntoAndZero(process_memory, address, size, specific);
} }
} // namespace } // namespace
......
...@@ -122,7 +122,9 @@ class MultiprocessExec : public Multiprocess { ...@@ -122,7 +122,9 @@ class MultiprocessExec : public Multiprocess {
//! //!
//! This method is only valid during the body of MultiprocessParent(). //! This method is only valid during the body of MultiprocessParent().
//! //!
//! \return A platform-specific type representing the child process. //! \return A platform-specific type representing the child process. This
//! method can fail on macOS because access to a child's task port
//! requires the task_for_pid entitlement.
ProcessType ChildProcess(); ProcessType ChildProcess();
protected: protected:
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <unistd.h> #include <unistd.h>
#include "base/posix/eintr_wrapper.h" #include "base/posix/eintr_wrapper.h"
#include "build/build_config.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "test/errors.h" #include "test/errors.h"
#include "util/misc/scoped_forbid_return.h" #include "util/misc/scoped_forbid_return.h"
...@@ -29,6 +30,10 @@ ...@@ -29,6 +30,10 @@
#include <stdio_ext.h> #include <stdio_ext.h>
#endif #endif
#if defined(OS_MACOSX)
#include "util/mach/task_for_pid.h"
#endif
namespace crashpad { namespace crashpad {
namespace test { namespace test {
...@@ -149,7 +154,11 @@ void MultiprocessExec::MultiprocessChild() { ...@@ -149,7 +154,11 @@ void MultiprocessExec::MultiprocessChild() {
} }
ProcessType MultiprocessExec::ChildProcess() { ProcessType MultiprocessExec::ChildProcess() {
#if defined(OS_MACOSX)
return TaskForPID(ChildPID());
#else
return ChildPID(); return ChildPID();
#endif
} }
} // namespace test } // namespace test
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#if defined(OS_FUCHSIA) #if defined(OS_FUCHSIA)
#include <lib/zx/process.h> #include <lib/zx/process.h>
#elif defined(OS_POSIX) #elif defined(OS_LINUX) || defined(OS_ANDROID)
#include <unistd.h> #include <unistd.h>
#endif #endif
...@@ -26,10 +26,12 @@ namespace test { ...@@ -26,10 +26,12 @@ namespace test {
ProcessType GetSelfProcess() { ProcessType GetSelfProcess() {
#if defined(OS_FUCHSIA) #if defined(OS_FUCHSIA)
return zx::process::self(); return zx::process::self();
#elif defined(OS_POSIX) #elif defined(OS_LINUX) || defined(OS_ANDROID)
return getpid(); return getpid();
#elif defined(OS_WIN) #elif defined(OS_WIN)
return GetCurrentProcess(); return GetCurrentProcess();
#elif defined(OS_MACOSX)
return mach_task_self();
#endif #endif
} }
......
...@@ -19,10 +19,12 @@ ...@@ -19,10 +19,12 @@
#if defined(OS_FUCHSIA) #if defined(OS_FUCHSIA)
#include <lib/zx/process.h> #include <lib/zx/process.h>
#elif defined(OS_POSIX) #elif defined(OS_LINUX) || defined(OS_ANDROID)
#include <sys/types.h> #include <sys/types.h>
#elif defined(OS_WIN) #elif defined(OS_WIN)
#include <windows.h> #include <windows.h>
#elif defined(OS_MACOSX)
#include <mach/mach.h>
#endif #endif
namespace crashpad { namespace crashpad {
...@@ -30,11 +32,13 @@ namespace test { ...@@ -30,11 +32,13 @@ namespace test {
#if defined(OS_FUCHSIA) #if defined(OS_FUCHSIA)
using ProcessType = zx::unowned_process; using ProcessType = zx::unowned_process;
#elif defined(OS_POSIX) || DOXYGEN #elif defined(OS_LINUX) || defined(OS_ANDROID) || DOXYGEN
//! \brief Alias for platform-specific type to represent a process. //! \brief Alias for platform-specific type to represent a process.
using ProcessType = pid_t; using ProcessType = pid_t;
#elif defined(OS_WIN) #elif defined(OS_WIN)
using ProcessType = HANDLE; using ProcessType = HANDLE;
#elif defined(OS_MACOSX)
using ProcessType = task_t;
#else #else
#error Port. #error Port.
#endif #endif
......
...@@ -137,6 +137,11 @@ static_library("util") { ...@@ -137,6 +137,11 @@ static_library("util") {
"numeric/in_range_cast.h", "numeric/in_range_cast.h",
"numeric/int128.h", "numeric/int128.h",
"numeric/safe_assignment.h", "numeric/safe_assignment.h",
"process/process_memory.cc",
"process/process_memory.h",
"process/process_memory_native.h",
"process/process_memory_range.cc",
"process/process_memory_range.h",
"stdlib/aligned_allocator.cc", "stdlib/aligned_allocator.cc",
"stdlib/aligned_allocator.h", "stdlib/aligned_allocator.h",
"stdlib/map_insert.h", "stdlib/map_insert.h",
...@@ -239,13 +244,13 @@ static_library("util") { ...@@ -239,13 +244,13 @@ static_library("util") {
"mach/symbolic_constants_mach.h", "mach/symbolic_constants_mach.h",
"mach/task_for_pid.cc", "mach/task_for_pid.cc",
"mach/task_for_pid.h", "mach/task_for_pid.h",
"mach/task_memory.cc",
"mach/task_memory.h",
"misc/capture_context_mac.S", "misc/capture_context_mac.S",
"misc/clock_mac.cc", "misc/clock_mac.cc",
"misc/paths_mac.cc", "misc/paths_mac.cc",
"net/http_transport_mac.mm", "net/http_transport_mac.mm",
"posix/process_info_mac.cc", "posix/process_info_mac.cc",
"process/process_memory_mac.cc",
"process/process_memory_mac.h",
"synchronization/semaphore_mac.cc", "synchronization/semaphore_mac.cc",
] ]
sources += get_target_outputs(":mig") sources += get_target_outputs(":mig")
...@@ -313,19 +318,6 @@ static_library("util") { ...@@ -313,19 +318,6 @@ static_library("util") {
] ]
} }
if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia ||
crashpad_is_win) {
sources += [
"process/process_memory.cc",
"process/process_memory.h",
"process/process_memory_native.h",
# TODO: Port to all platforms.
"process/process_memory_range.cc",
"process/process_memory_range.h",
]
}
if (crashpad_is_win) { if (crashpad_is_win) {
sources += [ sources += [
"file/directory_reader_win.cc", "file/directory_reader_win.cc",
...@@ -562,6 +554,8 @@ source_set("util_test") { ...@@ -562,6 +554,8 @@ source_set("util_test") {
"numeric/checked_range_test.cc", "numeric/checked_range_test.cc",
"numeric/in_range_cast_test.cc", "numeric/in_range_cast_test.cc",
"numeric/int128_test.cc", "numeric/int128_test.cc",
"process/process_memory_range_test.cc",
"process/process_memory_test.cc",
"stdlib/aligned_allocator_test.cc", "stdlib/aligned_allocator_test.cc",
"stdlib/map_insert_test.cc", "stdlib/map_insert_test.cc",
"stdlib/string_number_conversion_test.cc", "stdlib/string_number_conversion_test.cc",
...@@ -611,8 +605,8 @@ source_set("util_test") { ...@@ -611,8 +605,8 @@ source_set("util_test") {
"mach/notify_server_test.cc", "mach/notify_server_test.cc",
"mach/scoped_task_suspend_test.cc", "mach/scoped_task_suspend_test.cc",
"mach/symbolic_constants_mach_test.cc", "mach/symbolic_constants_mach_test.cc",
"mach/task_memory_test.cc",
"misc/capture_context_test_util_mac.cc", "misc/capture_context_test_util_mac.cc",
"process/process_memory_mac_test.cc",
] ]
} }
...@@ -633,15 +627,6 @@ source_set("util_test") { ...@@ -633,15 +627,6 @@ source_set("util_test") {
sources += [ "misc/capture_context_test_util_fuchsia.cc" ] sources += [ "misc/capture_context_test_util_fuchsia.cc" ]
} }
if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia ||
crashpad_is_win) {
sources += [
# TODO: Port to all platforms.
"process/process_memory_range_test.cc",
"process/process_memory_test.cc",
]
}
if (crashpad_is_win) { if (crashpad_is_win) {
sources += [ sources += [
"misc/capture_context_test_util_win.cc", "misc/capture_context_test_util_win.cc",
......
...@@ -25,7 +25,7 @@ namespace crashpad { ...@@ -25,7 +25,7 @@ namespace crashpad {
// static // static
bool Paths::Executable(base::FilePath* path) { bool Paths::Executable(base::FilePath* path) {
// Assume the environment has been set up following // Assume the environment has been set up following
// https://fuchsia.googlesource.com/docs/+/master/namespaces.md#typical-directory-structure // https://fuchsia.googlesource.com/docs/+/master/the-book/namespaces.md#typical-directory-structure
// . // .
*path = base::FilePath("/pkg/bin/app"); *path = base::FilePath("/pkg/bin/app");
return true; return true;
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#include "util/mach/task_memory.h" #include "util/process/process_memory_mac.h"
#include <mach/mach_vm.h> #include <mach/mach_vm.h>
#include <string.h> #include <string.h>
...@@ -26,11 +26,10 @@ ...@@ -26,11 +26,10 @@
namespace crashpad { namespace crashpad {
TaskMemory::MappedMemory::~MappedMemory() { ProcessMemoryMac::MappedMemory::~MappedMemory() {}
}
bool TaskMemory::MappedMemory::ReadCString( bool ProcessMemoryMac::MappedMemory::ReadCString(size_t offset,
size_t offset, std::string* string) const { std::string* string) const {
if (offset >= user_size_) { if (offset >= user_size_) {
LOG(WARNING) << "offset out of range"; LOG(WARNING) << "offset out of range";
return false; return false;
...@@ -48,10 +47,10 @@ bool TaskMemory::MappedMemory::ReadCString( ...@@ -48,10 +47,10 @@ bool TaskMemory::MappedMemory::ReadCString(
return true; return true;
} }
TaskMemory::MappedMemory::MappedMemory(vm_address_t vm_address, ProcessMemoryMac::MappedMemory::MappedMemory(vm_address_t vm_address,
size_t vm_size, size_t vm_size,
size_t user_offset, size_t user_offset,
size_t user_size) size_t user_size)
: vm_(vm_address, vm_size), : vm_(vm_address, vm_size),
data_(reinterpret_cast<const void*>(vm_address + user_offset)), data_(reinterpret_cast<const void*>(vm_address + user_offset)),
user_size_(user_size) { user_size_(user_size) {
...@@ -64,22 +63,20 @@ TaskMemory::MappedMemory::MappedMemory(vm_address_t vm_address, ...@@ -64,22 +63,20 @@ TaskMemory::MappedMemory::MappedMemory(vm_address_t vm_address,
DCHECK_LE(user_end, vm_end); DCHECK_LE(user_end, vm_end);
} }
TaskMemory::TaskMemory(task_t task) : task_(task) { ProcessMemoryMac::ProcessMemoryMac() : task_(TASK_NULL), initialized_() {}
}
bool TaskMemory::Read(mach_vm_address_t address, size_t size, void* buffer) {
std::unique_ptr<MappedMemory> memory = ReadMapped(address, size);
if (!memory) {
return false;
}
memcpy(buffer, memory->data(), size); bool ProcessMemoryMac::Initialize(task_t task) {
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
task_ = task;
INITIALIZATION_STATE_SET_VALID(initialized_);
return true; return true;
} }
std::unique_ptr<TaskMemory::MappedMemory> TaskMemory::ReadMapped( std::unique_ptr<ProcessMemoryMac::MappedMemory> ProcessMemoryMac::ReadMapped(
mach_vm_address_t address, mach_vm_address_t address,
size_t size) { size_t size) const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
if (size == 0) { if (size == 0) {
return std::unique_ptr<MappedMemory>(new MappedMemory(0, 0, 0, 0)); return std::unique_ptr<MappedMemory>(new MappedMemory(0, 0, 0, 0));
} }
...@@ -103,57 +100,29 @@ std::unique_ptr<TaskMemory::MappedMemory> TaskMemory::ReadMapped( ...@@ -103,57 +100,29 @@ std::unique_ptr<TaskMemory::MappedMemory> TaskMemory::ReadMapped(
new MappedMemory(region, region_size, address - region_address, size)); new MappedMemory(region, region_size, address - region_address, size));
} }
bool TaskMemory::ReadCString(mach_vm_address_t address, std::string* string) { ssize_t ProcessMemoryMac::ReadUpTo(VMAddress address,
return ReadCStringInternal(address, false, 0, string); size_t size,
} void* buffer) const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
DCHECK_LE(size, (size_t)std::numeric_limits<ssize_t>::max());
bool TaskMemory::ReadCStringSizeLimited(mach_vm_address_t address, std::unique_ptr<MappedMemory> memory = ReadMapped(address, size);
mach_vm_size_t size, if (!memory) {
std::string* string) { // If we can not read the entire mapping, try to perform a short read of the
return ReadCStringInternal(address, true, size, string); // first page instead. This is necessary to support ReadCString().
} size_t short_read = PAGE_SIZE - (address % PAGE_SIZE);
if (short_read >= size)
return -1;
memory = ReadMapped(address, short_read);
if (!memory)
return -1;
bool TaskMemory::ReadCStringInternal(mach_vm_address_t address, size = short_read;
bool has_size,
mach_vm_size_t size,
std::string* string) {
if (has_size) {
if (size == 0) {
string->clear();
return true;
}
} else {
size = PAGE_SIZE;
} }
std::string local_string; memcpy(buffer, memory->data(), size);
mach_vm_address_t read_address = address; return static_cast<ssize_t>(size);
do {
mach_vm_size_t read_length =
std::min(size, PAGE_SIZE - (read_address % PAGE_SIZE));
std::unique_ptr<MappedMemory> read_region =
ReadMapped(read_address, read_length);
if (!read_region) {
return false;
}
const char* read_region_data =
reinterpret_cast<const char*>(read_region->data());
size_t read_region_data_length = strnlen(read_region_data, read_length);
local_string.append(read_region_data, read_region_data_length);
if (read_region_data_length < read_length) {
string->swap(local_string);
return true;
}
if (has_size) {
size -= read_length;
}
read_address = mach_vm_trunc_page(read_address + read_length);
} while ((!has_size || size > 0) && read_address > address);
LOG(WARNING) << base::StringPrintf("unterminated string at 0x%llx", address);
return false;
} }
} // namespace crashpad } // namespace crashpad
...@@ -12,8 +12,8 @@ ...@@ -12,8 +12,8 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
#ifndef CRASHPAD_UTIL_MACH_TASK_MEMORY_H_ #ifndef CRASHPAD_UTIL_PROCESS_PROCESS_MEMORY_MAC_H_
#define CRASHPAD_UTIL_MACH_TASK_MEMORY_H_ #define CRASHPAD_UTIL_PROCESS_PROCESS_MEMORY_MAC_H_
#include <mach/mach.h> #include <mach/mach.h>
#include <sys/types.h> #include <sys/types.h>
...@@ -23,11 +23,14 @@ ...@@ -23,11 +23,14 @@
#include "base/mac/scoped_mach_vm.h" #include "base/mac/scoped_mach_vm.h"
#include "base/macros.h" #include "base/macros.h"
#include "util/misc/address_types.h"
#include "util/misc/initialization_state_dcheck.h"
#include "util/process/process_memory.h"
namespace crashpad { namespace crashpad {
//! \brief Accesses the memory of another Mach task. //! \brief Accesses the memory of another Mach task.
class TaskMemory { class ProcessMemoryMac : public ProcessMemory {
public: public:
//! \brief A memory region mapped from another Mach task. //! \brief A memory region mapped from another Mach task.
//! //!
...@@ -82,33 +85,25 @@ class TaskMemory { ...@@ -82,33 +85,25 @@ class TaskMemory {
size_t user_size_; size_t user_size_;
// The outer class needs to be able to call this class’ private constructor. // The outer class needs to be able to call this class’ private constructor.
friend class TaskMemory; friend class ProcessMemoryMac;
DISALLOW_COPY_AND_ASSIGN(MappedMemory); DISALLOW_COPY_AND_ASSIGN(MappedMemory);
}; };
//! \param[in] task A send right to the target task’s task port. This object ProcessMemoryMac();
//! does not take ownership of the send right. ~ProcessMemoryMac() {}
explicit TaskMemory(task_t task);
~TaskMemory() {}
//! \brief Copies memory from the target task into a caller-provided buffer in //! \brief Initializes this object to read the memory of a task with the
//! the current task. //! provided task port.
//! //!
//! \param[in] address The address, in the target task’s address space, of the //! This method must be called successfully prior to calling any other method
//! memory region to copy. //! in this class.
//! \param[in] size The size, in bytes, of the memory region to copy. \a
//! buffer must be at least this size.
//! \param[out] buffer The buffer into which the contents of the other task’s
//! memory will be copied.
//! //!
//! \return `true` on success, with \a buffer filled appropriately. `false` on //! \param[in] task A send right to the target task's task port. This object
//! failure, with a warning logged. Failures can occur, for example, when //! does not take ownership of the send right.
//! encountering unmapped or unreadable pages.
//! //!
//! \sa ReadMapped() //! \return `true` on success, `false` on failure with a message logged.
bool Read(mach_vm_address_t address, size_t size, void* buffer); bool Initialize(task_t task);
//! \brief Maps memory from the target task into the current task. //! \brief Maps memory from the target task into the current task.
//! //!
...@@ -124,56 +119,17 @@ class TaskMemory { ...@@ -124,56 +119,17 @@ class TaskMemory {
//! requested. On faliure, `nullptr`, with a warning logged. Failures can //! requested. On faliure, `nullptr`, with a warning logged. Failures can
//! occur, for example, when encountering unmapped or unreadable pages. //! occur, for example, when encountering unmapped or unreadable pages.
std::unique_ptr<MappedMemory> ReadMapped(mach_vm_address_t address, std::unique_ptr<MappedMemory> ReadMapped(mach_vm_address_t address,
size_t size); size_t size) const;
//! \brief Reads a `NUL`-terminated C string from the target task into a
//! string in the current task.
//!
//! The length of the string need not be known ahead of time. This method will
//! read contiguous memory until a `NUL` terminator is found.
//!
//! \param[in] address The address, in the target task’s address space, of the
//! string to copy.
//! \param[out] string The string read from the other task.
//!
//! \return `true` on success, with \a string set appropriately. `false` on
//! failure, with a warning logged. Failures can occur, for example, when
//! encountering unmapped or unreadable pages.
//!
//! \sa MappedMemory::ReadCString()
bool ReadCString(mach_vm_address_t address, std::string* string);
//! \brief Reads a `NUL`-terminated C string from the target task into a
//! string in the current task.
//!
//! \param[in] address The address, in the target task’s address space, of the
//! string to copy.
//! \param[in] size The maximum number of bytes to read. The string is
//! required to be `NUL`-terminated within this many bytes.
//! \param[out] string The string read from the other task.
//!
//! \return `true` on success, with \a string set appropriately. `false` on
//! failure, with a warning logged. Failures can occur, for example, when
//! a `NUL` terminator is not found within \a size bytes, or when
//! encountering unmapped or unreadable pages.
//!
//! \sa MappedMemory::ReadCString()
bool ReadCStringSizeLimited(mach_vm_address_t address,
mach_vm_size_t size,
std::string* string);
private: private:
// The common internal implementation shared by the ReadCString*() methods. ssize_t ReadUpTo(VMAddress address, size_t size, void* buffer) const override;
bool ReadCStringInternal(mach_vm_address_t address,
bool has_size,
mach_vm_size_t size,
std::string* string);
task_t task_; // weak task_t task_; // weak
InitializationStateDcheck initialized_;
DISALLOW_COPY_AND_ASSIGN(TaskMemory); DISALLOW_COPY_AND_ASSIGN(ProcessMemoryMac);
}; };
} // namespace crashpad } // namespace crashpad
#endif // CRASHPAD_UTIL_MACH_TASK_MEMORY_H_ #endif // CRASHPAD_UTIL_PROCESS_PROCESS_MEMORY_MAC_H_
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include "util/process/process_memory_linux.h" #include "util/process/process_memory_linux.h"
#elif defined(OS_WIN) #elif defined(OS_WIN)
#include "util/process/process_memory_win.h" #include "util/process/process_memory_win.h"
#elif defined(OS_MACOSX)
#include "util/process/process_memory_mac.h"
#endif #endif
namespace crashpad { namespace crashpad {
...@@ -31,6 +33,8 @@ using ProcessMemoryNative = ProcessMemoryFuchsia; ...@@ -31,6 +33,8 @@ using ProcessMemoryNative = ProcessMemoryFuchsia;
using ProcessMemoryNative = ProcessMemoryLinux; using ProcessMemoryNative = ProcessMemoryLinux;
#elif defined(OS_WIN) #elif defined(OS_WIN)
using ProcessMemoryNative = ProcessMemoryWin; using ProcessMemoryNative = ProcessMemoryWin;
#elif defined(OS_MACOSX)
using ProcessMemoryNative = ProcessMemoryMac;
#else #else
#error Port. #error Port.
#endif #endif
......
...@@ -20,18 +20,8 @@ ...@@ -20,18 +20,8 @@
#include "build/build_config.h" #include "build/build_config.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "util/misc/from_pointer_cast.h" #include "util/misc/from_pointer_cast.h"
#include "util/process/process_memory_native.h"
#if defined(OS_FUCHSIA) #include "test/process_type.h"
#include <lib/zx/process.h>
#include "util/process/process_memory_fuchsia.h"
#elif defined(OS_WIN)
#include "util/process/process_memory_win.h"
#else
#include <unistd.h>
#include "util/process/process_memory_linux.h"
#endif
namespace crashpad { namespace crashpad {
namespace test { namespace test {
...@@ -49,16 +39,8 @@ TEST(ProcessMemoryRange, Basic) { ...@@ -49,16 +39,8 @@ TEST(ProcessMemoryRange, Basic) {
constexpr bool is_64_bit = false; constexpr bool is_64_bit = false;
#endif // ARCH_CPU_64_BITS #endif // ARCH_CPU_64_BITS
#if defined(OS_FUCHSIA) ProcessMemoryNative memory;
ProcessMemoryFuchsia memory; ASSERT_TRUE(memory.Initialize(GetSelfProcess()));
ASSERT_TRUE(memory.Initialize(*zx::process::self()));
#elif defined(OS_WIN)
ProcessMemoryWin memory;
ASSERT_TRUE(memory.Initialize(GetCurrentProcess()));
#elif defined(OS_LINUX) || defined(OS_ANDROID)
ProcessMemoryLinux memory;
ASSERT_TRUE(memory.Initialize(getpid()));
#endif // OS_FUCHSIA
ProcessMemoryRange range; ProcessMemoryRange range;
ASSERT_TRUE(range.Initialize(&memory, is_64_bit)); ASSERT_TRUE(range.Initialize(&memory, is_64_bit));
......
...@@ -124,8 +124,6 @@ ...@@ -124,8 +124,6 @@
'mach/symbolic_constants_mach.h', 'mach/symbolic_constants_mach.h',
'mach/task_for_pid.cc', 'mach/task_for_pid.cc',
'mach/task_for_pid.h', 'mach/task_for_pid.h',
'mach/task_memory.cc',
'mach/task_memory.h',
'misc/address_sanitizer.h', 'misc/address_sanitizer.h',
'misc/address_types.h', 'misc/address_types.h',
'misc/arraysize_unsafe.h', 'misc/arraysize_unsafe.h',
...@@ -215,6 +213,8 @@ ...@@ -215,6 +213,8 @@
'process/process_memory.h', 'process/process_memory.h',
'process/process_memory_linux.cc', 'process/process_memory_linux.cc',
'process/process_memory_linux.h', 'process/process_memory_linux.h',
'process/process_memory_mac.cc',
'process/process_memory_mac.h',
'process/process_memory_native.h', 'process/process_memory_native.h',
'process/process_memory_range.cc', 'process/process_memory_range.cc',
'process/process_memory_range.h', 'process/process_memory_range.h',
......
...@@ -65,7 +65,6 @@ ...@@ -65,7 +65,6 @@
'mach/notify_server_test.cc', 'mach/notify_server_test.cc',
'mach/scoped_task_suspend_test.cc', 'mach/scoped_task_suspend_test.cc',
'mach/symbolic_constants_mach_test.cc', 'mach/symbolic_constants_mach_test.cc',
'mach/task_memory_test.cc',
'misc/arraysize_unsafe_test.cc', 'misc/arraysize_unsafe_test.cc',
'misc/capture_context_test.cc', 'misc/capture_context_test.cc',
'misc/capture_context_test_util.h', 'misc/capture_context_test_util.h',
...@@ -98,6 +97,7 @@ ...@@ -98,6 +97,7 @@
'posix/scoped_mmap_test.cc', 'posix/scoped_mmap_test.cc',
'posix/signals_test.cc', 'posix/signals_test.cc',
'posix/symbolic_constants_posix_test.cc', 'posix/symbolic_constants_posix_test.cc',
'process/process_memory_mac_test.cc',
'process/process_memory_range_test.cc', 'process/process_memory_range_test.cc',
'process/process_memory_test.cc', 'process/process_memory_test.cc',
'stdlib/aligned_allocator_test.cc', 'stdlib/aligned_allocator_test.cc',
......
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