diff options
Diffstat (limited to 'lib/kernel/doc/src/seq_trace.xml')
-rw-r--r-- | lib/kernel/doc/src/seq_trace.xml | 243 |
1 files changed, 123 insertions, 120 deletions
diff --git a/lib/kernel/doc/src/seq_trace.xml b/lib/kernel/doc/src/seq_trace.xml index f4fcd222ec..1a4a74419a 100644 --- a/lib/kernel/doc/src/seq_trace.xml +++ b/lib/kernel/doc/src/seq_trace.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1998</year><year>2013</year> + <year>1998</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -29,24 +29,17 @@ <rev>A</rev> </header> <module>seq_trace</module> - <modulesummary>Sequential Tracing of Messages</modulesummary> + <modulesummary>Sequential tracing of messages.</modulesummary> <description> <p>Sequential tracing makes it possible to trace all messages resulting from one initial message. Sequential tracing is - completely independent of the ordinary tracing in Erlang, which - is controlled by the <c>erlang:trace/3</c> BIF. See the chapter - <seealso marker="#whatis">What is Sequential Tracing</seealso> - below for more information about what sequential tracing is and - how it can be used.</p> - <p><c>seq_trace</c> provides functions which control all aspects of + independent of the ordinary tracing in Erlang, which + is controlled by the <c>erlang:trace/3</c> BIF. For more information + about what sequential tracing is and how it can be used, see section + <seealso marker="#whatis">Sequential Tracing</seealso>.</p> + <p><c>seq_trace</c> provides functions that control all aspects of sequential tracing. There are functions for activation, - deactivation, inspection and for collection of the trace output.</p> - <note> - <p>The implementation of sequential tracing is in beta status. - This means that the programming interface still might undergo - minor adjustments (possibly incompatible) based on feedback - from users.</p> - </note> + deactivation, inspection, and for collection of the trace output.</p> </description> <datatypes> <datatype> @@ -87,13 +80,18 @@ seq_trace:set_token(OldToken), % activate the trace token again <p>Sets the individual <c><anno>Component</anno></c> of the trace token to <c><anno>Val</anno></c>. Returns the previous value of the component.</p> <taglist> - <tag><c>set_token(label, <anno>Integer</anno>)</c></tag> + <tag><c>set_token(label, <anno>Label</anno>)</c></tag> <item> - <p>The <c>label</c> component is an integer which + <p>The <c>label</c> component is a term which identifies all events belonging to the same sequential trace. If several sequential traces can be active simultaneously, <c>label</c> is used to identify the separate traces. Default is 0.</p> + <warning> + <p>Labels were restricted to small signed integers (28 bits) + prior to OTP 21. The trace token will be silenty dropped if it + crosses over to a node that does not support the label.</p> + </warning> </item> <tag><c>set_token(serial, SerialValue)</c></tag> <item> @@ -136,7 +134,7 @@ seq_trace:set_token(OldToken), % activate the trace token again <seealso marker="erts:time_correction#Erlang_Monotonic_Time">Erlang monotonic time</seealso> and a monotonically increasing integer. The time-stamp has the same format and value - as produced by <c>{erlang:monotonic_time(nano_seconds), + as produced by <c>{erlang:monotonic_time(nanosecond), erlang:unique_integer([monotonic])}</c>.</p> </item> <tag><c>set_token(monotonic_timestamp, <anno>Bool</anno>)</c></tag> @@ -148,15 +146,15 @@ seq_trace:set_token(OldToken), % activate the trace token again <seealso marker="erts:time_correction#Erlang_Monotonic_Time">Erlang monotonic time</seealso>. The time-stamp has the same format and value as produced by - <c>erlang:monotonic_time(nano_seconds)</c>.</p> + <c>erlang:monotonic_time(nanosecond)</c>.</p> </item> + </taglist> <p>If multiple timestamp flags are passed, <c>timestamp</c> has precedence over <c>strict_monotonic_timestamp</c> which in turn has precedence over <c>monotonic_timestamp</c>. All timestamp flags are remembered, so if two are passed and the one with highest precedence later is disabled the other one will become active.</p> - </taglist> </desc> </func> <func> @@ -220,9 +218,10 @@ seq_trace:set_token(OldToken), % activate the trace token again <type name="tracer"/> <desc> <p>Sets the system tracer. The system tracer can be either a - process or port denoted by <c><anno>Tracer</anno></c>. Returns the previous - value (which can be <c>false</c> if no system tracer is - active).</p> + process, port or <seealso marker="erts:erl_tracer">tracer module</seealso> + denoted by <c><anno>Tracer</anno></c>. + Returns the previous value (which can be <c>false</c> if no system + tracer is active).</p> <p>Failure: <c>{badarg, Info}}</c> if <c><anno>Pid</anno></c> is not an existing local pid.</p> </desc> @@ -232,27 +231,28 @@ seq_trace:set_token(OldToken), % activate the trace token again <fsummary>Return the pid() or port() of the current system tracer.</fsummary> <type name="tracer"/> <desc> - <p>Returns the pid or port identifier of the current system + <p>Returns the pid, port identifier or tracer module of the current system tracer or <c>false</c> if no system tracer is activated.</p> </desc> </func> </funcs> <section> - <title>Trace Messages Sent To the System Tracer</title> - <p>The format of the messages are:</p> + <title>Trace Messages Sent to the System Tracer</title> + <p>The format of the messages is one of the following, depending on if + flag <c>timestamp</c> of the trace token is set to <c>true</c> or + <c>false</c>:</p> <code type="none"> {seq_trace, Label, SeqTraceInfo, TimeStamp}</code> <p>or</p> <code type="none"> {seq_trace, Label, SeqTraceInfo}</code> - <p>depending on whether the <c>timestamp</c> flag of the trace - token is set to <c>true</c> or <c>false</c>. Where:</p> + <p>Where:</p> <code type="none"> Label = int() TimeStamp = {Seconds, Milliseconds, Microseconds} Seconds = Milliseconds = Microseconds = int()</code> - <p>The <c>SeqTraceInfo</c> can have the following formats:</p> + <p><c>SeqTraceInfo</c> can have the following formats:</p> <taglist> <tag><c>{send, Serial, From, To, Message}</c></tag> <item> @@ -262,141 +262,151 @@ TimeStamp = {Seconds, Milliseconds, Microseconds} <tag><c>{'receive', Serial, From, To, Message}</c></tag> <item> <p>Used when a process <c>To</c> receives a message with a - trace token that has the <c>'receive'</c> flag set to - <c>true</c>.</p> + trace token that has flag <c>'receive'</c> set to <c>true</c>.</p> </item> <tag><c>{print, Serial, From, _, Info}</c></tag> <item> - <p>Used when a process <c>From</c> has called + <p>Used when a process <c>From</c> has called <c>seq_trace:print(Label, TraceInfo)</c> and has a trace - token with the <c>print</c> flag set to <c>true</c> and + token with flag <c>print</c> set to <c>true</c>, and <c>label</c> set to <c>Label</c>.</p> </item> </taglist> <p><c>Serial</c> is a tuple <c>{PreviousSerial, ThisSerial}</c>, - where the first integer <c>PreviousSerial</c> denotes the serial - counter passed in the last received message which carried a trace - token. If the process is the first one in a new sequential trace, - <c>PreviousSerial</c> is set to the value of the process internal - "trace clock". The second integer <c>ThisSerial</c> is the serial - counter that a process sets on outgoing messages and it is based - on the process internal "trace clock" which is incremented by one - before it is attached to the trace token in the message.</p> + where:</p> + <list type="bulleted"> + <item><p>Integer <c>PreviousSerial</c> denotes the serial + counter passed in the last received message that carried a trace + token. If the process is the first in a new sequential trace, + <c>PreviousSerial</c> is set to the value of the process internal + "trace clock".</p></item> + <item><p>Integer <c>ThisSerial</c> is the serial + counter that a process sets on outgoing messages. It is based + on the process internal "trace clock", which is incremented by one + before it is attached to the trace token in the message.</p></item> + </list> </section> <section> <marker id="whatis"></marker> - <title>What is Sequential Tracing</title> + <title>Sequential Tracing</title> <p>Sequential tracing is a way to trace a sequence of messages sent between different local or remote processes, where the sequence - is initiated by one single message. In short it works like this:</p> + is initiated by a single message. In short, it works as follows:</p> <p>Each process has a <em>trace token</em>, which can be empty or - not empty. When not empty the trace token can be seen as + not empty. When not empty, the trace token can be seen as the tuple <c>{Label, Flags, Serial, From}</c>. The trace token is passed invisibly with each message.</p> - <p>In order to start a sequential trace the user must explicitly set + <p>To start a sequential trace, the user must explicitly set the trace token in the process that will send the first message in a sequence.</p> <p>The trace token of a process is set each time the process matches a message in a receive statement, according to the trace token carried by the received message, empty or not.</p> - <p>On each Erlang node a process can be set as the <em>system tracer</em>. This process will receive trace messages each time + <p>On each Erlang node, a process can be set as the <em>system tracer</em>. + This process will receive trace messages each time a message with a trace token is sent or received (if the trace token flag <c>send</c> or <c>'receive'</c> is set). The system - tracer can then print each trace event, write it to a file or + tracer can then print each trace event, write it to a file, or whatever suitable.</p> <note> - <p>The system tracer will only receive those trace events that + <p>The system tracer only receives those trace events that occur locally within the Erlang node. To get the whole picture - of a sequential trace that involves processes on several Erlang + of a sequential trace, involving processes on many Erlang nodes, the output from the system tracer on each involved node - must be merged (off line).</p> + must be merged (offline).</p> </note> - <p>In the following sections Sequential Tracing and its most - fundamental concepts are described.</p> + <p>The following sections describe sequential tracing and its most + fundamental concepts.</p> </section> <section> <title>Trace Token</title> - <p>Each process has a current trace token. Initially the token is + <p>Each process has a current trace token. Initially, the token is empty. When the process sends a message to another process, a - copy of the current token will be sent "invisibly" along with + copy of the current token is sent "invisibly" along with the message.</p> - <p>The current token of a process is set in two ways, either</p> - <list type="ordered"> + <p>The current token of a process is set in one of the following two + ways:</p> + <list type="bulleted"> <item> - <p>explicitly by the process itself, through a call to - <c>seq_trace:set_token</c>, or</p> + <p>Explicitly by the process itself, through a call to + <c>seq_trace:set_token/1,2</c></p> </item> <item> - <p>when a message is received.</p> + <p>When a message is received</p> </item> </list> - <p>In both cases the current token will be set. In particular, if - the token of a message received is empty, the current token of + <p>In both cases, the current token is set. In particular, if + the token of a received message is empty, the current token of the process is set to empty.</p> - <p>A trace token contains a label, and a set of flags. Both - the label and the flags are set in 1 and 2 above.</p> + <p>A trace token contains a label and a set of flags. Both + the label and the flags are set in both alternatives above.</p> </section> <section> <title>Serial</title> - <p>The trace token contains a component which is called - <c>serial</c>. It consists of two integers <c>Previous</c> and + <p>The trace token contains a component called + <c>serial</c>. It consists of two integers, <c>Previous</c> and <c>Current</c>. The purpose is to uniquely identify each traced - event within a trace sequence and to order the messages - chronologically and in the different branches if any.</p> + event within a trace sequence, as well as to order the messages + chronologically and in the different branches, if any.</p> <p>The algorithm for updating <c>Serial</c> can be described as follows:</p> - <p>Let each process have two counters <c>prev_cnt</c> and - <c>curr_cnt</c> which both are set to 0 when a process is created. + <p>Let each process have two counters, <c>prev_cnt</c> and + <c>curr_cnt</c>, both are set to <c>0</c> when a process is created. The counters are updated at the following occasions:</p> <list type="bulleted"> <item> - <p><em>When the process is about to send a message and the trace token is not empty.</em></p> + <p><em>When the process is about to send a message and the trace token + is not empty.</em></p> <p>Let the serial of the trace token be <c>tprev</c> and - <c>tcurr</c>. <br></br> -<c>curr_cnt := curr_cnt + 1</c> <br></br> -<c>tprev := prev_cnt</c> <br></br> -<c>tcurr := curr_cnt</c></p> + <c>tcurr</c>.</p> + <pre> +curr_cnt := curr_cnt + 1 +tprev := prev_cnt +tcurr := curr_cnt</pre> <p>The trace token with <c>tprev</c> and <c>tcurr</c> is then passed along with the message.</p> </item> <item> - <p><em>When the process calls</em><c>seq_trace:print(Label, Info)</c>, <em>Label matches the label part of the trace token and the trace token print flag is true.</em></p> - <p>The same algorithm as for send above.</p> + <p><em>When the process calls</em> <c>seq_trace:print(Label, Info)</c>, + <c>Label</c> <em>matches the label part of the trace token and the + trace token print flag is <c>true</c>.</em></p> + <p>The algorithm is the same as for send above.</p> </item> <item> - <p><em>When a message is received and contains a nonempty trace token.</em></p> + <p><em>When a message is received and contains a non-empty trace + token.</em></p> <p>The process trace token is set to the trace token from the message.</p> <p>Let the serial of the trace token be <c>tprev</c> and - <c>tcurr</c>. <br></br> -<c><![CDATA[if (curr_cnt < tcurr )]]></c> <br></br> - - <c>curr_cnt := tcurr</c> <br></br> -<c>prev_cnt := tcurr</c></p> + <c>tcurr</c>.</p> + <code> +<![CDATA[if (curr_cnt < tcurr )]]> + curr_cnt := tcurr +prev_cnt := tcurr</code> </item> </list> - <p>The <c>curr_cnt</c> of a process is incremented each time + <p><c>curr_cnt</c> of a process is incremented each time the process is involved in a sequential trace. The counter can reach its limit (27 bits) if a process is very long-lived and is - involved in much sequential tracing. If the counter overflows it - will not be possible to use the serial for ordering of the trace - events. To prevent the counter from overflowing in the middle of - a sequential trace the function <c>seq_trace:reset_trace/0</c> - can be called to reset the <c>prev_cnt</c> and <c>curr_cnt</c> of - all processes in the Erlang node. This function will also set all - trace tokens in processes and their message queues to empty and - will thus stop all ongoing sequential tracing.</p> + involved in much sequential tracing. If the counter overflows, the + serial for ordering of the trace events cannot be used. To prevent + the counter from overflowing in the middle of + a sequential trace, function <c>seq_trace:reset_trace/0</c> + can be called to reset <c>prev_cnt</c> and <c>curr_cnt</c> of + all processes in the Erlang node. This function also sets all + trace tokens in processes and their message queues to empty, and + thus stops all ongoing sequential tracing.</p> </section> <section> - <title>Performance considerations</title> - <p>The performance degradation for a system which is enabled for - Sequential Tracing is negligible as long as no tracing is - activated. When tracing is activated there will of course be an - extra cost for each traced message but all other messages will be + <title>Performance Considerations</title> + <p>The performance degradation for a system that is enabled for + sequential tracing is negligible as long as no tracing is + activated. When tracing is activated, there is an + extra cost for each traced message, but all other messages are unaffected.</p> </section> @@ -404,13 +414,13 @@ TimeStamp = {Seconds, Milliseconds, Microseconds} <title>Ports</title> <p>Sequential tracing is not performed across ports.</p> <p>If the user for some reason wants to pass the trace token to a - port this has to be done manually in the code of the port + port, this must be done manually in the code of the port controlling process. The port controlling processes have to check the appropriate sequential trace settings (as obtained from - <c>seq_trace:get_token/1</c> and include trace information in + <c>seq_trace:get_token/1</c>) and include trace information in the message data sent to their respective ports.</p> <p>Similarly, for messages received from a port, a port controller - has to retrieve trace specific information, and set appropriate + has to retrieve trace-specific information, and set appropriate sequential trace flags through calls to <c>seq_trace:set_token/2</c>.</p> </section> @@ -418,23 +428,17 @@ TimeStamp = {Seconds, Milliseconds, Microseconds} <section> <title>Distribution</title> <p>Sequential tracing between nodes is performed transparently. - This applies to C-nodes built with Erl_Interface too. A C-node - built with Erl_Interface only maintains one trace token, which - means that the C-node will appear as one process from + This applies to C-nodes built with <c>Erl_Interface</c> too. A C-node + built with <c>Erl_Interface</c> only maintains one trace token, which + means that the C-node appears as one process from the sequential tracing point of view.</p> - <p>In order to be able to perform sequential tracing between - distributed Erlang nodes, the distribution protocol has been - extended (in a backward compatible way). An Erlang node which - supports sequential tracing can communicate with an older - (OTP R3B) node but messages passed within that node can of course - not be traced.</p> </section> <section> - <title>Example of Usage</title> - <p>The example shown here will give rough idea of how the new - primitives can be used and what kind of output it will produce.</p> - <p>Assume that we have an initiating process with + <title>Example of Use</title> + <p>This example gives a rough idea of how the new + primitives can be used and what kind of output it produces.</p> + <p>Assume that you have an initiating process with <c><![CDATA[Pid == <0.30.0>]]></c> like this:</p> <code type="none"> -module(seqex). @@ -463,8 +467,8 @@ loop() -> PortController ! {ack,Ack} end, loop().</code> - <p>A possible output from the system's sequential_tracer (inspired - by AXE-10 and MD-110) could look like:</p> + <p>A possible output from the system's <c>sequential_tracer</c> can be + like this:</p> <pre> 17:<0.30.0> Info {0,1} WITH "**** Trace Started ****" @@ -475,7 +479,7 @@ loop() -> 17:<0.30.0> Received {2,4} FROM <0.31.0> WITH {ack,{received,the_message}}</pre> <p>The implementation of a system tracer process that produces - the printout above could look like this:</p> + this printout can look like this:</p> <code type="none"> tracer() -> receive @@ -502,16 +506,15 @@ print_trace({'receive',Serial,From,To,Message}) -> print_trace({send,Serial,From,To,Message}) -> io:format("~p Sent ~p TO ~p WITH~n~p~n", [From,Serial,To,Message]).</code> - <p>The code that creates a process that runs the tracer function - above and sets that process as the system tracer could look like - this:</p> + <p>The code that creates a process that runs this tracer function + and sets that process as the system tracer can look like this:</p> <code type="none"> start() -> Pid = spawn(?MODULE,tracer,[]), seq_trace:set_system_tracer(Pid), % set Pid as the system tracer ok.</code> - <p>With a function like <c>test/0</c> below the whole example can be - started.</p> + <p>With a function like <c>test/0</c>, the whole example can be + started:</p> <code type="none"> test() -> P = spawn(?MODULE, loop, [port]), |