mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-26 06:31:50 +08:00
Add a mask to MinidumpCrashpadInfo to indicate valid pointer addresses.
ARM64 supports storing pointer authentication codes in the upper bits of a pointer. This mask can be used by LLDB to mimic ptrauth_strip and strip the pointer authentication codes. To recover an address from pointer with an authentication code, `AND` this mask with the pointer. If the platform does not support pointer authentication, or the range of valid addressees for a pointer was unaccessible, this field will be 0 and should be ignored. Change-Id: Ie5cef90802dd1e892d456195ab8874223eac6a1b Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2773358 Commit-Queue: Justin Cohen <justincohen@chromium.org> Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
parent
85b7d3dd6f
commit
c11d49db88
@ -672,6 +672,8 @@ void InProcessIntermediateDumpHandler::WriteSystemInfo(
|
||||
IntermediateDumpKey::kDaylightName,
|
||||
daylight_name.c_str(),
|
||||
daylight_name.length());
|
||||
uint64_t address_mask = system_data.AddressMask();
|
||||
WriteProperty(writer, IntermediateDumpKey::kAddressMask, &address_mask);
|
||||
|
||||
vm_size_t page_size;
|
||||
host_page_size(mach_host_self(), &page_size);
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "minidump/minidump_module_crashpad_info_writer.h"
|
||||
#include "minidump/minidump_simple_string_dictionary_writer.h"
|
||||
#include "snapshot/process_snapshot.h"
|
||||
#include "snapshot/system_snapshot.h"
|
||||
#include "util/file/file_writer.h"
|
||||
|
||||
namespace crashpad {
|
||||
@ -30,6 +31,7 @@ MinidumpCrashpadInfoWriter::MinidumpCrashpadInfoWriter()
|
||||
simple_annotations_(nullptr),
|
||||
module_list_(nullptr) {
|
||||
crashpad_info_.version = MinidumpCrashpadInfo::kVersion;
|
||||
crashpad_info_.reserved = 0;
|
||||
}
|
||||
|
||||
MinidumpCrashpadInfoWriter::~MinidumpCrashpadInfoWriter() {
|
||||
@ -56,6 +58,10 @@ void MinidumpCrashpadInfoWriter::InitializeFromSnapshot(
|
||||
SetSimpleAnnotations(std::move(simple_annotations));
|
||||
}
|
||||
|
||||
if (process_snapshot->System()) {
|
||||
SetAddressMask(process_snapshot->System()->AddressMask());
|
||||
}
|
||||
|
||||
auto modules = std::make_unique<MinidumpModuleCrashpadInfoListWriter>();
|
||||
modules->InitializeFromSnapshot(process_snapshot->Modules());
|
||||
|
||||
@ -90,6 +96,10 @@ void MinidumpCrashpadInfoWriter::SetModuleList(
|
||||
module_list_ = std::move(module_list);
|
||||
}
|
||||
|
||||
void MinidumpCrashpadInfoWriter::SetAddressMask(uint64_t mask) {
|
||||
crashpad_info_.address_mask = mask;
|
||||
}
|
||||
|
||||
bool MinidumpCrashpadInfoWriter::Freeze() {
|
||||
DCHECK_EQ(state(), kStateMutable);
|
||||
|
||||
|
@ -86,6 +86,9 @@ class MinidumpCrashpadInfoWriter final : public internal::MinidumpStreamWriter {
|
||||
void SetModuleList(
|
||||
std::unique_ptr<MinidumpModuleCrashpadInfoListWriter> module_list);
|
||||
|
||||
//! \brief Sets MinidumpCrashpadInfo::address_mask.
|
||||
void SetAddressMask(uint64_t mask);
|
||||
|
||||
//! \brief Determines whether the object is useful.
|
||||
//!
|
||||
//! A useful object is one that carries data that makes a meaningful
|
||||
|
@ -122,6 +122,59 @@ TEST(MinidumpCrashpadInfoWriter, ReportAndClientID) {
|
||||
EXPECT_FALSE(module_list);
|
||||
}
|
||||
|
||||
TEST(MinidumpCrashpadInfoWriter, AddressMask) {
|
||||
MinidumpFileWriter minidump_file_writer;
|
||||
auto crashpad_info_writer = std::make_unique<MinidumpCrashpadInfoWriter>();
|
||||
|
||||
constexpr uint64_t mask = 0xFFFFFF8000000000;
|
||||
crashpad_info_writer->SetAddressMask(mask);
|
||||
|
||||
ASSERT_TRUE(minidump_file_writer.AddStream(std::move(crashpad_info_writer)));
|
||||
|
||||
StringFile string_file;
|
||||
ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));
|
||||
|
||||
const MinidumpCrashpadInfo* crashpad_info = nullptr;
|
||||
const MinidumpSimpleStringDictionary* simple_annotations = nullptr;
|
||||
const MinidumpModuleCrashpadInfoList* module_list = nullptr;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(GetCrashpadInfoStream(
|
||||
string_file.string(), &crashpad_info, &simple_annotations, &module_list));
|
||||
|
||||
UUID empty_report_id;
|
||||
ASSERT_TRUE(empty_report_id.InitializeFromString(
|
||||
"00000000-0000-0000-0000-000000000000"));
|
||||
UUID empty_client_id;
|
||||
ASSERT_TRUE(empty_client_id.InitializeFromString(
|
||||
"00000000-0000-0000-0000-000000000000"));
|
||||
|
||||
EXPECT_EQ(crashpad_info->version, MinidumpCrashpadInfo::kVersion);
|
||||
EXPECT_EQ(crashpad_info->address_mask, mask);
|
||||
EXPECT_EQ(crashpad_info->report_id, empty_report_id);
|
||||
EXPECT_EQ(crashpad_info->client_id, empty_client_id);
|
||||
EXPECT_FALSE(simple_annotations);
|
||||
EXPECT_FALSE(module_list);
|
||||
}
|
||||
|
||||
TEST(MinidumpCrashpadInfoWriter, EmptyAddressMask) {
|
||||
MinidumpFileWriter minidump_file_writer;
|
||||
auto crashpad_info_writer = std::make_unique<MinidumpCrashpadInfoWriter>();
|
||||
|
||||
ASSERT_TRUE(minidump_file_writer.AddStream(std::move(crashpad_info_writer)));
|
||||
|
||||
StringFile string_file;
|
||||
ASSERT_TRUE(minidump_file_writer.WriteEverything(&string_file));
|
||||
|
||||
const MinidumpCrashpadInfo* crashpad_info = nullptr;
|
||||
const MinidumpSimpleStringDictionary* simple_annotations = nullptr;
|
||||
const MinidumpModuleCrashpadInfoList* module_list = nullptr;
|
||||
|
||||
ASSERT_NO_FATAL_FAILURE(GetCrashpadInfoStream(
|
||||
string_file.string(), &crashpad_info, &simple_annotations, &module_list));
|
||||
|
||||
EXPECT_EQ(crashpad_info->address_mask, 0UL);
|
||||
}
|
||||
|
||||
TEST(MinidumpCrashpadInfoWriter, SimpleAnnotations) {
|
||||
MinidumpFileWriter minidump_file_writer;
|
||||
auto crashpad_info_writer = std::make_unique<MinidumpCrashpadInfoWriter>();
|
||||
|
@ -444,8 +444,9 @@ struct ALIGNAS(4) PACKED MinidumpCrashpadInfo {
|
||||
report_id(),
|
||||
client_id(),
|
||||
simple_annotations(),
|
||||
module_list() {
|
||||
}
|
||||
module_list(),
|
||||
reserved(),
|
||||
address_mask() {}
|
||||
|
||||
//! \brief The structure’s currently-defined version number.
|
||||
//!
|
||||
@ -499,6 +500,28 @@ struct ALIGNAS(4) PACKED MinidumpCrashpadInfo {
|
||||
//!
|
||||
//! This field is present when #version is at least `1`.
|
||||
MINIDUMP_LOCATION_DESCRIPTOR module_list;
|
||||
|
||||
//! \brief This field is always `0`.
|
||||
uint32_t reserved;
|
||||
|
||||
//! \brief A mask indicating the range of valid addresses for a pointer.
|
||||
//!
|
||||
//! ARM64 supports MTE, TBI and PAC masking, generally in the upper bits of
|
||||
//! a pointer. This mask can be used by LLDB to mimic ptrauth_strip and strip
|
||||
//! the pointer authentication codes. To recover `pointer` in userland on
|
||||
//! Darwin, `pointer & (~mask)`. In the case of code running in high memory,
|
||||
//! where bit 55 is set (indicating that all of the high bits should be set
|
||||
//! to 1), `pointer | mask`. See ABIMacOSX_arm64::FixAddress for more details
|
||||
//! here:
|
||||
//! https://github.com/llvm/llvm-project/blob/001d18664f8bcf63af64f10688809f7681dfbf0b/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.cpp#L817-L830
|
||||
//!
|
||||
//! If the platform does not support pointer authentication, or the range of
|
||||
//! valid addressees for a pointer was inaccessible, this field will be 0 and
|
||||
//! should be ignored.
|
||||
//!
|
||||
//! This field is present when #version is at least `1`, if the size of the
|
||||
//! structure is large enough to accommodate it.
|
||||
uint64_t address_mask;
|
||||
};
|
||||
|
||||
#if defined(COMPILER_MSVC)
|
||||
|
@ -73,6 +73,8 @@ class SystemSnapshotFuchsia final : public SystemSnapshot {
|
||||
int* daylight_offset_seconds,
|
||||
std::string* standard_name,
|
||||
std::string* daylight_name) const override;
|
||||
uint64_t AddressMask() const override { return 0; }
|
||||
|
||||
private:
|
||||
std::string os_version_full_;
|
||||
const timeval* snapshot_time_; // weak
|
||||
|
@ -57,6 +57,7 @@ SystemSnapshotIOSIntermediateDump::SystemSnapshotIOSIntermediateDump()
|
||||
daylight_offset_seconds_(0),
|
||||
standard_name_(),
|
||||
daylight_name_(),
|
||||
address_mask_(0),
|
||||
initialized_() {}
|
||||
|
||||
SystemSnapshotIOSIntermediateDump::~SystemSnapshotIOSIntermediateDump() {}
|
||||
@ -97,6 +98,8 @@ void SystemSnapshotIOSIntermediateDump::Initialize(
|
||||
dst_status_ = SystemSnapshot::kDoesNotObserveDaylightSavingTime;
|
||||
}
|
||||
|
||||
GetDataValueFromMap(system_data, Key::kAddressMask, &address_mask_);
|
||||
|
||||
vm_size_t page_size;
|
||||
if (GetDataValueFromMap(system_data, Key::kPageSize, &page_size)) {
|
||||
const IOSIntermediateDumpMap* vm_stat =
|
||||
@ -241,5 +244,10 @@ void SystemSnapshotIOSIntermediateDump::TimeZone(
|
||||
daylight_name->assign(daylight_name_);
|
||||
}
|
||||
|
||||
uint64_t SystemSnapshotIOSIntermediateDump::AddressMask() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
return address_mask_;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace crashpad
|
||||
|
@ -73,6 +73,7 @@ class SystemSnapshotIOSIntermediateDump final : public SystemSnapshot {
|
||||
int* daylight_offset_seconds,
|
||||
std::string* standard_name,
|
||||
std::string* daylight_name) const override;
|
||||
uint64_t AddressMask() const override;
|
||||
|
||||
private:
|
||||
std::string os_version_build_;
|
||||
@ -91,6 +92,7 @@ class SystemSnapshotIOSIntermediateDump final : public SystemSnapshot {
|
||||
int daylight_offset_seconds_;
|
||||
std::string standard_name_;
|
||||
std::string daylight_name_;
|
||||
uint64_t address_mask_;
|
||||
InitializationStateDcheck initialized_;
|
||||
};
|
||||
|
||||
|
@ -89,6 +89,7 @@ class SystemSnapshotLinux final : public SystemSnapshot {
|
||||
int* daylight_offset_seconds,
|
||||
std::string* standard_name,
|
||||
std::string* daylight_name) const override;
|
||||
uint64_t AddressMask() const override { return 0; }
|
||||
|
||||
private:
|
||||
void ReadKernelVersion(const std::string& version_string);
|
||||
|
@ -390,5 +390,19 @@ void SystemSnapshotMac::TimeZone(DaylightSavingTimeStatus* dst_status,
|
||||
daylight_name);
|
||||
}
|
||||
|
||||
uint64_t SystemSnapshotMac::AddressMask() const {
|
||||
uint64_t mask = 0;
|
||||
#if defined(ARCH_CPU_ARM64)
|
||||
// `machdep.virtual_address_size` is the number of addressable bits in
|
||||
// userspace virtual addresses
|
||||
uint8_t addressable_bits =
|
||||
CastIntSysctlByName<uint8_t>("machdep.virtual_address_size", 0);
|
||||
if (addressable_bits) {
|
||||
mask = ~((1UL << addressable_bits) - 1);
|
||||
}
|
||||
#endif
|
||||
return mask;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace crashpad
|
||||
|
@ -83,6 +83,7 @@ class SystemSnapshotMac final : public SystemSnapshot {
|
||||
int* daylight_offset_seconds,
|
||||
std::string* standard_name,
|
||||
std::string* daylight_name) const override;
|
||||
uint64_t AddressMask() const override;
|
||||
|
||||
private:
|
||||
std::string os_version_full_;
|
||||
|
@ -266,7 +266,10 @@ bool ProcessSnapshotMinidump::InitializeCrashpadInfo() {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (stream_it->second->DataSize < sizeof(crashpad_info_)) {
|
||||
constexpr size_t crashpad_info_min_size =
|
||||
offsetof(decltype(crashpad_info_), reserved);
|
||||
size_t remaining_data_size = stream_it->second->DataSize;
|
||||
if (remaining_data_size < crashpad_info_min_size) {
|
||||
LOG(ERROR) << "crashpad_info size mismatch";
|
||||
return false;
|
||||
}
|
||||
@ -275,9 +278,34 @@ bool ProcessSnapshotMinidump::InitializeCrashpadInfo() {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file_reader_->ReadExactly(&crashpad_info_, sizeof(crashpad_info_))) {
|
||||
if (!file_reader_->ReadExactly(&crashpad_info_, crashpad_info_min_size)) {
|
||||
return false;
|
||||
}
|
||||
remaining_data_size -= crashpad_info_min_size;
|
||||
|
||||
// Read `reserved` if available.
|
||||
size_t crashpad_reserved_size = sizeof(crashpad_info_.reserved);
|
||||
if (remaining_data_size >= crashpad_reserved_size) {
|
||||
if (!file_reader_->ReadExactly(&crashpad_info_.reserved,
|
||||
crashpad_reserved_size)) {
|
||||
return false;
|
||||
}
|
||||
remaining_data_size -= crashpad_reserved_size;
|
||||
} else {
|
||||
crashpad_info_.reserved = 0;
|
||||
}
|
||||
|
||||
// Read `address_mask` if available.
|
||||
size_t crashpad_address_mask_size = sizeof(crashpad_info_.address_mask);
|
||||
if (remaining_data_size >= crashpad_address_mask_size) {
|
||||
if (!file_reader_->ReadExactly(&crashpad_info_.address_mask,
|
||||
crashpad_address_mask_size)) {
|
||||
return false;
|
||||
}
|
||||
remaining_data_size -= crashpad_address_mask_size;
|
||||
} else {
|
||||
crashpad_info_.address_mask = 0;
|
||||
}
|
||||
|
||||
if (crashpad_info_.version != MinidumpCrashpadInfo::kVersion) {
|
||||
LOG(ERROR) << "crashpad_info version mismatch";
|
||||
|
@ -270,6 +270,47 @@ TEST(ProcessSnapshotMinidump, ClientID) {
|
||||
EXPECT_TRUE(process_snapshot.AnnotationsSimpleMap().empty());
|
||||
}
|
||||
|
||||
TEST(ProcessSnapshotMinidump, ReadOldCrashpadInfo) {
|
||||
StringFile string_file;
|
||||
|
||||
MINIDUMP_HEADER header = {};
|
||||
EXPECT_TRUE(string_file.Write(&header, sizeof(header)));
|
||||
|
||||
UUID client_id;
|
||||
ASSERT_TRUE(
|
||||
client_id.InitializeFromString("0001f4a9-d00d-5155-0a55-c0ffeec0ffee"));
|
||||
|
||||
MinidumpCrashpadInfo crashpad_info = {};
|
||||
crashpad_info.version = MinidumpCrashpadInfo::kVersion;
|
||||
crashpad_info.client_id = client_id;
|
||||
|
||||
MINIDUMP_DIRECTORY crashpad_info_directory = {};
|
||||
crashpad_info_directory.StreamType = kMinidumpStreamTypeCrashpadInfo;
|
||||
crashpad_info_directory.Location.Rva =
|
||||
static_cast<RVA>(string_file.SeekGet());
|
||||
EXPECT_TRUE(string_file.Write(&crashpad_info, sizeof(crashpad_info) - 8));
|
||||
crashpad_info_directory.Location.DataSize = sizeof(crashpad_info) - 8;
|
||||
|
||||
header.StreamDirectoryRva = static_cast<RVA>(string_file.SeekGet());
|
||||
EXPECT_TRUE(string_file.Write(&crashpad_info_directory,
|
||||
sizeof(crashpad_info_directory)));
|
||||
|
||||
header.Signature = MINIDUMP_SIGNATURE;
|
||||
header.Version = MINIDUMP_VERSION;
|
||||
header.NumberOfStreams = 1;
|
||||
EXPECT_TRUE(string_file.SeekSet(0));
|
||||
EXPECT_TRUE(string_file.Write(&header, sizeof(header)));
|
||||
|
||||
ProcessSnapshotMinidump process_snapshot;
|
||||
EXPECT_TRUE(process_snapshot.Initialize(&string_file));
|
||||
|
||||
UUID actual_client_id;
|
||||
process_snapshot.ClientID(&actual_client_id);
|
||||
EXPECT_EQ(actual_client_id, client_id);
|
||||
|
||||
EXPECT_TRUE(process_snapshot.AnnotationsSimpleMap().empty());
|
||||
}
|
||||
|
||||
TEST(ProcessSnapshotMinidump, AnnotationsSimpleMap) {
|
||||
StringFile string_file;
|
||||
|
||||
|
@ -195,5 +195,11 @@ void SystemSnapshotMinidump::TimeZone(DaylightSavingTimeStatus* dst_status,
|
||||
NOTREACHED(); // https://crashpad.chromium.org/bug/10
|
||||
}
|
||||
|
||||
uint64_t SystemSnapshotMinidump::AddressMask() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
NOTREACHED(); // https://crashpad.chromium.org/bug/10
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace crashpad
|
||||
|
@ -74,6 +74,7 @@ class SystemSnapshotMinidump : public SystemSnapshot {
|
||||
int* daylight_offset_seconds,
|
||||
std::string* standard_name,
|
||||
std::string* daylight_name) const override;
|
||||
uint64_t AddressMask() const override;
|
||||
|
||||
private:
|
||||
MINIDUMP_SYSTEM_INFO minidump_system_info_;
|
||||
|
@ -275,6 +275,20 @@ class SystemSnapshot {
|
||||
int* daylight_offset_seconds,
|
||||
std::string* standard_name,
|
||||
std::string* daylight_name) const = 0;
|
||||
|
||||
//! \brief Returns a mask indicating the range of valid addresses for a
|
||||
//! pointer.
|
||||
//!
|
||||
//! ARM64 supports storing pointer authentication codes in the upper bits of
|
||||
//! a pointer. This mask is generated based on the number of bits in a pointer
|
||||
//! reserved for the authentication codes. To recover an address from pointer
|
||||
//! with an authentication code, `AND` this mask with the pointer. If the pac
|
||||
//! sign extension bit is set, instead `~` and `OR` this mask with the
|
||||
//! pointer.
|
||||
//!
|
||||
//! If the platform does not support pointer authentication, or the range of
|
||||
//! valid addressees for a pointer was inaccessible, this field will be 0.
|
||||
virtual uint64_t AddressMask() const = 0;
|
||||
};
|
||||
|
||||
} // namespace crashpad
|
||||
|
@ -36,14 +36,14 @@ TestSystemSnapshot::TestSystemSnapshot()
|
||||
os_version_bugfix_(0),
|
||||
os_version_build_(),
|
||||
os_version_full_(),
|
||||
address_mask_(0),
|
||||
nx_enabled_(false),
|
||||
machine_description_(),
|
||||
time_zone_dst_status_(kDoesNotObserveDaylightSavingTime),
|
||||
time_zone_standard_offset_seconds_(0),
|
||||
time_zone_daylight_offset_seconds_(0),
|
||||
time_zone_standard_name_(),
|
||||
time_zone_daylight_name_() {
|
||||
}
|
||||
time_zone_daylight_name_() {}
|
||||
|
||||
TestSystemSnapshot::~TestSystemSnapshot() {
|
||||
}
|
||||
@ -130,5 +130,9 @@ void TestSystemSnapshot::TimeZone(DaylightSavingTimeStatus* dst_status,
|
||||
*daylight_name = time_zone_daylight_name_;
|
||||
}
|
||||
|
||||
uint64_t TestSystemSnapshot::AddressMask() const {
|
||||
return address_mask_;
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
||||
|
@ -90,6 +90,8 @@ class TestSystemSnapshot final : public SystemSnapshot {
|
||||
time_zone_daylight_name_ = daylight_name;
|
||||
}
|
||||
|
||||
void SetAddressMask(uint64_t mask) { address_mask_ = mask; }
|
||||
|
||||
// SystemSnapshot:
|
||||
|
||||
CPUArchitecture GetCPUArchitecture() const override;
|
||||
@ -114,6 +116,7 @@ class TestSystemSnapshot final : public SystemSnapshot {
|
||||
int* daylight_offset_seconds,
|
||||
std::string* standard_name,
|
||||
std::string* daylight_name) const override;
|
||||
uint64_t AddressMask() const override;
|
||||
|
||||
private:
|
||||
CPUArchitecture cpu_architecture_;
|
||||
@ -134,6 +137,7 @@ class TestSystemSnapshot final : public SystemSnapshot {
|
||||
int os_version_bugfix_;
|
||||
std::string os_version_build_;
|
||||
std::string os_version_full_;
|
||||
uint64_t address_mask_;
|
||||
bool nx_enabled_;
|
||||
std::string machine_description_;
|
||||
DaylightSavingTimeStatus time_zone_dst_status_;
|
||||
|
@ -79,6 +79,7 @@ class SystemSnapshotWin final : public SystemSnapshot {
|
||||
int* daylight_offset_seconds,
|
||||
std::string* standard_name,
|
||||
std::string* daylight_name) const override;
|
||||
uint64_t AddressMask() const override { return 0; }
|
||||
|
||||
private:
|
||||
std::string os_version_full_;
|
||||
|
@ -85,6 +85,7 @@ namespace internal {
|
||||
TD(kFree, 5017) \
|
||||
TD(kInactive, 5018) \
|
||||
TD(kWired, 5019) \
|
||||
TD(kAddressMask, 5020) \
|
||||
TD(kThreads, 6000) \
|
||||
TD(kDebugState, 6001) \
|
||||
TD(kFloatState, 6002) \
|
||||
@ -103,7 +104,6 @@ namespace internal {
|
||||
TD(kMaxValue, 65535) \
|
||||
// clang-format on
|
||||
|
||||
|
||||
//! \brief They key for items in the intermediate dump file.
|
||||
//!
|
||||
//! These values are persisted to the intermediate crash dump file. Entries
|
||||
|
@ -43,6 +43,7 @@ class IOSSystemDataCollector {
|
||||
const std::string& StandardName() const { return standard_name_; }
|
||||
const std::string& DaylightName() const { return daylight_name_; }
|
||||
bool IsApplicationActive() const { return active_; }
|
||||
uint64_t AddressMask() const { return address_mask_; }
|
||||
|
||||
// Currently unused by minidump.
|
||||
int Orientation() const { return orientation_; }
|
||||
@ -80,6 +81,7 @@ class IOSSystemDataCollector {
|
||||
std::string standard_name_;
|
||||
std::string daylight_name_;
|
||||
ActiveApplicationCallback active_application_callback_;
|
||||
uint64_t address_mask_;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -102,6 +102,16 @@ IOSSystemDataCollector::IOSSystemDataCollector()
|
||||
#if defined(ARCH_CPU_X86_64)
|
||||
cpu_vendor_ = ReadStringSysctlByName("machdep.cpu.vendor");
|
||||
#endif
|
||||
uint32_t addressable_bits = 0;
|
||||
size_t len = sizeof(uint32_t);
|
||||
// `machdep.virtual_address_size` is the number of addressable bits in
|
||||
// userspace virtual addresses
|
||||
if (sysctlbyname(
|
||||
"machdep.virtual_address_size", &addressable_bits, &len, NULL, 0) !=
|
||||
0) {
|
||||
addressable_bits = 0;
|
||||
}
|
||||
address_mask_ = ~((1UL << addressable_bits) - 1);
|
||||
|
||||
#if TARGET_OS_SIMULATOR
|
||||
// TODO(justincohen): Consider adding board and model information to
|
||||
|
Loading…
x
Reference in New Issue
Block a user