File 1531-Add-support-to-erl-for-JPperfdirectory-directory.patch of Package erlang

From b759c1b059eceefcedb4bdc13e2c442425da63a0 Mon Sep 17 00:00:00 2001
From: Freddie Lamble <flamble1@bloomberg.net>
Date: Mon, 24 Mar 2025 10:35:32 +0000
Subject: [PATCH] Add support to `erl` for `+JPperfdirectory <directory>`

This adds support for a `+JPperfdirectory <directory>` cli arg which
allows changing the location used for the `jit<pid>.dump` and `perf<pid>.map`
files which prior to this always went into `/tmp`.

The motivation is so that a different mount from `/tmp` can be used.

Example usage:
```console
[ ~/otp/bin @issue/9500 ] $ mkdir /testdir
[ ~/otp/bin @issue/9500 ] $ ./erl -noinput -eval 'io:format("I am ~s~n", [os:getpid()]).' -s init stop +JPperf true +JPperfdirectory /testdir
I am 149279
[ ~/otp/bin @issue/9500 ] $ ls /testdir/
jit-149279.dump  perf-149279.map
```

Without it, they still go to `/tmp/`:
```console
[ ~/otp/bin @issue/9500 ] $ ./erl -noinput -eval 'io:format("I am ~s~n", [os:getpid()]).' -s init stop +JPperf true
I am 209905
[ ~/otp/bin @issue/9500 ] $ ls /tmp/*209905*
/tmp/jit-209905.dump  /tmp/perf-209905.map
```

Closes #9500.
---
 erts/doc/references/erl_cmd.md               |  4 +++
 erts/emulator/beam/erl_init.c                | 13 +++++++++-
 erts/emulator/beam/jit/beam_asm.h            |  1 +
 erts/emulator/beam/jit/beam_jit_main.cpp     |  1 +
 erts/emulator/beam/jit/beam_jit_metadata.cpp | 12 +++++++--
 erts/emulator/test/jit_SUITE.erl             | 27 ++++++++++++++++++--
 6 files changed, 53 insertions(+), 5 deletions(-)

