mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 14:06:33 +00:00
mac: Update the process_types version of dyld_all_image_infos for 10.15
macOS 10.15 (“Catalina”) introduces a single new field to its dyld_all_image_infos structure, and uses structure version 16. macOS 10.13 and 10.14 were documented in <mach-o/dyld_images.h> as using structure version 16, but they actually use version 15. They should have used version 16, as they do use a structure expanded from macOS 10.12, which also uses version 15. Previously, process_types was true to the documentation, but now that this is known to be incorrect, it’s been revised to reflect reality. Because two variants of the version 15 structure exist, run-time OS version detection is used to disambiguate. Bug: crashpad:310 Test: crashpad_snapshot_test ProcessTypes.DyldImagesSelf (10.15 SDK) Change-Id: Ibc82b6a73809949f4bbf416ece7aa955b627c573 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/1852109 Commit-Queue: Mark Mentovai <mark@chromium.org> Reviewed-by: Robert Sesek <rsesek@chromium.org>
This commit is contained in:
parent
fe52a01df1
commit
2fb4e9e6a4
@ -59,4 +59,16 @@
|
||||
#define MAC_OS_X_VERSION_10_13 101300
|
||||
#endif
|
||||
|
||||
// 10.14 SDK
|
||||
|
||||
#ifndef MAC_OS_X_VERSION_10_14
|
||||
#define MAC_OS_X_VERSION_10_14 101400
|
||||
#endif
|
||||
|
||||
// 10.15 SDK
|
||||
|
||||
#ifndef MAC_OS_X_VERSION_10_15
|
||||
#define MAC_OS_X_VERSION_10_15 101500
|
||||
#endif
|
||||
|
||||
#endif // CRASHPAD_COMPAT_MAC_AVAILABILITYMACROS_H_
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
#include "base/logging.h"
|
||||
@ -26,6 +27,7 @@
|
||||
#include "base/stl_util.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "snapshot/mac/process_types/internal.h"
|
||||
#include "util/mac/mac_util.h"
|
||||
#include "util/process/process_memory_mac.h"
|
||||
|
||||
#if !DOXYGEN
|
||||
@ -140,8 +142,8 @@ size_t dyld_all_image_infos<Traits>::ExpectedSizeForVersion(
|
||||
offsetof(dyld_all_image_infos<Traits>, sharedCacheSlide), // 11
|
||||
offsetof(dyld_all_image_infos<Traits>, sharedCacheUUID), // 12
|
||||
offsetof(dyld_all_image_infos<Traits>, infoArrayChangeTimestamp), // 13
|
||||
offsetof(dyld_all_image_infos<Traits>, end_14_15), // 14
|
||||
offsetof(dyld_all_image_infos<Traits>, end_14_15), // 15
|
||||
offsetof(dyld_all_image_infos<Traits>, end_14), // 14
|
||||
std::numeric_limits<size_t>::max(), // 15, see below
|
||||
sizeof(dyld_all_image_infos<Traits>), // 16
|
||||
};
|
||||
|
||||
@ -151,7 +153,27 @@ size_t dyld_all_image_infos<Traits>::ExpectedSizeForVersion(
|
||||
|
||||
static_assert(std::is_unsigned<decltype(version)>::value,
|
||||
"version must be unsigned");
|
||||
return kSizeForVersion[version];
|
||||
|
||||
if (version == 15) {
|
||||
// Disambiguate between the two different layouts for version 15. The
|
||||
// original one introduced in macOS 10.12 had the same size as version 14.
|
||||
// The revised one in macOS 10.13 grew. It’s safe to assume that the
|
||||
// dyld_all_image_infos structure came from the same system that’s now
|
||||
// interpreting it, so use an OS version check.
|
||||
int mac_os_x_minor_version = MacOSXMinorVersion();
|
||||
if (mac_os_x_minor_version == 12) {
|
||||
return offsetof(dyld_all_image_infos<Traits>, end_14);
|
||||
}
|
||||
|
||||
DCHECK_GE(mac_os_x_minor_version, 13);
|
||||
DCHECK_LE(mac_os_x_minor_version, 14);
|
||||
return offsetof(dyld_all_image_infos<Traits>, platform);
|
||||
}
|
||||
|
||||
size_t size = kSizeForVersion[version];
|
||||
DCHECK_NE(size, std::numeric_limits<size_t>::max());
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -121,23 +121,29 @@ PROCESS_TYPE_STRUCT_BEGIN(dyld_all_image_infos)
|
||||
// the runtimes that use versions 14 and 15 were built with SDKs that did not
|
||||
// have this extra padding, it’s necessary to treat the element at index 4 on
|
||||
// 32-bit systems as outside of the version 14 and 15 structure. This is why
|
||||
// |reserved| is only declared a 4-element array, with a special end_14_15
|
||||
// member (not present in the native definition) available to indicate the
|
||||
// end of the native version 14 and 15 structure, preceding the padding in the
|
||||
// 32-bit structure that would natively be addressed at index 4 of |reserved|.
|
||||
// Treat reserved_4_32 as only available in version 16 of the structure.
|
||||
// |reserved| is only declared a 4-element array, with a special end_14 member
|
||||
// (not present in the native definition) available to indicate the end of the
|
||||
// native version 14 structure and the 10.12 version 15 structure, preceding
|
||||
// the padding in the 32-bit structure that would natively be addressed at
|
||||
// index 4 of |reserved|. Treat reserved_4_32 as only available in version 16
|
||||
// of the structure.
|
||||
PROCESS_TYPE_STRUCT_MEMBER(UIntPtr, reserved, [4])
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Reserved64_64Only, reserved_4_64)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Reserved64_64Only, reserved_5)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Reserved64_64Only, reserved_6)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Reserved64_64Only, reserved_7)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Reserved64_64Only, reserved_8)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Nothing, end_14_15)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Nothing, end_14)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(Reserved32_32Only, reserved_4_32)
|
||||
|
||||
// Version 16 (macOS 10.13)
|
||||
// Version 15 (macOS 10.13). <mach-o/dyld_images.h> incorrectly claims that
|
||||
// these were introduced at version 16. These fields are not present in macOS
|
||||
// 10.12, which also identifies its structure as version 15.
|
||||
PROCESS_TYPE_STRUCT_MEMBER(UIntPtr, compact_dyld_image_info_addr)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(ULong, compact_dyld_image_info_size) // size_t
|
||||
|
||||
// Version 16 (macOS 10.15)
|
||||
PROCESS_TYPE_STRUCT_MEMBER(uint32_t, platform) // dyld_platform_t
|
||||
PROCESS_TYPE_STRUCT_END(dyld_all_image_infos)
|
||||
|
||||
#endif // ! PROCESS_TYPE_STRUCT_IMPLEMENT_INTERNAL_READ_INTO &&
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <mach/mach.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
|
||||
#include "base/stl_util.h"
|
||||
@ -47,13 +48,11 @@ namespace {
|
||||
TEST(ProcessTypes, DyldImagesSelf) {
|
||||
// Get the in-process view of dyld_all_image_infos, and check it for sanity.
|
||||
const dyld_all_image_infos* self_image_infos = DyldGetAllImageInfos();
|
||||
int mac_os_x_minor_version = MacOSXMinorVersion();
|
||||
const int mac_os_x_minor_version = MacOSXMinorVersion();
|
||||
|
||||
// The 10.13 SDK defines dyld_all_image_infos version 16 and says that it’s
|
||||
// used on 10.13, but 10.13db1 17A264c uses version 15.
|
||||
//
|
||||
// TODO(mark): Recheck later in the beta period, up to the 10.13 release.
|
||||
if (mac_os_x_minor_version >= 12) {
|
||||
if (mac_os_x_minor_version >= 15) {
|
||||
EXPECT_GE(self_image_infos->version, 16u);
|
||||
} else if (mac_os_x_minor_version >= 12) {
|
||||
EXPECT_GE(self_image_infos->version, 15u);
|
||||
} else if (mac_os_x_minor_version >= 9) {
|
||||
EXPECT_GE(self_image_infos->version, 13u);
|
||||
@ -104,7 +103,7 @@ TEST(ProcessTypes, DyldImagesSelf) {
|
||||
ProcessReaderMac process_reader;
|
||||
ASSERT_TRUE(process_reader.Initialize(mach_task_self()));
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_13
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15
|
||||
constexpr uint32_t kDyldAllImageInfosVersionInSDK = 16;
|
||||
#elif MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12
|
||||
constexpr uint32_t kDyldAllImageInfosVersionInSDK = 15;
|
||||
@ -120,12 +119,33 @@ TEST(ProcessTypes, DyldImagesSelf) {
|
||||
|
||||
// Make sure that the size of the structure as declared in the SDK matches the
|
||||
// size expected for the version of the structure that the SDK describes.
|
||||
EXPECT_EQ(process_types::dyld_all_image_infos::ExpectedSizeForVersion(
|
||||
&process_reader, kDyldAllImageInfosVersionInSDK),
|
||||
sizeof(dyld_all_image_infos));
|
||||
//
|
||||
// There are two possible layouts for version 15, and the
|
||||
// ExpectedSizeForVersion() implementation infers the correct one based on the
|
||||
// run-time OS version, so if the SDK defines the version 15 structure, this
|
||||
// test can only be performed if the run-time OS natively uses the same format
|
||||
// structure as the SDK.
|
||||
bool test_expected_size_for_version_matches_sdk_sizeof;
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_12
|
||||
test_expected_size_for_version_matches_sdk_sizeof =
|
||||
mac_os_x_minor_version == 12;
|
||||
#elif MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_13 && \
|
||||
MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_14
|
||||
test_expected_size_for_version_matches_sdk_sizeof =
|
||||
mac_os_x_minor_version >= 13 && mac_os_x_minor_version <= 14;
|
||||
#else
|
||||
test_expected_size_for_version_matches_sdk_sizeof = true;
|
||||
#endif
|
||||
|
||||
if (test_expected_size_for_version_matches_sdk_sizeof) {
|
||||
EXPECT_EQ(process_types::dyld_all_image_infos::ExpectedSizeForVersion(
|
||||
&process_reader, kDyldAllImageInfosVersionInSDK),
|
||||
sizeof(dyld_all_image_infos));
|
||||
}
|
||||
|
||||
// Make sure that the computed sizes of various versions of this structure are
|
||||
// correct at different bitnessses.
|
||||
constexpr size_t kSpecialCase = std::numeric_limits<size_t>::max();
|
||||
constexpr struct {
|
||||
uint32_t version;
|
||||
size_t size_32;
|
||||
@ -144,13 +164,40 @@ TEST(ProcessTypes, DyldImagesSelf) {
|
||||
{12, 84, 160},
|
||||
{13, 104, 184},
|
||||
{14, 164, 304},
|
||||
{15, 164, 304},
|
||||
{16, 176, 320},
|
||||
{15, kSpecialCase, kSpecialCase},
|
||||
{16, 184, 328},
|
||||
};
|
||||
for (size_t index = 0; index < base::size(kVersionsAndSizes); ++index) {
|
||||
uint32_t version = kVersionsAndSizes[index].version;
|
||||
SCOPED_TRACE(base::StringPrintf("index %zu, version %u", index, version));
|
||||
|
||||
if (version == 15) {
|
||||
if (mac_os_x_minor_version == 12) {
|
||||
EXPECT_EQ(process_types::internal::dyld_all_image_infos<
|
||||
process_types::internal::Traits32>::
|
||||
ExpectedSizeForVersion(version),
|
||||
164u);
|
||||
EXPECT_EQ(process_types::internal::dyld_all_image_infos<
|
||||
process_types::internal::Traits64>::
|
||||
ExpectedSizeForVersion(version),
|
||||
304u);
|
||||
} else if (mac_os_x_minor_version >= 13 && mac_os_x_minor_version <= 14) {
|
||||
EXPECT_EQ(process_types::internal::dyld_all_image_infos<
|
||||
process_types::internal::Traits32>::
|
||||
ExpectedSizeForVersion(version),
|
||||
176u);
|
||||
EXPECT_EQ(process_types::internal::dyld_all_image_infos<
|
||||
process_types::internal::Traits64>::
|
||||
ExpectedSizeForVersion(version),
|
||||
320u);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
ASSERT_NE(kVersionsAndSizes[index].size_32, kSpecialCase);
|
||||
ASSERT_NE(kVersionsAndSizes[index].size_64, kSpecialCase);
|
||||
|
||||
EXPECT_EQ(
|
||||
process_types::internal::dyld_all_image_infos<
|
||||
process_types::internal::Traits32>::ExpectedSizeForVersion(version),
|
||||
@ -306,7 +353,7 @@ TEST(ProcessTypes, DyldImagesSelf) {
|
||||
#endif
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_13
|
||||
if (proctype_image_infos.version >= 16) {
|
||||
if (proctype_image_infos.version >= 15 && mac_os_x_minor_version >= 13) {
|
||||
EXPECT_EQ(proctype_image_infos.compact_dyld_image_info_addr,
|
||||
self_image_infos->compact_dyld_image_info_addr);
|
||||
EXPECT_EQ(proctype_image_infos.compact_dyld_image_info_size,
|
||||
@ -314,6 +361,12 @@ TEST(ProcessTypes, DyldImagesSelf) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_15
|
||||
if (proctype_image_infos.version >= 16) {
|
||||
EXPECT_EQ(proctype_image_infos.platform, self_image_infos->platform);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (proctype_image_infos.version >= 1) {
|
||||
std::vector<process_types::dyld_image_info> proctype_image_info_vector(
|
||||
proctype_image_infos.infoArrayCount);
|
||||
|
Loading…
x
Reference in New Issue
Block a user