aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2016-02-29 15:09:26 +0100
committerLukas Larsson <[email protected]>2016-04-15 15:07:38 +0200
commit3738103d0b1195e570a7525c4370cd490a5368aa (patch)
tree24fd26a93799a643c7d672ef0d794696057c0187
parentb8ca148ba2c98a2bec923dbac6ed52a80aa167ca (diff)
downloadotp-3738103d0b1195e570a7525c4370cd490a5368aa.tar.gz
otp-3738103d0b1195e570a7525c4370cd490a5368aa.tar.bz2
otp-3738103d0b1195e570a7525c4370cd490a5368aa.zip
erts: Add 'spawned' trace event to 'procs' trace flag
OTP-13497 This trace event is triggered when a process is created from the process that is created.
-rw-r--r--erts/doc/src/erlang.xml11
-rw-r--r--erts/emulator/beam/atom.names1
-rw-r--r--erts/emulator/beam/erl_process.c13
-rw-r--r--erts/emulator/beam/erl_trace.c6
-rw-r--r--erts/emulator/beam/erl_trace.h2
-rw-r--r--erts/emulator/test/trace_SUITE.erl5
-rw-r--r--erts/preloaded/src/erl_tracer.erl2
7 files changed, 33 insertions, 7 deletions
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index abc0d56983..d6fe585c8d 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -8464,6 +8464,7 @@ timestamp() ->
<item>
<p>Traces process-related events.</p>
<p>Message tags: <c><seealso marker="#trace_3_trace_messages_spawn">spawn</seealso></c>,
+ <c><seealso marker="#trace_3_trace_messages_spawned">spawned</seealso></c>,
<c><seealso marker="#trace_3_trace_messages_exit">exit</seealso></c>,
<c><seealso marker="#trace_3_trace_messages_register">register</seealso></c>,
<c><seealso marker="#trace_3_trace_messages_unregister">unregister</seealso></c>,
@@ -8705,6 +8706,16 @@ timestamp() ->
but can be any term if the spawn is erroneous.</p>
</item>
<tag>
+ <marker id="trace_3_trace_messages_spawned"></marker>
+ <c>{trace, Pid, spawned, Pid2, {M, F, Args}}</c>
+ </tag>
+ <item>
+ <p>When <c>Pid</c> is spawned by process <c>Pid2</c> with
+ the specified function call as entry point.</p>
+ <p><c>Args</c> is supposed to be the argument list,
+ but can be any term if the spawn is erroneous.</p>
+ </item>
+ <tag>
<marker id="trace_3_trace_messages_exit"></marker>
<c>{trace, Pid, exit, Reason}</c>
</tag>
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index bd1005867c..8c51f788c0 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -571,6 +571,7 @@ atom size
atom sl_alloc
atom spawn_executable
atom spawn_driver
+atom spawned
atom ssl_tls
atom stack_size
atom start
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 1398bc9c61..a520005c35 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -11176,12 +11176,23 @@ erl_create_process(Process* parent, /* Parent of process (default group leader).
locks &= ~(ERTS_PROC_LOCK_STATUS|ERTS_PROC_LOCK_TRACE);
erts_smp_proc_unlock(p, ERTS_PROC_LOCK_STATUS|ERTS_PROC_LOCK_TRACE);
erts_smp_proc_unlock(parent, ERTS_PROC_LOCK_STATUS|ERTS_PROC_LOCK_TRACE);
- trace_proc_spawn(parent, p->common.id, mod, func, args);
+ trace_proc_spawn(parent, am_spawn, p->common.id, mod, func, args);
if (so->flags & SPO_LINK)
trace_proc(parent, locks, parent, am_link, p->common.id);
}
}
+ if (IS_TRACED_FL(p, F_TRACE_PROCS)) {
+ if (locks & (ERTS_PROC_LOCK_STATUS|ERTS_PROC_LOCK_TRACE)) {
+ locks &= ~(ERTS_PROC_LOCK_STATUS|ERTS_PROC_LOCK_TRACE);
+ erts_smp_proc_unlock(p, locks & (ERTS_PROC_LOCK_STATUS|ERTS_PROC_LOCK_TRACE));
+ erts_smp_proc_unlock(parent, locks & (ERTS_PROC_LOCK_STATUS|ERTS_PROC_LOCK_TRACE));
+ }
+ trace_proc_spawn(p, am_spawned, parent->common.id, mod, func, args);
+ if (so->flags & SPO_LINK)
+ trace_proc(p, locks, p, am_getting_linked, parent->common.id);
+ }
+
/*
* Check if this process should be initially linked to its parent.
*/
diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c
index 5ba58e9350..3027e34968 100644
--- a/erts/emulator/beam/erl_trace.c
+++ b/erts/emulator/beam/erl_trace.c
@@ -1249,20 +1249,20 @@ trace_proc(Process *c_p, ErtsProcLocks c_p_locks,
* and 'args' may be a deep term.
*/
void
-trace_proc_spawn(Process *p, Eterm pid,
+trace_proc_spawn(Process *p, Eterm what, Eterm pid,
Eterm mod, Eterm func, Eterm args)
{
ErtsTracerNif *tnif = NULL;
if (is_tracer_proc_enabled(p, ERTS_PROC_LOCKS_ALL &
~(ERTS_PROC_LOCK_STATUS|ERTS_PROC_LOCK_TRACE),
- &p->common, &tnif, am_spawn)) {
+ &p->common, &tnif, what)) {
Eterm mfa;
Eterm* hp;
hp = HAlloc(p, 4);
mfa = TUPLE3(hp, mod, func, args);
hp += 4;
- send_to_tracer_nif(p, &p->common, p->common.id, tnif, am_spawn, pid, mfa);
+ send_to_tracer_nif(p, &p->common, p->common.id, tnif, what, pid, mfa);
}
}
diff --git a/erts/emulator/beam/erl_trace.h b/erts/emulator/beam/erl_trace.h
index 0fefd6f70d..14d0c36016 100644
--- a/erts/emulator/beam/erl_trace.h
+++ b/erts/emulator/beam/erl_trace.h
@@ -100,7 +100,7 @@ void erts_trace_exception(Process* p, BeamInstr mfa[], Eterm class, Eterm value,
void erts_trace_return_to(Process *p, BeamInstr *pc);
void trace_sched(Process*, ErtsProcLocks, Eterm);
void trace_proc(Process*, ErtsProcLocks, Process*, Eterm, Eterm);
-void trace_proc_spawn(Process*, Eterm pid, Eterm mod, Eterm func, Eterm args);
+void trace_proc_spawn(Process*, Eterm what, Eterm pid, Eterm mod, Eterm func, Eterm args);
void save_calls(Process *p, Export *);
void trace_gc(Process *p, Eterm what);
/* port tracing */
diff --git a/erts/emulator/test/trace_SUITE.erl b/erts/emulator/test/trace_SUITE.erl
index d9974bd6f7..b7f312635e 100644
--- a/erts/emulator/test/trace_SUITE.erl
+++ b/erts/emulator/test/trace_SUITE.erl
@@ -312,12 +312,14 @@ procs_trace(Config) when is_list(Config) ->
Proc2 = spawn(?MODULE, process, [Self]),
io:format("Proc2 = ~p ~n", [Proc2]),
%%
- 1 = erlang:trace(Proc1, true, [procs]),
+ 1 = erlang:trace(Proc1, true, [procs, set_on_first_spawn]),
MFA = {?MODULE, process, [Self]},
%%
%% spawn, link
Proc1 ! {spawn_link_please, Self, MFA},
Proc3 = receive {spawned, Proc1, P3} -> P3 end,
+ receive {trace, Proc3, spawned, Proc1, MFA} -> ok end,
+ receive {trace, Proc3, getting_linked, Proc1} -> ok end,
{trace, Proc1, spawn, Proc3, MFA} = receive_first_trace(),
io:format("Proc3 = ~p ~n", [Proc3]),
{trace, Proc1, link, Proc3} = receive_first_trace(),
@@ -328,6 +330,7 @@ procs_trace(Config) when is_list(Config) ->
Reason3 = make_ref(),
Proc1 ! {send_please, Proc3, {exit_please, Reason3}},
receive {Proc1, {'EXIT', Proc3, Reason3}} -> ok end,
+ receive {trace, Proc3, exit, Reason3} -> ok end,
{trace, Proc1, getting_unlinked, Proc3} = receive_first_trace(),
Proc1 ! {trap_exit_please, false},
receive_nothing(),
diff --git a/erts/preloaded/src/erl_tracer.erl b/erts/preloaded/src/erl_tracer.erl
index a8da2b4c14..2177e48f60 100644
--- a/erts/preloaded/src/erl_tracer.erl
+++ b/erts/preloaded/src/erl_tracer.erl
@@ -5,7 +5,7 @@
-type tracee() :: port() | pid() | undefined.
-type trace_tag() :: send | send_to_non_existing_process | 'receive' |
call | return_to | return_from | exception_from |
- spawn | exit | link | unlink | getting_linked |
+ spawn | spawned | exit | link | unlink | getting_linked |
getting_unlinked | register | unregister | in | out |
in_exiting | out_exiting | out_exited |
open | closed | gc_start | gc_end.