From 54172674e71caf7da7a0b069c9bd92543e4f705d Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Wed, 4 May 2016 14:45:05 +0200 Subject: erts: Add send and 'receive' to trace_info/2 to obtain match specs --- erts/doc/src/erlang.xml | 33 ++++++++++++++++++++----------- erts/emulator/beam/erl_bif_trace.c | 40 ++++++++++++++++++++++++++++++++++++++ erts/emulator/test/trace_SUITE.erl | 5 ++++- erts/preloaded/src/erlang.erl | 8 ++++---- 4 files changed, 70 insertions(+), 16 deletions(-) (limited to 'erts') diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index f42923a009..5af4f0bd66 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -9015,16 +9015,16 @@ timestamp() -> -

Returns trace information about a port, process or function.

-

To get information about a port or process, - PidPortOrFunc is to +

Returns trace information about a port, process, function or event.

+

To get information about a port or process, + PidPortFuncEvent is to be a process identifier (pid), port identifier or one of the atoms new, new_processes, new_ports. The atom new or new_processes means that the default trace state for processes to be created is returned. The atom new_ports means that the default trace state for ports to be created is returned.

-

The following Items are valid:

+

The following Items are valid for ports and processes:

flags @@ -9048,12 +9048,15 @@ timestamp() -> value is [].

-

To get information about a function, PidPortOrFunc is to +

To get information about a function, PidPortFuncEvent is to be the three-element tuple {Module, Function, Arity} or the atom on_load. No wild cards are allowed. Returns undefined if the function does not exist, or - false if the function is not traced.

-

The following Items are valid::

+ false if the function is not traced. If PidPortFuncEvent + is on_load, the information returned refers to + the default value for code that will be loaded.

+ +

The following Items are valid for functions:

traced @@ -9112,13 +9115,21 @@ timestamp() -> is active for this function.

+

To get information about an event, PidPortFuncEvent is to + be one of the atoms send or 'receive'.

+

The only valid Item for events is:

+ + match_spec + +

Returns the match specification for this event, if it + has one, or true if no match specification has been + set.

+
+

The return value is {Item, Value}, where Value is the requested information as described earlier. If a pid for a dead process was given, or the name of a non-existing function, Value is undefined.

-

If PidPortOrFunc is on_load, the information - returned refers to the default value for code that will be - loaded.

@@ -9237,7 +9248,7 @@ timestamp() -> false -

Disables tracing for all sent messages. +

Disables tracing for all received messages. Any match specification is removed.

diff --git a/erts/emulator/beam/erl_bif_trace.c b/erts/emulator/beam/erl_bif_trace.c index ffc0afda58..b65c0e303f 100644 --- a/erts/emulator/beam/erl_bif_trace.c +++ b/erts/emulator/beam/erl_bif_trace.c @@ -81,6 +81,8 @@ static void new_seq_trace_token(Process* p); /* help func for seq_trace_2*/ static Eterm trace_info_pid(Process* p, Eterm pid_spec, Eterm key); static Eterm trace_info_func(Process* p, Eterm pid_spec, Eterm key); static Eterm trace_info_on_load(Process* p, Eterm key); +static Eterm trace_info_event(Process* p, Eterm event, Eterm key); + static void reset_bif_trace(void); static void setup_bif_trace(void); @@ -814,6 +816,8 @@ Eterm trace_info_2(BIF_ALIST_2) if (What == am_on_load) { res = trace_info_on_load(p, Key); + } else if (What == am_send || What == am_receive) { + res = trace_info_event(p, What, Key); } else if (is_atom(What) || is_pid(What) || is_port(What)) { res = trace_info_pid(p, What, Key); } else if (is_tuple(What)) { @@ -1303,6 +1307,42 @@ trace_info_on_load(Process* p, Eterm key) } } +static Eterm +trace_info_event(Process* p, Eterm event, Eterm key) +{ + ErtsTracingEvent* te; + Eterm retval; + Eterm* hp; + + switch (event) { + case am_send: te = erts_send_tracing; break; + case am_receive: te = erts_receive_tracing; break; + default: + goto error; + } + + if (key != am_match_spec) + goto error; + + te = &te[erts_active_bp_ix()]; + + if (te->on) { + if (!te->match_spec) + retval = am_true; + else + retval = copy_object(MatchSetGetSource(te->match_spec), p); + } + else + retval = am_false; + + hp = HAlloc(p, 3); + return TUPLE2(hp, key, retval); + + error: + BIF_ERROR(p, BADARG); +} + + #undef FUNC_TRACE_NOEXIST #undef FUNC_TRACE_UNTRACED #undef FUNC_TRACE_GLOBAL_TRACE diff --git a/erts/emulator/test/trace_SUITE.erl b/erts/emulator/test/trace_SUITE.erl index 1930332691..3d7cb41fc0 100644 --- a/erts/emulator/test/trace_SUITE.erl +++ b/erts/emulator/test/trace_SUITE.erl @@ -495,7 +495,10 @@ send_trace(Config) when is_list(Config) -> ok. set_trace_pattern(_, no, _) -> 0; -set_trace_pattern(MSA, Pat, Flg) -> erlang:trace_pattern(MSA, Pat, Flg). +set_trace_pattern(MFA, Pat, Flg) -> + R = erlang:trace_pattern(MFA, Pat, Flg), + {match_spec, Pat} = erlang:trace_info(MFA, match_spec), + R. %% Test trace(Pid, How, [procs]). procs_trace(Config) when is_list(Config) -> diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl index d09958032b..90fd536b15 100644 --- a/erts/preloaded/src/erlang.erl +++ b/erts/preloaded/src/erlang.erl @@ -1749,16 +1749,16 @@ trace_delivered(_Tracee) -> erlang:nif_error(undefined). %% trace_info/2 --spec erlang:trace_info(PidPortOrFunc, Item) -> Res when - PidPortOrFunc :: pid() | port() | new | new_processes | new_ports - | {Module, Function, Arity} | on_load, +-spec erlang:trace_info(PidPortFuncEvent, Item) -> Res when + PidPortFuncEvent :: pid() | port() | new | new_processes | new_ports + | {Module, Function, Arity} | on_load | send | 'receive', Module :: module(), Function :: atom(), Arity :: arity(), Item :: flags | tracer | traced | match_spec | meta | meta_match_spec | call_count | call_time | all, Res :: trace_info_return(). -trace_info(_PidPortOrFunc, _Item) -> +trace_info(_PidPortFuncEvent, _Item) -> erlang:nif_error(undefined). %% trunc/1 -- cgit v1.2.3