[vm] Disable dual code mapping when perf flags are passed.

Otherwise these perf flags are broken by default.

Change-Id: I17cdb54b03da38fc6384116cecbdee60e7e5ed93
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/102161
Commit-Queue: Samir Jindel <sjindel@google.com>
Reviewed-by: RĂ©gis Crelier <regis@google.com>
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index bc254e4..2ca3bb6 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -37,12 +37,14 @@
 DEFINE_FLAG(bool,
             generate_perf_events_symbols,
             false,
-            "Generate events symbols for profiling with perf");
+            "Generate events symbols for profiling with perf (disables dual "
+            "code mapping)");
 
 DEFINE_FLAG(bool,
             generate_perf_jitdump,
             false,
-            "Generate jitdump file to use with perf-inject");
+            "Generate jitdump file to use with perf-inject (disables dual code "
+            "mapping)");
 
 DECLARE_FLAG(bool, write_protect_code);
 DECLARE_FLAG(bool, write_protect_vm_isolate);
diff --git a/runtime/vm/virtual_memory_posix.cc b/runtime/vm/virtual_memory_posix.cc
index fb1fff2..bf9833f 100644
--- a/runtime/vm/virtual_memory_posix.cc
+++ b/runtime/vm/virtual_memory_posix.cc
@@ -35,12 +35,29 @@
 DECLARE_FLAG(bool, dual_map_code);
 DECLARE_FLAG(bool, write_protect_code);
 
+#if defined(TARGET_OS_LINUX)
+DECLARE_FLAG(bool, generate_perf_events_symbols);
+DECLARE_FLAG(bool, generate_perf_jitdump);
+#endif
+
 uword VirtualMemory::page_size_ = 0;
 
 void VirtualMemory::Init() {
   page_size_ = getpagesize();
 
 #if defined(DUAL_MAPPING_SUPPORTED)
+// Perf is Linux-specific and the flags aren't defined in Product.
+#if defined(TARGET_OS_LINUX) && !defined(PRODUCT)
+  // Perf interacts strangely with memfds, leading it to sometimes collect
+  // garbled return addresses.
+  if (FLAG_generate_perf_events_symbols || FLAG_generate_perf_jitdump) {
+    LOG_INFO(
+        "Dual code mapping disabled to generate perf events or jitdump.\n");
+    FLAG_dual_map_code = false;
+    return;
+  }
+#endif
+
   // Detect dual mapping exec permission limitation on some platforms,
   // such as on docker containers, and disable dual mapping in this case.
   // Also detect for missing support of memfd_create syscall.