From bd5ccf95d11dec6c4bbf52e1996a364ec9c785bc Mon Sep 17 00:00:00 2001 From: Nourhan Hasan Date: Thu, 11 Jun 2026 11:30:22 -0700 Subject: [PATCH] [vm/service]: Add OS::SafeReadMemory for macOS using mach_vm_read_overwrite TEST=runtime/vm/service_test.cc Cq-Include-Trybots: dart/try:vm-asan-mac-release-arm64-try,vm-dyn-mac-debug-arm64-try,vm-mac-debug-arm64-try,vm-mac-debug-x64-try,vm-tsan-mac-release-arm64-try,vm-ubsan-mac-release-arm64-try Change-Id: I1be990f3debb7e0b7102f54e8c5bec25252756d4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/507040 Reviewed-by: Daco Harkes Commit-Queue: Daco Harkes Reviewed-by: Ben Konyi --- runtime/tests/vm/vm.status | 4 ---- runtime/vm/os_macos.cc | 46 +++++++++++++++++++++++++++++--------- runtime/vm/service.cc | 3 ++- runtime/vm/service_test.cc | 2 ++ 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status index 37bc155ab8b..cad5b4c37de 100644 --- a/runtime/tests/vm/vm.status +++ b/runtime/tests/vm/vm.status @@ -232,10 +232,6 @@ dart/data_uri_spawn_test: Skip # TODO(zra): package:unittest is not in the image dart/spawn_shutdown_test: Skip # OOM crash can bring down the OS. [ $system == macos ] -cc/Service_ReadNativeMemory_InvalidAddress: Skip -cc/Service_ReadNativeMemory_LargeRead: Skip -cc/Service_ReadNativeMemory_NullAddress: Skip -cc/Service_ReadNativeMemory_ValidAddress: Skip dart/transferable_throws_oom_test: SkipByDesign # Allocating too much memory to cause OOM doesn't work on mac [ $system == windows ] diff --git a/runtime/vm/os_macos.cc b/runtime/vm/os_macos.cc index c5c45871429..727717b62df 100644 --- a/runtime/vm/os_macos.cc +++ b/runtime/vm/os_macos.cc @@ -7,18 +7,21 @@ #include "vm/os.h" -#include // NOLINT -#include // NOLINT -#include // NOLINT -#include // NOLINT -#include // NOLINT -#include // NOLINT -#include // NOLINT -#include // NOLINT -#include // NOLINT -#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT #if DART_HOST_OS_IOS #include // NOLINT +#else +#include // NOLINT #endif #include "platform/utils.h" @@ -131,6 +134,29 @@ uintptr_t OS::CurrentRSS() { return info.resident_size; } +bool OS::SafeReadMemory(void* address, + uint8_t* buffer, + size_t size_in_bytes, + const char** error) { +#if DART_HOST_OS_IOS + vm_size_t bytes_read = 0; + kern_return_t kr = vm_read_overwrite( + mach_task_self(), reinterpret_cast(address), size_in_bytes, + reinterpret_cast(buffer), &bytes_read); +#else + mach_vm_size_t bytes_read = 0; + kern_return_t kr = mach_vm_read_overwrite( + mach_task_self(), reinterpret_cast(address), + size_in_bytes, reinterpret_cast(buffer), &bytes_read); +#endif + + if (kr != KERN_SUCCESS || bytes_read != size_in_bytes) { + *error = OS::SCreate(nullptr, "%s (kr=%d)", mach_error_string(kr), kr); + return false; + } + return true; +} + void OS::Sleep(int64_t millis) { int64_t micros = millis * kMicrosecondsPerMillisecond; SleepMicros(micros); diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc index bb4dc5ff0ef..7d1ecdc90fb 100644 --- a/runtime/vm/service.cc +++ b/runtime/vm/service.cc @@ -6268,7 +6268,8 @@ static void ReadNativeMemoryHelper(JSONStream* js, bool ok = OS::SafeReadMemory(reinterpret_cast(address), buffer.get(), size, &read_error); #elif defined(DART_HOST_OS_MACOS) || defined(DART_HOST_OS_IOS) - bool ok = false; // TODO(thenourhan): implement using mach_vm_read + bool ok = OS::SafeReadMemory(reinterpret_cast(address), buffer.get(), + size, &read_error); #elif defined(DART_HOST_OS_WINDOWS) bool ok = OS::SafeReadMemory(reinterpret_cast(address), buffer.get(), size, &read_error); diff --git a/runtime/vm/service_test.cc b/runtime/vm/service_test.cc index a454ae2bdf4..18a21b4b5c2 100644 --- a/runtime/vm/service_test.cc +++ b/runtime/vm/service_test.cc @@ -824,6 +824,8 @@ ISOLATE_UNIT_TEST_CASE(Service_ReadNativeMemory_InvalidAddress) { EXPECT_SUBSTRING("Input\\/output error", handler.msg()); #elif defined(DART_HOST_OS_WINDOWS) EXPECT_SUBSTRING("error 299", handler.msg()); +#elif defined(DART_HOST_OS_MACOS) + EXPECT_SUBSTRING("invalid address", handler.msg()); #endif }