[vm runtime] Dynamically disable dual mapping of code on some platforms.
Until a better solution is found, disable dual mapping of code on docker
containers that fail setting exec permissions on dual mappings.
Change-Id: Ic7477e1ef70ae0ea4d0187284702d5a3ee594edf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/96668
Commit-Queue: Régis Crelier <regis@google.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
Auto-Submit: Régis Crelier <regis@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
diff --git a/runtime/vm/virtual_memory_posix.cc b/runtime/vm/virtual_memory_posix.cc
index 8291ff0..bf22734 100644
--- a/runtime/vm/virtual_memory_posix.cc
+++ b/runtime/vm/virtual_memory_posix.cc
@@ -43,6 +43,23 @@
#if defined(DUAL_MAPPING_SUPPORTED)
shm_unlink(DART_SHM_NAME); // Could be left over from a previous crash.
+
+ // Detect dual mapping exec permission limitation on some platforms,
+ // such as on docker containers, and disable dual mapping in this case.
+ if (FLAG_dual_map_code) {
+ intptr_t size = page_size_;
+ intptr_t alignment = 256 * 1024; // e.g. heap page size.
+ VirtualMemory* vm = AllocateAligned(size, alignment, true, NULL);
+ void* region = reinterpret_cast<void*>(vm->region_.start());
+ void* alias = reinterpret_cast<void*>(vm->alias_.start());
+ if (region == alias ||
+ mprotect(region, size, PROT_READ) != 0 || // Remove PROT_WRITE.
+ mprotect(alias, size, PROT_READ | PROT_EXEC) != 0) { // Add PROT_EXEC.
+ LOG_INFO("disabling dual mapping of code\n");
+ FLAG_dual_map_code = false;
+ }
+ delete vm;
+ }
#endif // defined(DUAL_MAPPING_SUPPORTED)
}