diff --git a/erts/doc/references/erl_cmd.md b/erts/doc/references/erl_cmd.md
index 2b2214cce2..c37319f46f 100644
--- a/erts/doc/references/erl_cmd.md
+++ b/erts/doc/references/erl_cmd.md
@@ -772,6 +772,10 @@ behavior of earlier flags.
   [perf support](BeamAsm.md#linux-perf-support) section in the BeamAsm internal
   documentation.
 
+- **`+JPperfdirectory <directory>`{: #+JPperfdirectory }** - Set the directory
+  used to store `perf` dump and map files when running with the JIT on Linux.
+  Defaults to `/tmp`.
+
 - **`+JMsingle true|false`{: #+JMsingle }** - Enables or disables the use of
   single-mapped RWX memory for JIT code.
 
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index 5c20f55fd8..1b7f91b100 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -594,6 +594,7 @@ __decl_noreturn void __noreturn  erts_usage(void)
     erts_fprintf(stderr, "-JDdump bool   enable or disable dumping of generated assembly code for each module loaded\n");
     erts_fprintf(stderr, "-JPcover true|false|line|line_counters|function|function_counters  enable or disable instrumentation for coverage\n");
     erts_fprintf(stderr, "-JPperf true|false|dump|map|fp|no_fp   enable or disable support for perf on Linux\n");
+    erts_fprintf(stderr, "-JPperfdirectory <directory>    set the directory perf files are stored. Default: /tmp\n");
     erts_fprintf(stderr, "-JMsingle bool enable the use of single-mapped RWX memory for JIT:ed code\n");
     erts_fprintf(stderr, "\n");
 #endif
@@ -1686,7 +1687,17 @@ erl_start(int argc, char **argv)
             case 'P':
                 sub_param++;
 
-                if (has_prefix("perf", sub_param)) {
+                if (has_prefix("perfdirectory", sub_param)){
+                    arg = get_arg(sub_param+13, argv[i + 1], &i);
+#ifdef HAVE_LINUX_PERF_SUPPORT
+                    sys_strncpy(etrs_jit_perf_directory, arg, sizeof(etrs_jit_perf_directory));
+                    etrs_jit_perf_directory[sizeof(etrs_jit_perf_directory) -1 ] = '\0';
+#else
+                    erts_fprintf(stderr, "+JPperfdirectory is not supported on this platform\n");
+                    erts_usage();
+#endif
+                }
+                else if (has_prefix("perf", sub_param)) {
                     arg = get_arg(sub_param+4, argv[i + 1], &i);
 
 #ifdef HAVE_LINUX_PERF_SUPPORT
diff --git a/erts/emulator/beam/jit/beam_asm.h b/erts/emulator/beam/jit/beam_asm.h
index 8966abce9a..0fdeba7b4f 100644
--- a/erts/emulator/beam/jit/beam_asm.h
+++ b/erts/emulator/beam/jit/beam_asm.h
@@ -47,6 +47,7 @@ enum beamasm_perf_flags {
     BEAMASM_PERF_DISABLED = 0,
 };
 extern enum beamasm_perf_flags erts_jit_perf_support;
+extern char etrs_jit_perf_directory[MAXPATHLEN];
 #    endif
 extern int erts_jit_single_map;
 
diff --git a/erts/emulator/beam/jit/beam_jit_main.cpp b/erts/emulator/beam/jit/beam_jit_main.cpp
index 69a4f7ebb5..f178d60ac3 100644
--- a/erts/emulator/beam/jit/beam_jit_main.cpp
+++ b/erts/emulator/beam/jit/beam_jit_main.cpp
@@ -44,6 +44,7 @@ ErtsFrameLayout ERTS_WRITE_UNLIKELY(erts_frame_layout);
 /* Global configuration variables (under the `+J` prefix) */
 #ifdef HAVE_LINUX_PERF_SUPPORT
 enum beamasm_perf_flags erts_jit_perf_support;
+char etrs_jit_perf_directory[MAXPATHLEN] = "/tmp";
 #endif
 /* Force use of single-mapped RWX memory for JIT code */
 int erts_jit_single_map = 0;
diff --git a/erts/emulator/beam/jit/beam_jit_metadata.cpp b/erts/emulator/beam/jit/beam_jit_metadata.cpp
index 2f08f0487e..5953058168 100644
--- a/erts/emulator/beam/jit/beam_jit_metadata.cpp
+++ b/erts/emulator/beam/jit/beam_jit_metadata.cpp
@@ -332,7 +332,11 @@ public:
 
         /* LLVM places this file in ~/.debug/jit/ maybe we should do that to? */
 
-        erts_snprintf(name, sizeof(name), "/tmp/jit-%d.dump", getpid());
+        erts_snprintf(name,
+                      sizeof(name),
+                      "%s/jit-%d.dump",
+                      etrs_jit_perf_directory,
+                      getpid());
 
         file = fopen(name, "w+");
 
@@ -473,7 +477,11 @@ public:
 
         if (erts_sys_explicit_host_getenv("ERL_SYM_MAP_FILE", name, &namesz) !=
             1) {
-            snprintf(name, sizeof(name), "/tmp/perf-%i.map", getpid());
+            erts_snprintf(name,
+                          sizeof(name),
+                          "%s/perf-%i.map",
+                          etrs_jit_perf_directory,
+                          getpid());
         }
         file = fopen(name, "w");
         if (!file) {
diff --git a/erts/emulator/test/jit_SUITE.erl b/erts/emulator/test/jit_SUITE.erl
index c6a16968ad..23e79953fd 100644
--- a/erts/emulator/test/jit_SUITE.erl
+++ b/erts/emulator/test/jit_SUITE.erl
@@ -26,7 +26,7 @@
          init_per_suite/1, end_per_suite/1,
          init_per_group/2, end_per_group/2,
          init_per_testcase/2, end_per_testcase/2]).
--export([annotate/1, jmsingle/1, named_labels/1, symbols/1]).
+-export([annotate/1, jmsingle/1, named_labels/1, symbols/1, perfdirectory_set/1, perfdirectory_not_set/1]).
 
 suite() ->
     [{timetrap, {minutes, 4}}].
@@ -35,7 +35,7 @@ groups() ->
     [{perf, [symbols, annotate]}].
 
 all() ->
-    [{group, perf}, jmsingle, named_labels].
+    [{group, perf}, jmsingle, named_labels, perfdirectory_set, perfdirectory_not_set].
 
 init_per_suite(Config) ->
     case erlang:system_info(emu_flavor) of
@@ -286,3 +286,26 @@ named_labels(_Config) ->
         _ ->
             ct:fail("No labels found in assembly dump")
     end.
+
+perfdirectory_set(_Config) ->
+    %% Confirm that when +JPperfdirectory is set, the jit/perf files
+    %% end up in the appropriate directory
+    TempDir = string:strip(os:cmd("mktemp -d"), right, $\n),
+    run_perfdirectory_test("+JPperfdirectory " ++ TempDir, TempDir).
+
+perfdirectory_not_set(_Config) ->
+    %% Confirm that when +JPperfdirectory is not set, the jit/perf files
+    %% end up in /tmp
+    run_perfdirectory_test("", "/tmp").
+
+run_perfdirectory_test(AdditionalFlags, ExpectedDirectory) ->
+    Cmd = "erl -noinput -eval 'io:format(\"~s~n\", [os:getpid()]).' -s init stop +JPperf true " ++ AdditionalFlags,
+    ThePid = string:strip(os:cmd(Cmd), right, $\n),
+    JitDumpFile = ExpectedDirectory ++ "/jit-" ++ ThePid ++ ".dump",
+    PerfMapFile = ExpectedDirectory ++ "/perf-" ++ ThePid ++ ".map",
+    case lists:all(fun filelib:is_file/1, [JitDumpFile, PerfMapFile]) of
+        true ->
+            ok;
+        _ ->
+            ct:fail("Expected ~s and ~s to exist", [JitDumpFile, PerfMapFile])
+    end.
-- 
2.43.0

openSUSE Build Service is sponsored by