mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 22:16:13 +00:00
mac: System libraries are no longer found on disk on macOS 11
On macOS 11, system libraries are no longer present on disk as individual Mach-O files, but are shipped exclusively in the dyld shared cache. This affects tests that verify the list of modules loaded into a process. The new _dyld_shared_cache_contains_path function can be used to determine whether a path exists in the dyld shared cache. Bug: crashpad:347 Test: crashpad_snapshot_test ProcessReaderMac.{Self,Child}Modules Change-Id: I19402e45701caeb850bdafd701ccbba4ef9c60bc Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2384322 Commit-Queue: Mark Mentovai <mark@chromium.org> Reviewed-by: Robert Sesek <rsesek@chromium.org>
This commit is contained in:
parent
56937e1df5
commit
b3d84e0d05
@ -16,17 +16,20 @@
|
||||
|
||||
#include <Availability.h>
|
||||
#include <OpenCL/opencl.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <mach-o/dyld_images.h>
|
||||
#include <mach/mach.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
#include "base/check_op.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/mac/mach_logging.h"
|
||||
#include "base/posix/eintr_wrapper.h"
|
||||
#include "base/stl_util.h"
|
||||
@ -530,6 +533,75 @@ TEST(ProcessReaderMac, ChildSeveralThreads) {
|
||||
process_reader_threaded_child.Run();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T GetDyldFunction(const char* symbol) {
|
||||
static void* dl_handle = []() -> void* {
|
||||
Dl_info dl_info;
|
||||
if (!dladdr(reinterpret_cast<void*>(dlopen), &dl_info)) {
|
||||
LOG(ERROR) << "dladdr: failed";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* dl_handle =
|
||||
dlopen(dl_info.dli_fname, RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
|
||||
DCHECK(dl_handle) << "dlopen: " << dlerror();
|
||||
|
||||
return dl_handle;
|
||||
}();
|
||||
|
||||
if (!dl_handle) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return reinterpret_cast<T>(dlsym(dl_handle, symbol));
|
||||
}
|
||||
|
||||
void VerifyImageExistenceAndTimestamp(const char* path, time_t timestamp) {
|
||||
const char* stat_path;
|
||||
bool timestamp_may_be_0;
|
||||
|
||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED < __MAC_10_16
|
||||
static auto _dyld_shared_cache_contains_path =
|
||||
GetDyldFunction<bool (*)(const char*)>(
|
||||
"_dyld_shared_cache_contains_path");
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunguarded-availability"
|
||||
if (_dyld_shared_cache_contains_path &&
|
||||
_dyld_shared_cache_contains_path(path)) {
|
||||
#pragma clang diagnostic pop
|
||||
// The timestamp will either match the timestamp of the dyld_shared_cache
|
||||
// file in use, or be 0.
|
||||
static const char* dyld_shared_cache_file_path = []() -> const char* {
|
||||
auto dyld_shared_cache_file_path_f =
|
||||
GetDyldFunction<const char* (*)()>("dyld_shared_cache_file_path");
|
||||
|
||||
// dyld_shared_cache_file_path should always be present if
|
||||
// _dyld_shared_cache_contains_path is.
|
||||
DCHECK(dyld_shared_cache_file_path_f);
|
||||
|
||||
const char* dyld_shared_cache_file_path = dyld_shared_cache_file_path_f();
|
||||
DCHECK(dyld_shared_cache_file_path);
|
||||
|
||||
return dyld_shared_cache_file_path;
|
||||
}();
|
||||
|
||||
stat_path = dyld_shared_cache_file_path;
|
||||
timestamp_may_be_0 = true;
|
||||
} else {
|
||||
stat_path = path;
|
||||
timestamp_may_be_0 = false;
|
||||
}
|
||||
|
||||
struct stat stat_buf;
|
||||
int rv = stat(stat_path, &stat_buf);
|
||||
EXPECT_EQ(rv, 0) << ErrnoMessage("stat");
|
||||
if (rv == 0 && (!timestamp_may_be_0 || timestamp != 0)) {
|
||||
EXPECT_EQ(timestamp, stat_buf.st_mtime);
|
||||
}
|
||||
}
|
||||
|
||||
// cl_kernels images (OpenCL kernels) are weird. They’re not ld output and don’t
|
||||
// exist as files on disk. On OS X 10.10 and 10.11, their Mach-O structure isn’t
|
||||
// perfect. They show up loaded into many executables, so these quirks should be
|
||||
@ -695,12 +767,8 @@ TEST(ProcessReaderMac, SelfModules) {
|
||||
found_cl_kernels = true;
|
||||
} else {
|
||||
// Hope that the module didn’t change on disk.
|
||||
struct stat stat_buf;
|
||||
int rv = stat(dyld_image_name, &stat_buf);
|
||||
EXPECT_EQ(rv, 0) << ErrnoMessage("stat");
|
||||
if (rv == 0) {
|
||||
EXPECT_EQ(modules[index].timestamp, stat_buf.st_mtime);
|
||||
}
|
||||
VerifyImageExistenceAndTimestamp(dyld_image_name,
|
||||
modules[index].timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -785,12 +853,8 @@ class ProcessReaderModulesChild final : public MachMultiprocess {
|
||||
found_cl_kernels = true;
|
||||
} else {
|
||||
// Hope that the module didn’t change on disk.
|
||||
struct stat stat_buf;
|
||||
int rv = stat(expect_name.c_str(), &stat_buf);
|
||||
EXPECT_EQ(rv, 0) << ErrnoMessage("stat");
|
||||
if (rv == 0) {
|
||||
EXPECT_EQ(modules[index].timestamp, stat_buf.st_mtime);
|
||||
}
|
||||
VerifyImageExistenceAndTimestamp(expect_name.c_str(),
|
||||
modules[index].timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user