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