File 5391-erts-Expose-parent-process-via-process_info-_-parent.patch of Package erlang

From d0e45b4c35c263482d2809b9a30618aaffd038d0 Mon Sep 17 00:00:00 2001
From: Maxim Fedorov <dane@whatsapp.com>
Date: Sat, 5 Mar 2022 11:07:43 -0800
Subject: [PATCH 1/2] [erts] Expose parent process via process_info(_, parent)

Parent process information is available in the VM process structure,
but is not exposed via process_info. Sometimes it is very convenient
to know who spawned processes that are not supporting any OTP
behaviours (where this information is stored in a process dictionary).

Parent process is returned only for locally started processes. Remotely
started process, or 'init' process that has no parent, return 'undefined'.
---
 erts/doc/src/erlang.xml              |  8 ++++++++
 erts/emulator/beam/atom.names        |  3 ++-
 erts/emulator/beam/erl_bif_info.c    | 10 +++++++++-
 erts/emulator/test/process_SUITE.erl |  9 +++++++++
 erts/preloaded/src/erlang.erl        |  2 ++
 5 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 1aad91c29d..f6ed80fd63 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -6668,6 +6668,14 @@ receive_replies(ReqId, N, Acc) ->
               <seeerl marker="#process_flag_message_queue_data">
               <c>process_flag(message_queue_data, MQD)</c></seeerl>.</p>
           </item>
+            <tag><c>{parent, <anno>Pid</anno>}</c></tag>
+            <item>
+                <p><c><anno>Pid</anno></c> is the identifier
+                of the parent process, the one that spawned current
+                process. When the process does not have a local parent
+                (e.g. <c>init</c>, or process is spawned remotely),
+                <c>undefined</c> is returned.</p>
+            </item>
           <tag><c>{priority, <anno>Level</anno>}</c></tag>
           <item>
             <p><c><anno>Level</anno></c> is the current priority level for
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index f396a6312a..70b0a6818f 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -530,6 +530,7 @@ atom owner
 atom packet
 atom packet_size
 atom parallelism
+atom parent
 atom Plus='+'
 atom PlusPlus='++'
 atom pause
@@ -746,4 +747,4 @@ atom yes
 atom yield
 atom nifs
 atom auto
-atom debug_hash_fixed_number_of_locks
\ No newline at end of file
+atom debug_hash_fixed_number_of_locks
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index 30130bbd09..b671b1315c 100644
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -769,6 +769,7 @@ collect_one_suspend_monitor(ErtsMonitor *mon, void *vsmicp, Sint reds)
 #define ERTS_PI_IX_GARBAGE_COLLECTION_INFO              33
 #define ERTS_PI_IX_MAGIC_REF                            34
 #define ERTS_PI_IX_FULLSWEEP_AFTER                      35
+#define ERTS_PI_IX_PARENT                               36
 
 #define ERTS_PI_FLAG_SINGELTON                          (1 << 0)
 #define ERTS_PI_FLAG_ALWAYS_WRAP                        (1 << 1)
@@ -824,7 +825,8 @@ static ErtsProcessInfoArgs pi_args[] = {
     {am_message_queue_data, 0, 0, ERTS_PROC_LOCK_MAIN},
     {am_garbage_collection_info, ERTS_PROCESS_GC_INFO_MAX_SIZE, 0, ERTS_PROC_LOCK_MAIN},
     {am_magic_ref, 0, ERTS_PI_FLAG_FORCE_SIG_SEND, ERTS_PROC_LOCK_MAIN},
-    {am_fullsweep_after, 0, 0, ERTS_PROC_LOCK_MAIN}
+    {am_fullsweep_after, 0, 0, ERTS_PROC_LOCK_MAIN},
+    {am_parent, 0, 0, ERTS_PROC_LOCK_MAIN}
 };
 
 #define ERTS_PI_ARGS ((int) (sizeof(pi_args)/sizeof(pi_args[0])))
@@ -943,6 +945,8 @@ pi_arg2ix(Eterm arg)
         return ERTS_PI_IX_MAGIC_REF;
     case am_fullsweep_after:
         return ERTS_PI_IX_FULLSWEEP_AFTER;
+    case am_parent:
+        return ERTS_PI_IX_PARENT;
     default:
         return -1;
     }
@@ -2025,6 +2029,10 @@ process_info_aux(Process *c_p,
 	}
 	break;
 
+    case ERTS_PI_IX_PARENT:
+        res = rp->parent == NIL ? am_undefined : rp->parent;
+        break;
+
     case ERTS_PI_IX_MAGIC_REF: {
 	Uint sz = 0;
 	(void) bld_magic_ref_bin_list(NULL, &sz, &MSO(rp));
diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl
index 354e4e054d..a02c53ea70 100644
--- a/erts/emulator/test/process_SUITE.erl
+++ b/erts/emulator/test/process_SUITE.erl
@@ -26,6 +26,7 @@
 %%	process_info/1,2
 %%	register/2 (partially)
 
+-include_lib("stdlib/include/assert.hrl").
 -include_lib("common_test/include/ct.hrl").
 
 -define(heap_binary_size, 64).
@@ -43,6 +44,7 @@
 	 process_info_lock_reschedule2/1,
 	 process_info_lock_reschedule3/1,
          process_info_garbage_collection/1,
+         process_info_parent/1,
          process_info_smoke_all/1,
          process_info_status_handled_signal/1,
          process_info_reductions/1,
@@ -105,6 +107,7 @@ all() ->
      process_info_lock_reschedule3,
      process_info_other_message_queue_len_signal_race,
      process_info_garbage_collection,
+     process_info_parent,
      process_info_smoke_all,
      process_info_status_handled_signal,
      process_info_reductions,
@@ -1064,6 +1067,12 @@ process_info_garbage_collection(_Config) ->
 gv(Key,List) ->
     proplists:get_value(Key,List).
 
+process_info_parent(Config) when is_list(Config) ->
+    Child = spawn_link(fun () -> receive stop -> ok end end),
+    ?assertEqual({parent, self()}, erlang:process_info(Child, parent)),
+    Child ! stop,
+    ?assertEqual({parent, undefined}, erlang:process_info(whereis(init), parent)).
+
 process_info_smoke_all_tester() ->
     register(process_info_smoke_all_tester, self()),
     put(ets_ref, ets:new(blupp, [])),
diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index b0430f4182..5f525aebf5 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -2478,6 +2478,7 @@ process_flag(_Flag, _Value) ->
       monitored_by |
       monitors |
       message_queue_data |
+      parent |
       priority |
       reductions |
       registered_name |
@@ -2522,6 +2523,7 @@ process_flag(_Flag, _Value) ->
        Monitors :: [{process | port, Pid :: pid() | port() |
                                      {RegName :: atom(), Node :: node()}}]} |
       {message_queue_data, MQD :: message_queue_data()} |
+      {parent, pid() | undefined} |
       {priority, Level :: priority_level()} |
       {reductions, Number :: non_neg_integer()} |
       {registered_name, [] | (Atom :: atom())} |
-- 
2.34.1

openSUSE Build Service is sponsored by