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 }