diff options
Diffstat (limited to 'erts/doc')
33 files changed, 1046 insertions, 230 deletions
diff --git a/erts/doc/Makefile b/erts/doc/Makefile index d415e544f3..f26a43592e 100644 --- a/erts/doc/Makefile +++ b/erts/doc/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1996-2009. All Rights Reserved. +# Copyright Ericsson AB 1996-2016. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/erts/doc/src/Makefile b/erts/doc/src/Makefile index 83f4c58560..b96cbbce40 100644 --- a/erts/doc/src/Makefile +++ b/erts/doc/src/Makefile @@ -1,7 +1,7 @@ # # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2012. All Rights Reserved. +# Copyright Ericsson AB 1997-2016. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -50,12 +50,14 @@ XML_REF1_FILES = epmd.xml \ XML_REF3_EFILES = \ erl_prim_loader.xml \ erlang.xml \ + erl_tracer.xml \ init.xml \ zlib.xml XML_REF3_FILES = \ driver_entry.xml \ erl_nif.xml \ + erl_tracer.xml \ erl_driver.xml \ erl_prim_loader.xml \ erlang.xml \ @@ -154,18 +156,9 @@ clean: rm -f $(SPECDIR)/* rm -f errs core *~ -$(SPECDIR)/specs_driver_entry.xml: +$(SPECDIR)/specs_%.xml: escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ - -o$(dir $@) -module driver_entry -$(SPECDIR)/specs_erl_nif.xml: - escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ - -o$(dir $@) -module erl_nif -$(SPECDIR)/specs_erl_driver.xml: - escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ - -o$(dir $@) -module erl_driver -$(SPECDIR)/specs_erts_alloc.xml: - escript $(SPECS_EXTRACTOR) $(SPECS_FLAGS) \ - -o$(dir $@) -module erts_alloc + -o$(dir $@) -module $(patsubst $(SPECDIR)/specs_%.xml,%,$@) # ---------------------------------------------------- # Release Target diff --git a/erts/doc/src/alt_dist.xml b/erts/doc/src/alt_dist.xml index 2263302707..e283acc1b4 100644 --- a/erts/doc/src/alt_dist.xml +++ b/erts/doc/src/alt_dist.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2000</year><year>2013</year> + <year>2000</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/book.xml b/erts/doc/src/book.xml index 12eda03ee5..a0780c91d9 100644 --- a/erts/doc/src/book.xml +++ b/erts/doc/src/book.xml @@ -4,7 +4,7 @@ <book xmlns:xi="http://www.w3.org/2001/XInclude"> <header titlestyle="normal"> <copyright> - <year>1997</year><year>2013</year> + <year>1997</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/communication.xml b/erts/doc/src/communication.xml index 3deea3e4af..1eb05310e9 100644 --- a/erts/doc/src/communication.xml +++ b/erts/doc/src/communication.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2012</year><year>2013</year> + <year>2012</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/crash_dump.xml b/erts/doc/src/crash_dump.xml index 61c9159823..0b827ae583 100644 --- a/erts/doc/src/crash_dump.xml +++ b/erts/doc/src/crash_dump.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1999</year><year>2013</year> + <year>1999</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/driver.xml b/erts/doc/src/driver.xml index a68e87d3b3..4bef5e1388 100644 --- a/erts/doc/src/driver.xml +++ b/erts/doc/src/driver.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2001</year><year>2013</year> + <year>2001</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/epmd.xml b/erts/doc/src/epmd.xml index 7f61804bea..d9f580d081 100644 --- a/erts/doc/src/epmd.xml +++ b/erts/doc/src/epmd.xml @@ -4,7 +4,7 @@ <comref> <header> <copyright> - <year>1996</year><year>2013</year> + <year>1996</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml index 096af096dc..e13470c83c 100644 --- a/erts/doc/src/erl.xml +++ b/erts/doc/src/erl.xml @@ -4,7 +4,7 @@ <comref> <header> <copyright> - <year>1996</year><year>2015</year> + <year>1996</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/erl_driver.xml b/erts/doc/src/erl_driver.xml index 241d4131d5..175b7f6bfb 100644 --- a/erts/doc/src/erl_driver.xml +++ b/erts/doc/src/erl_driver.xml @@ -4,7 +4,7 @@ <cref> <header> <copyright> - <year>2001</year><year>2015</year> + <year>2001</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml index be0e406b9c..7546f7ef81 100644 --- a/erts/doc/src/erl_nif.xml +++ b/erts/doc/src/erl_nif.xml @@ -4,7 +4,7 @@ <cref> <header> <copyright> - <year>2001</year><year>2015</year> + <year>2001</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -524,6 +524,18 @@ typedef struct { <p>Note that <c>ErlNifBinary</c> is a semi-opaque type and you are only allowed to read fields <c>size</c> and <c>data</c>.</p> </item> + + <tag><marker id="ErlNifBinaryToTerm"/>ErlNifBinaryToTerm</tag> + <item> + <p>An enumeration of the options that can be given to + <seealso marker="#enif_binary_to_term">enif_binary_to_term</seealso>. + For default behavior, use the value <c>0</c>.</p> + <taglist> + <tag><c>ERL_NIF_BIN2TERM_SAFE</c></tag> + <item><p>Use this option when receiving data from untrusted sources.</p></item> + </taglist> + </item> + <tag><marker id="ErlNifPid"/>ErlNifPid</tag> <item> <p><c>ErlNifPid</c> is a process identifier (pid). In contrast to @@ -532,6 +544,14 @@ typedef struct { <seealso marker="#ErlNifEnv">environment</seealso>. <c>ErlNifPid</c> is an opaque type.</p> </item> + <tag><marker id="ErlNifPort"/>ErlNifPort</tag> + <item> + <p><c>ErlNifPort</c> is a port identifier. In contrast to + port id terms (instances of <c>ERL_NIF_TERM</c>), <c>ErlNifPort</c>'s are self + contained and not bound to any + <seealso marker="#ErlNifEnv">environment</seealso>. <c>ErlNifPort</c> + is an opaque type.</p> + </item> <tag><marker id="ErlNifResourceType"/>ErlNifResourceType</tag> <item> @@ -546,8 +566,7 @@ typedef struct { <code type="none"> typedef void ErlNifResourceDtor(ErlNifEnv* env, void* obj); </code> - <p>The function prototype of a resource destructor function. - A destructor function is not allowed to call any term-making functions.</p> + <p>The function prototype of a resource destructor function.</p> </item> <tag><marker id="ErlNifCharEncoding"/>ErlNifCharEncoding</tag> <item> @@ -591,6 +610,21 @@ typedef enum { </taglist> </item> + <tag><marker id="ErlNifUniqueInteger"/>ErlNifUniqueInteger</tag> + <item> + <p>An enumeration of the properties that can be requested from + <seealso marker="#enif_make_unique_integer">enif_unique_integer</seealso>. + For default properties, use the value <c>0</c>.</p> + <taglist> + <tag><c>ERL_NIF_UNIQUE_POSITIVE</c></tag> + <item><p>Return only positive integers</p></item> + <tag><c>ERL_NIF_UNIQUE_MONOTONIC</c></tag> + <item><p>Return only + <seealso marker="time_correction#Strictly_Monotonically_Increasing">strictly + monotonically increasing</seealso> integer corresponding to creation time</p></item> + </taglist> + </item> + </taglist> </section> @@ -632,6 +666,25 @@ typedef enum { have been allocated with <seealso marker="#enif_alloc_env">enif_alloc_env</seealso>. </p></desc> </func> + <func><name><ret>size_t</ret><nametext>enif_binary_to_term(ErlNifEnv *env, const unsigned char* data, size_t size, ERL_NIF_TERM *term, ErlNifBinaryToTerm opts)</nametext></name> + <fsummary>Create a term from the external format</fsummary> + <desc> + <p>Create a term that is the result of decoding the binary data + at <c>data</c>, which must be encoded according to the Erlang external term format. + No more than <c>size</c> bytes are read from <c>data</c>. Argument <c>opts</c> + correspond to the second argument to <seealso marker="erlang#binary_to_term-2"> + <c>erlang:binary_to_term/2</c></seealso>, and must be either <c>0</c> or + <c>ERL_NIF_BIN2TERM_SAFE</c>.</p> + <p>On success, store the resulting term at <c>*term</c> and return + the actual number of bytes read. Return zero if decoding fails or if <c>opts</c> + is invalid.</p> + <p>See also: + <seealso marker="#ErlNifBinaryToTerm"><c>ErlNifBinaryToTerm</c></seealso>, + <seealso marker="erlang#binary_to_term-2"><c>erlang:binary_to_term/2</c></seealso> and + <seealso marker="#enif_term_to_binary"><c>enif_term_to_binary</c></seealso>. + </p> + </desc> + </func> <func><name><ret>int</ret><nametext>enif_compare(ERL_NIF_TERM lhs, ERL_NIF_TERM rhs)</nametext></name> <fsummary>Compare two terms</fsummary> <desc><p>Return an integer less than, equal to, or greater than @@ -689,7 +742,48 @@ typedef enum { a number of repeated NIF-calls without the need to create threads. See also the <seealso marker="#WARNING">warning</seealso> text at the beginning of this document.</p> </desc> + </func> + + <func> + <name><ret>ErlNifTime</ret><nametext>enif_convert_time_unit(ErlNifTime val, ErlNifTimeUnit from, ErlNifTimeUnit to)</nametext></name> + <fsummary>Convert time unit of a time value</fsummary> + <desc> + <marker id="enif_convert_time_unit"></marker> + <p>Arguments:</p> + <taglist> + <tag><c>val</c></tag> + <item>Value to convert time unit for.</item> + <tag><c>from</c></tag> + <item>Time unit of <c>val</c>.</item> + <tag><c>to</c></tag> + <item>Time unit of returned value.</item> + </taglist> + <p>Converts the <c>val</c> value of time unit <c>from</c> to + the corresponding value of time unit <c>to</c>. The result is + rounded using the floor function.</p> + <p>Returns <c>ERL_NIF_TIME_ERROR</c> if called with an invalid + time unit argument.</p> + <p>See also: + <seealso marker="#ErlNifTime"><c>ErlNifTime</c></seealso> and + <seealso marker="#ErlNifTimeUnit"><c>ErlNifTimeUnit</c></seealso>. + </p> + </desc> + </func> + + <func> + <name><ret>ERL_NIF_TERM</ret><nametext>enif_cpu_time(ErlNifEnv *)</nametext></name> + <fsummary></fsummary> + <desc> + <p>Returns the CPU time in the same format as <seealso marker="erlang#timestamp-0">erlang:timestamp()</seealso>. + The CPU time is the time the current logical cpu has spent executing since + some arbitrary point in the past. + If the OS does not support fetching of this value <c>enif_cpu_time</c> + invokes <seealso marker="#enif_make_badarg">enif_make_badarg</seealso>. + </p> + </desc> + </func> + <func><name><ret>int</ret><nametext>enif_equal_tids(ErlNifTid tid1, ErlNifTid tid2)</nametext></name> <fsummary></fsummary> <desc><p>Same as <seealso marker="erl_driver#erl_drv_equal_tids">erl_drv_equal_tids</seealso>. @@ -744,6 +838,12 @@ typedef enum { pid variable <c>*pid</c> from it and return true. Otherwise return false. No check if the process is alive is done.</p></desc> </func> + <func><name><ret>int</ret><nametext>enif_get_local_port(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifPort* port_id)</nametext></name> + <fsummary>Read an local port term</fsummary> + <desc><p>If <c>term</c> identifies a node local port, initialize the + port variable <c>*port_id</c> from it and return true. Otherwise return false. + No check if the port is alive is done.</p></desc> + </func> <func><name><ret>int</ret><nametext>enif_get_list_cell(ErlNifEnv* env, ERL_NIF_TERM list, ERL_NIF_TERM* head, ERL_NIF_TERM* tail)</nametext></name> <fsummary>Get head and tail from a list</fsummary> <desc><p>Set <c>*head</c> and <c>*tail</c> from @@ -912,6 +1012,17 @@ typedef enum { <fsummary>Determine if a term is a port</fsummary> <desc><p>Return true if <c>term</c> is a port.</p></desc> </func> + <func><name><ret>int</ret><nametext>enif_is_port_alive(ErlNifEnv* env, ErlNifPort *port_id)</nametext></name> + <fsummary>Determine if a local port is alive or not.</fsummary> + <desc><p>Return true if <c>port_id</c> is currently alive.</p> + <p>This function can only be used in a from a NIF-calling thread.</p></desc> + </func> + <func><name><ret>int</ret><nametext>enif_is_process_alive(ErlNifEnv* env, ErlNifPid *pid)</nametext></name> + <fsummary>Determine if a local process is alive or not.</fsummary> + <desc><p>Return true if <c>pid</c> is currently alive.</p> + <p>This function is only thread-safe when the emulator with SMP support is used. + It can only be used in a non-SMP emulator from a NIF-calling thread.</p></desc> + </func> <func><name><ret>int</ret><nametext>enif_is_ref(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name> <fsummary>Determine if a term is a reference</fsummary> <desc><p>Return true if <c>term</c> is a reference.</p></desc> @@ -961,7 +1072,7 @@ typedef enum { <seealso marker="#enif_is_exception">enif_is_exception</seealso>, but not to any other NIF API function.</p> <p>See also: <seealso marker="#enif_has_pending_exception">enif_has_pending_exception</seealso> - and <seealso marker="#enif_raise_exception">enif_raise_exception</seealso> + and <seealso marker="#enif_raise_exception">enif_raise_exception</seealso>. </p> <note><p>In earlier versions (older than erts-7.0, OTP 18) the return value from <c>enif_make_badarg</c> had to be returned from the NIF. This @@ -1195,6 +1306,23 @@ typedef enum { <fsummary>Create an unsigned integer term</fsummary> <desc><p>Create an integer term from an unsigned 64-bit integer.</p></desc> </func> + <func> + <name><ret>ERL_NIF_TERM</ret><nametext>enif_make_unique_integer(ErlNifEnv *env, ErlNifUniqueInteger properties)</nametext></name> + <fsummary></fsummary> + <desc> + <p>Returns a unique integer with the same properties as given by <seealso marker="erlang#unique_integer-1">erlang:unique_integer/1</seealso>.</p> + <p><c>env</c> is the environment to create the integer in.</p> + <p> + <c>ERL_NIF_UNIQUE_POSITIVE</c> and <c>ERL_NIF_UNIQUE_MONOTONIC</c> can + be passed as the second argument to change the properties of the + integer returned. It is possible to combine them by or:ing the + two values together. + </p> + <p>See also: + <seealso marker="#ErlNifUniqueInteger"><c>ErlNifUniqueInteger</c></seealso>. + </p> + </desc> + </func> <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_ulong(ErlNifEnv* env, unsigned long i)</nametext></name> <fsummary>Create an integer term from an unsigned long int</fsummary> <desc><p>Create an integer term from an <c>unsigned long int</c>.</p></desc> @@ -1265,6 +1393,33 @@ enif_map_iterator_destroy(env, &iter); or false if the iterator is positioned at the head (before the first entry).</p></desc> </func> + + <func> + <name><ret>ErlNifTime</ret><nametext>enif_monotonic_time(ErlNifTimeUnit time_unit)</nametext></name> + <fsummary>Get Erlang Monotonic Time</fsummary> + <desc> + <marker id="enif_monotonic_time"></marker> + <p>Arguments:</p> + <taglist> + <tag><c>time_unit</c></tag> + <item>Time unit of returned value.</item> + </taglist> + <p> + Returns the current + <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang + monotonic time</seealso>. Note that it is not uncommon with + negative values. + </p> + <p>Returns <c>ERL_NIF_TIME_ERROR</c> if called with an invalid + time unit argument, or if called from a thread that is not a + scheduler thread.</p> + <p>See also: + <seealso marker="#ErlNifTime"><c>ErlNifTime</c></seealso> and + <seealso marker="#ErlNifTimeUnit"><c>ErlNifTimeUnit</c></seealso>. + </p> + </desc> + </func> + <func><name><ret>ErlNifMutex *</ret><nametext>enif_mutex_create(char *name)</nametext></name> <fsummary></fsummary> <desc><p>Same as <seealso marker="erl_driver#erl_drv_mutex_create">erl_drv_mutex_create</seealso>. @@ -1290,6 +1445,11 @@ enif_map_iterator_destroy(env, &iter); <desc><p>Same as <seealso marker="erl_driver#erl_drv_mutex_unlock">erl_drv_mutex_unlock</seealso>. </p></desc> </func> + <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_now_time(ErlNifEnv *env)</nametext></name> + <fsummary></fsummary> + <desc><p>Retuns an <seealso marker="erlang#now-0">erlang:now()</seealso> timestamp. + The enif_now_time function is <em>deprecated</em>.</p></desc> + </func> <func><name><ret>ErlNifResourceType *</ret><nametext>enif_open_resource_type(ErlNifEnv* env, const char* module_str, const char* name, ErlNifResourceDtor* dtor, ErlNifResourceFlags flags, ErlNifResourceFlags* tried)</nametext></name> @@ -1319,6 +1479,35 @@ enif_map_iterator_destroy(env, &iter); and <seealso marker="#upgrade">upgrade</seealso>.</p> </desc> </func> + <func><name><ret>int</ret><nametext>enif_port_command(ErlNifEnv* env, const ErlNifPort* to_port, ErlNifEnv *msg_env, ERL_NIF_TERM msg)</nametext></name> + <fsummary>Send a port_command to to_port</fsummary> + <desc> + <p>This function works the same as <seealso marker="erlang#port_command-2">erlang:port_command/2</seealso> + except that it is always completely asynchronous. This call may return false + if it detects that the port is already dead, otherwise it will return true. + </p> + <taglist> + <tag><c>env</c></tag> + <item>The environment of the calling process. May not be NULL.</item> + <tag><c>*to_port</c></tag> + <item>The port id of the receiving port. The port id should refer to a + port on the local node.</item> + <tag><c>msg_env</c></tag> + <item>The environment of the message term. Can be a process + independent environment allocated with + <seealso marker="#enif_alloc_env">enif_alloc_env</seealso> or NULL.</item> + <tag><c>msg</c></tag> + <item>The message term to send. The same limitations apply as on the + payload to <seealso marker="erlang#port_command-2">erlang:port_command/2</seealso>.</item> + </taglist> + <p>Using a <c>msg_env</c> of NULL is an optimization which groups together + calls to <c>enif_alloc_env</c>, <c>enif_make_copy</c>, <c>enif_port_command</c> + and <c>enif_free_env</c> into one call. This optimization is only usefull + when a majority of the terms are to be copied from <c>env</c> to the <c>msg_env</c>.</p> + <p>The call may return false if it detects that the command failed for some reason. Otherwise true is returned.</p> + <p>See also: <seealso marker="#enif_get_local_port"><c>enif_get_local_port</c></seealso>.</p> + </desc> + </func> <func><name><ret>void *</ret><nametext>enif_priv_data(ErlNifEnv* env)</nametext></name> <fsummary>Get the private data of a NIF library</fsummary> <desc><p>Return the pointer to the private data that was set by <c>load</c>, @@ -1442,7 +1631,7 @@ enif_map_iterator_destroy(env, &iter); <tag><c>msg_env</c></tag> <item>The environment of the message term. Must be a process independent environment allocated with - <seealso marker="#enif_alloc_env">enif_alloc_env</seealso>.</item> + <seealso marker="#enif_alloc_env">enif_alloc_env</seealso> or NULL.</item> <tag><c>msg</c></tag> <item>The message term to send.</item> </taglist> @@ -1451,8 +1640,12 @@ enif_map_iterator_destroy(env, &iter); <c>msg</c>) will be invalidated by a successful call to <c>enif_send</c>. The environment should either be freed with <seealso marker="#enif_free_env">enif_free_env</seealso> of cleared for reuse with <seealso marker="#enif_clear_env">enif_clear_env</seealso>.</p> + <p>If <c>msg_env</c> is set to NULL the <c>msg</c> term is copied and + the original term and its environemt is still valid after the call.</p> <p>This function is only thread-safe when the emulator with SMP support is used. It can only be used in a non-SMP emulator from a NIF-calling thread.</p> + <note><p>Passing <c>msg_env</c> as <c>NULL</c> is only supported since + erts-8.0 (OTP 19).</p></note> </desc> </func> <func><name><ret>unsigned</ret><nametext>enif_sizeof_resource(void* obj)</nametext></name> @@ -1466,6 +1659,18 @@ enif_map_iterator_destroy(env, &iter); <desc><p>Same as <seealso marker="erl_driver#driver_system_info">driver_system_info</seealso>. </p></desc> </func> + <func><name><ret>int</ret><nametext>enif_term_to_binary(ErlNifEnv *env, ERL_NIF_TERM term, ErlNifBinary *bin)</nametext></name> + <fsummary>Convert a term to the external format</fsummary> + <desc> + <p>Allocates a new binary with <seealso marker="#enif_alloc_binary">enif_alloc_binary</seealso> + and stores the result of encoding <c>term</c> according to the Erlang external term format.</p> + <p>Returns true on success or false if allocation failed.</p> + <p>See also: + <seealso marker="erlang#term_to_binary-1"><c>erlang:term_to_binary/1</c></seealso> and + <seealso marker="#enif_binary_to_term"><c>enif_binary_to_term</c></seealso>. + </p> + </desc> + </func> <func><name><ret>int</ret><nametext>enif_thread_create(char *name,ErlNifTid *tid,void * (*func)(void *),void *args,ErlNifThreadOpts *opts)</nametext></name> <fsummary></fsummary> <desc><p>Same as <seealso marker="erl_driver#erl_drv_thread_create">erl_drv_thread_create</seealso>. @@ -1496,54 +1701,6 @@ enif_map_iterator_destroy(env, &iter); <desc><p>Same as <seealso marker="erl_driver#erl_drv_thread_self">erl_drv_thread_self</seealso>. </p></desc> </func> - <func><name><ret>int</ret><nametext>enif_tsd_key_create(char *name, ErlNifTSDKey *key)</nametext></name> - <fsummary></fsummary> - <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_key_create">erl_drv_tsd_key_create</seealso>. - </p></desc> - </func> - <func><name><ret>void</ret><nametext>enif_tsd_key_destroy(ErlNifTSDKey key)</nametext></name> - <fsummary></fsummary> - <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_key_destroy">erl_drv_tsd_key_destroy</seealso>. - </p></desc> - </func> - <func><name><ret>void *</ret><nametext>enif_tsd_get(ErlNifTSDKey key)</nametext></name> - <fsummary></fsummary> - <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_get">erl_drv_tsd_get</seealso>. - </p></desc> - </func> - <func><name><ret>void</ret><nametext>enif_tsd_set(ErlNifTSDKey key, void *data)</nametext></name> - <fsummary></fsummary> - <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_set">erl_drv_tsd_set</seealso>. - </p></desc> - </func> - - - <func> - <name><ret>ErlNifTime</ret><nametext>enif_monotonic_time(ErlNifTimeUnit time_unit)</nametext></name> - <fsummary>Get Erlang Monotonic Time</fsummary> - <desc> - <marker id="enif_monotonic_time"></marker> - <p>Arguments:</p> - <taglist> - <tag><c>time_unit</c></tag> - <item>Time unit of returned value.</item> - </taglist> - <p> - Returns - <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang - monotonic time</seealso>. Note that it is not uncommon with - negative values. - </p> - <p>Returns <c>ERL_NIF_TIME_ERROR</c> if called with an invalid - time unit argument, or if called from a thread that is not a - scheduler thread.</p> - <p>See also:</p> - <list> - <item><seealso marker="#ErlNifTime"><c>ErlNifTime</c></seealso></item> - <item><seealso marker="#ErlNifTimeUnit"><c>ErlNifTimeUnit</c></seealso></item> - </list> - </desc> - </func> <func> <name><ret>ErlNifTime</ret><nametext>enif_time_offset(ErlNifTimeUnit time_unit)</nametext></name> @@ -1563,41 +1720,33 @@ enif_map_iterator_destroy(env, &iter); <p>Returns <c>ERL_NIF_TIME_ERROR</c> if called with an invalid time unit argument, or if called from a thread that is not a scheduler thread.</p> - <p>See also:</p> - <list> - <item><seealso marker="#ErlNifTime"><c>ErlNifTime</c></seealso></item> - <item><seealso marker="#ErlNifTimeUnit"><c>ErlNifTimeUnit</c></seealso></item> - </list> + <p>See also: + <seealso marker="#ErlNifTime"><c>ErlNifTime</c></seealso> and + <seealso marker="#ErlNifTimeUnit"><c>ErlNifTimeUnit</c></seealso>. + </p> </desc> </func> - <func> - <name><ret>ErlNifTime</ret><nametext>enif_convert_time_unit(ErlNifTime val, ErlNifTimeUnit from, ErlNifTimeUnit to)</nametext></name> - <fsummary>Convert time unit of a time value</fsummary> - <desc> - <marker id="enif_convert_time_unit"></marker> - <p>Arguments:</p> - <taglist> - <tag><c>val</c></tag> - <item>Value to convert time unit for.</item> - <tag><c>from</c></tag> - <item>Time unit of <c>val</c>.</item> - <tag><c>to</c></tag> - <item>Time unit of returned value.</item> - </taglist> - <p>Converts the <c>val</c> value of time unit <c>from</c> to - the corresponding value of time unit <c>to</c>. The result is - rounded using the floor function.</p> - <p>Returns <c>ERL_NIF_TIME_ERROR</c> if called with an invalid - time unit argument.</p> - <p>See also:</p> - <list> - <item><seealso marker="#ErlNifTime"><c>ErlNifTime</c></seealso></item> - <item><seealso marker="#ErlNifTimeUnit"><c>ErlNifTimeUnit</c></seealso></item> - </list> - </desc> + <func><name><ret>int</ret><nametext>enif_tsd_key_create(char *name, ErlNifTSDKey *key)</nametext></name> + <fsummary></fsummary> + <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_key_create">erl_drv_tsd_key_create</seealso>. + </p></desc> + </func> + <func><name><ret>void</ret><nametext>enif_tsd_key_destroy(ErlNifTSDKey key)</nametext></name> + <fsummary></fsummary> + <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_key_destroy">erl_drv_tsd_key_destroy</seealso>. + </p></desc> + </func> + <func><name><ret>void *</ret><nametext>enif_tsd_get(ErlNifTSDKey key)</nametext></name> + <fsummary></fsummary> + <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_get">erl_drv_tsd_get</seealso>. + </p></desc> + </func> + <func><name><ret>void</ret><nametext>enif_tsd_set(ErlNifTSDKey key, void *data)</nametext></name> + <fsummary></fsummary> + <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_set">erl_drv_tsd_set</seealso>. + </p></desc> </func> - </funcs> <section> <title>SEE ALSO</title> diff --git a/erts/doc/src/erl_prim_loader.xml b/erts/doc/src/erl_prim_loader.xml index 8f66e07ae1..d3ece37cc5 100644 --- a/erts/doc/src/erl_prim_loader.xml +++ b/erts/doc/src/erl_prim_loader.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2013</year> + <year>1996</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/erl_tracer.xml b/erts/doc/src/erl_tracer.xml new file mode 100644 index 0000000000..1e8e78b25f --- /dev/null +++ b/erts/doc/src/erl_tracer.xml @@ -0,0 +1,324 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE erlref SYSTEM "erlref.dtd"> + +<erlref> + <header> + <copyright> + <year>2016</year><year>2016</year> + <holder>Ericsson AB. All Rights Reserved.</holder> + </copyright> + <legalnotice> + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + </legalnotice> + + <title>erl_tracer</title> + <prepared></prepared> + <docno></docno> + <date></date> + <rev></rev> + </header> + <module>erl_tracer</module> + <modulesummary>Erlang Tracer Behaviour</modulesummary> + <description> + <p>A behaviour module for implementing the back end of the erlang + tracing system. The functions in this module will be called whenever + a trace probe is triggered. Both the <c>enabled</c> and <c>trace</c> + functions are called in the context of the entity that triggered the + trace probe. + This means that the overhead by having the tracing enabled will be + greatly effected by how much time is spent in these functions. So do as + little work as possible in these functions.</p> + <note> + <p>All functions in this behaviour have to be implemented as NIF's. + This is a limitation that may the lifted in the future. + There is an <seealso marker="#example">example tracer module nif</seealso> + implementation at the end of this page.</p> + </note> + <warning> + <p>Do not send messages or issue port commands to the <c>Tracee</c> + in any of the callbacks. Doing so is not allowed and can cause all + sorts of strange behaviour, including but not limited to infinite + recursions.</p> + </warning> + </description> + + <datatypes> + <datatype> + <name name="trace_tag" /> + <desc> + <p>The different trace tags that the tracer will be called with. + Each trace tag is described in greater detail in + <seealso marker="#trace">Module:trace/6</seealso> + </p> + </desc> + </datatype> + <datatype> + <name name="tracee" /> + <desc> + <p>The process or port that the trace belongs to. + </p> + </desc> + </datatype> + <datatype> + <name name="trace_opts" /> + <desc> + <p>The options for the tracee. + <taglist> + <tag><c>timestamp</c></tag> + <item>If not set to <c>undefined</c>, the tracer has been requested to + include a timestamp.</item> + <tag><c>match_spec_result</c></tag> + <item>If not set to <c>true</c>, the tracer has been requested to + include the output of a match specification that was run.</item> + <tag><c>scheduler_id</c></tag> + <item>Set to a number of the scheduler id is to be included by the tracer. + Otherwise it is set to <c>undefined</c>.</item> + </taglist> + </p> + </desc> + </datatype> + <datatype> + <name name="tracer_state" /> + <desc> + <p> + The state which is given when calling + <seealso marker="erlang#trace-3"><c>erlang:trace(PidPortSpec,true,[{tracer,Module,TracerState}])</c></seealso>. + The tracer state is an immutable value that is passed to erl_tracer callbacks and should + contain all the data that is needed to generate the trace event. + </p> + </desc> + </datatype> + </datatypes> + + <section> + <title>CALLBACK FUNCTIONS</title> + <p>The following functions + should be exported from a <c>erl_tracer</c> callback module.</p> + </section> + <marker id="enabled"></marker> + <funcs> + <func> + <name>Module:enabled(TraceTag, TracerState, Tracee) -> Result</name> + <fsummary>Check if a trace event should be generated.</fsummary> + <type> + <v>TraceTag = <seealso marker="#type-trace_tag">trace_tag()</seealso> | trace_status</v> + <v>TracerState = term()</v> + <v>Tracee = <seealso marker="#type-trace_tag">tracee()</seealso></v> + <v>Result = trace | discard | remove</v> + </type> + <desc> + <p>This callback will be called whenever a trace point is triggered. It + allows the tracer to decide whether a trace should be generated or not. + This check is made as early as possible in order to limit the amount of + overhead associated with tracing. If <c>trace</c> is returned the + necessary trace data will be created and the trace call-back of the tracer + will be called. If <c>discard</c> is returned, this trace call + will be discarded and no call to trace will be done. If + <c>remove</c> is returned, the VM will attempt to remove this tracer + from the tracee, together with any trace flags set on the tracee. + </p> + <p><c>trace_status</c> is a special type of <c>TraceTag</c> which is used + to check if the tracer should still be active. It is called in multiple + scenarios, but most significantly it is used when tracing is started + using this tracer.</p> + <p>This function may be called multiple times per trace point, so it + is important that it is both fast and side effect free.</p> + </desc> + </func> + <marker id="trace"></marker> + <func> + <name>Module:trace(TraceTag, TracerState, Tracee, FirstTraceTerm, SecondTraceTerm, Opts) -> Result</name> + <fsummary>Check if a trace event should be generated.</fsummary> + <type> + <v>TraceTag = <seealso marker="#type-trace_tag">trace_tag()</seealso></v> + <v>TracerState = term()</v> + <v>Tracee = <seealso marker="#type-trace_tag">tracee()</seealso></v> + <v>FirstTraceTerm = term()</v> + <v>SecondTraceTerm = term() | undefined</v> + <v>Opts = <seealso marker="#type-trace_opts">trace_opts()</seealso></v> + <v>Result = ok</v> + </type> + <desc> + <p>This callback will be called when a trace point is triggered and + the <seealso marker="#enabled">Module:enabled/3</seealso> + callback returned <c>trace</c>. In it any side effects needed by + the tracer should be done. The trace point payload is located in + the <c>FirstTraceTerm</c> and <c>SecondTraceTerm</c>. The content + of the TraceTerms depends on which <c>TraceTag</c> has been triggered. + The <c>FirstTraceTerm</c> and <c>SecondTraceTerm</c> correspond to the + fourth and fifth slot in the trace tuples described in + <seealso marker="erlang#trace_3_trace_messages">erlang:trace/3</seealso>. + If the tuple only has four elements, <c>SecondTraceTerm</c> will be + <c>undefined</c>.</p> + </desc> + </func> + <func> + <name name="trace">Module:trace(seq_trace, TracerState, Label, SeqTraceInfo, undefined, Opts) -> Result</name> + <fsummary>Check if a sequence trace event should be generated.</fsummary> + <type> + <v>TracerState = term()</v> + <v>Label = term()</v> + <v>SeqTraceInfo = term()</v> + <v>Opts = <seealso marker="#type-trace_opts">trace_opts()</seealso></v> + <v>Result = ok</v> + </type> + <desc> + <p>The <c>TraceTag</c> <c>seq_trace</c> is handled a little bit + differently. There is not <c>Tracee</c> for seq_trace, instead the + <c>Label</c> associated with the seq_trace event is given. + For more info on what <c>Label</c> and <c>SeqTraceInfo</c> can be + see the <seealso marker="kernel:seq_trace">seq_trace</seealso> manual.</p> + </desc> + </func> + </funcs> + <section> + <marker id="example"></marker> + <title>Erl Tracer Module example</title> + <p>In the example below a tracer module with a nif backend sends a message + for each <c>send</c> trace tag containing only the sender and receiver. + Using this tracer module, a much more lightweight message tracer is + used that only records who sent messages to who.</p> + <p>Here is an example session using it on Linux.</p> + <pre> +$ gcc -I erts-8.0/include/ -fPIC -shared -o erl_msg_tracer.so erl_msg_tracer.c +$ erl +Erlang/OTP 19 [DEVELOPMENT] [erts-8.0] [source-ed2b56b] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] + +Eshell V8.0 (abort with ^G) +1> c(erl_msg_tracer), erl_msg_tracer:load(). +ok +2> Tracer = spawn(fun F() -> receive M -> io:format("~p~n",[M]), F() end end). +<0.37.0> +3> erlang:trace(new, true, [send,{tracer, erl_msg_tracer, Tracer}]). +0 +{<0.39.0>,<0.27.0>} +4> {ok, D} = file:open("/tmp/tmp.data",[write]). +{trace,#Port<0.486>,<0.40.0>} +{trace,<0.40.0>,<0.21.0>} +{trace,#Port<0.487>,<0.4.0>} +{trace,#Port<0.488>,<0.4.0>} +{trace,#Port<0.489>,<0.4.0>} +{trace,#Port<0.490>,<0.4.0>} +{ok,<0.40.0>} +{trace,<0.41.0>,<0.27.0>} +5> + </pre> + <p>erl_msg_tracer.erl</p> + <pre> +-module(erl_msg_tracer). + +-export([enabled/3, trace/6, load/0]). + +load() -> + erlang:load_nif("erl_msg_tracer", []). + +enabled(_, _, _) -> + error. + +trace(_, _, _,_, _, _) -> + error. + </pre> + <p>erl_msg_tracer.c</p> + <pre> +#include "erl_nif.h" + +/* NIF interface declarations */ +static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info); +static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info); +static void unload(ErlNifEnv* env, void* priv_data); + +/* The NIFs: */ +static ERL_NIF_TERM enabled(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); +static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); + +static ErlNifFunc nif_funcs[] = { + {"enabled", 3, enabled}, + {"trace", 6, trace} +}; + +ERL_NIF_INIT(erl_msg_tracer, nif_funcs, load, NULL, upgrade, unload) + +static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info) +{ + *priv_data = NULL; + return 0; +} + +static void unload(ErlNifEnv* env, void* priv_data) +{ + +} + +static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, + ERL_NIF_TERM load_info) +{ + if (*old_priv_data != NULL || *priv_data != NULL) { + return -1; /* Don't know how to do that */ + } + if (load(env, priv_data, load_info)) { + return -1; + } + return 0; +} + +/* + * argv[0]: Trace Tag + * argv[1]: TracerState + * argv[2]: Tracee + */ +static ERL_NIF_TERM enabled(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + ErlNifPid to_pid; + if (enif_get_local_pid(env, argv[1], &to_pid)) + if (!enif_is_process_alive(env, &to_pid)) + /* tracer is dead so we should remove this trace point */ + return enif_make_atom(env, "remove"); + + /* Only generate trace for when tracer != tracee */ + if (enif_is_identical(argv[1], argv[2])) + return enif_make_atom(env, "discard"); + + /* Only trigger trace messages on 'send' */ + if (enif_is_identical(enif_make_atom(env, "send"), argv[0])) + return enif_make_atom(env, "trace"); + + /* Have to answer trace_status */ + if (enif_is_identical(enif_make_atom(env, "trace_status"), argv[0])) + return enif_make_atom(env, "trace"); + + return enif_make_atom(env, "discard"); +} + +/* + * argv[0]: Trace Tag, should only be 'send' + * argv[1]: TracerState, process to send {argv[2], argv[4]} to + * argv[2]: Tracee + * argv[3]: Message, ignored + * argv[4]: Recipient + * argv[5]: Options, ignored + */ +static ERL_NIF_TERM trace(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) +{ + ErlNifPid to_pid; + + if (enif_get_local_pid(env, argv[1], &to_pid)) { + ERL_NIF_TERM msg = enif_make_tuple3(env, enif_make_atom(env, "trace"), argv[2], argv[4]); + enif_send(env, &to_pid, NULL, msg); + } + + return enif_make_atom(env, "ok"); +} + </pre> + </section> +</erlref> diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index 350a8506f5..423ccdf98f 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2015</year> + <year>1996</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -2613,6 +2613,48 @@ os_prompt% </pre> </func> <func> + <name name="match_spec_test" arity="3"/> + <fsummary>Test that a match specification works</fsummary> + <desc> + <p> + This function is a utility to test a match_spec used in calls to + <seealso marker="stdlib:ets#select/2">ets:select/2</seealso> and + <seealso marker="#trace_pattern/3">erlang:trace_pattern/3</seealso>. + The function both tests MatchSpec for "syntactic" correctness and + runs the match_spec against the object. If the match_spec contains + errors, the tuple {error, Errors} is returned where Errors is a list + of natural language descriptions of what was wrong with the match_spec. + </p> + <p> + If the <c><anno>Type</anno></c> is <c>table</c> the object to match + against should be a tuple. The function then returns + {ok,Result,[],Warnings} where Result is what would have been the + result in a real ets:select/2 call or false if the match_spec does + not match the object tuple. + </p> + + <p> + If <c><anno>Type</anno></c> is <c>trace</c> the object to match + against should be a list. The function returns + {ok, Result, Flags, Warnings} where Result is <c>true</c> if a trace + message should be emitted, <c>false</c> if a trace message should not + be emitted or the message term to be appended to the trace message. + Flags is a list containing all the trace flags that will be enabled, + at the moment this is only <c>return_trace</c>. + </p> + + <p> + This is a useful debugging and test tool, especially when writing complicated + match specifications. + </p> + <p> + See also + <seealso marker="stdlib:ets#test_ms/2">ets:test_ms/2</seealso>. + </p> + </desc> + </func> + + <func> <name name="max" arity="2"/> <fsummary>Returns the largest of two terms.</fsummary> <desc> @@ -8347,22 +8389,47 @@ timestamp() -> <c><anno>How</anno> == false</c>) the trace flags in <c><anno>FlagList</anno></c> for the process or processes represented by - <c><anno>PidSpec</anno></c>.</p> - <p><c><anno>PidSpec</anno></c> is either a process identifier - (pid) for a local process, or one of the following atoms:</p> + <c><anno>PidPortSpec</anno></c>.</p> + <p><c><anno>PidPortSpec</anno></c> is either a process identifier + (pid) for a local process, a port identifier, + or one of the following atoms:</p> <taglist> + <tag><c>all</c></tag> + <item> + <p>All currently existing processes and ports and all that + will be created in the future.</p> + </item> + <tag><c>processes</c></tag> + <item> + <p>All currently existing processes and all that will be created in the future.</p> + </item> + <tag><c>ports</c></tag> + <item> + <p>All currently existing ports and all that will be created in the future.</p> + </item> <tag><c>existing</c></tag> <item> + <p>All currently existing processes and ports.</p> + </item> + <tag><c>existing_processes</c></tag> + <item> <p>All currently existing processes.</p> </item> + <tag><c>existing_ports</c></tag> + <item> + <p>All currently existing ports.</p> + </item> <tag><c>new</c></tag> <item> - <p>All processes that are created in the future.</p> + <p>All processes and ports that will be created in the future.</p> </item> - <tag><c>all</c></tag> + <tag><c>new_processes</c></tag> + <item> + <p>All processes that will be created in the future.</p> + </item> + <tag><c>new_ports</c></tag> <item> - <p>All currently existing processes and all processes that - are created in the future.</p> + <p>All ports that will be created in the future.</p> </item> </taglist> <p><c><anno>FlagList</anno></c> can contain any number of the @@ -8371,35 +8438,28 @@ timestamp() -> <taglist> <tag><c>all</c></tag> <item> - <p>Sets all trace flags except <c>{tracer, Tracer}</c> and + <p>Sets all trace flags except <c>tracer</c> and <c>cpu_timestamp</c>, which are in their nature different than the others.</p> </item> <tag><c>send</c></tag> <item> <p>Traces sending of messages.</p> - <p>Message tags: <c>send</c> and - <c>send_to_non_existing_process</c>.</p> + <p>Message tags: <c><seealso marker="#trace_3_trace_messages_send">send</seealso></c> and + <c><seealso marker="#trace_3_trace_messages_send_to_non_existing_process">send_to_non_existing_process</seealso></c>.</p> </item> <tag><c>'receive'</c></tag> <item> <p>Traces receiving of messages.</p> - <p>Message tags: <c>'receive'</c>.</p> + <p>Message tags: <c><seealso marker="#trace_3_trace_messages_receive">'receive'</seealso></c>.</p> </item> - <tag><c>procs</c></tag> - <item> - <p>Traces process-related events.</p> - <p>Message tags: <c>spawn</c>, <c>exit</c>, - <c>register</c>, <c>unregister</c>, <c>link</c>, - <c>unlink</c>, <c>getting_linked</c>, and - <c>getting_unlinked</c>.</p> - </item> - <tag><c>call</c></tag> +<tag><c>call</c></tag> <item> <p>Traces certain function calls. Specify which function calls to trace by calling <seealso marker="#trace_pattern/3">erlang:trace_pattern/3</seealso>.</p> - <p>Message tags: <c>call</c> and <c>return_from</c>.</p> + <p>Message tags: <c><seealso marker="#trace_3_trace_messages_call">call</seealso></c> and + <c><seealso marker="#trace_3_trace_messages_return_from">return_from</seealso></c>.</p> </item> <tag><c>silent</c></tag> <item> @@ -8417,8 +8477,9 @@ timestamp() -> specification function <c>{silent,Bool}</c>, giving a high degree of control of which functions with which arguments that trigger the trace.</p> - <p>Message tags: <c>call</c>, <c>return_from</c>, and - <c>return_to</c>. Or rather, the absence of.</p> + <p>Message tags: <c><seealso marker="#trace_3_trace_messages_call">call</seealso></c>, + <c><seealso marker="#trace_3_trace_messages_return_from">return_from</seealso></c>, and + <c><seealso marker="#trace_3_trace_messages_return_to">return_to</seealso></c>. Or rather, the absence of.</p> </item> <tag><c>return_to</c></tag> <item> @@ -8439,23 +8500,63 @@ timestamp() -> <p>To get trace messages containing return values from functions, use the <c>{return_trace}</c> match specification action instead.</p> - <p>Message tags: <c>return_to</c>.</p> + <p>Message tags: <c><seealso marker="#trace_3_trace_messages_return_to">return_to</seealso></c>.</p> + </item> + <tag><c>procs</c></tag> + <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>, + <c><seealso marker="#trace_3_trace_messages_link">link</seealso></c>, + <c><seealso marker="#trace_3_trace_messages_unlink">unlink</seealso></c>, + <c><seealso marker="#trace_3_trace_messages_getting_linked">getting_linked</seealso></c>, and + <c><seealso marker="#trace_3_trace_messages_getting_unlinked">getting_unlinked</seealso></c>.</p> + </item> + <tag><c>ports</c></tag> + <item> + <p>Traces port-related events.</p> + <p>Message tags: <c><seealso marker="#trace_3_trace_messages_open">open</seealso></c>, + <c><seealso marker="#trace_3_trace_messages_closed">closed</seealso></c>, + <c><seealso marker="#trace_3_trace_messages_register">register</seealso></c>, + <c><seealso marker="#trace_3_trace_messages_unregister">unregister</seealso></c>, + <c><seealso marker="#trace_3_trace_messages_getting_linked">getting_linked</seealso></c>, and + <c><seealso marker="#trace_3_trace_messages_getting_unlinked">getting_unlinked</seealso></c>.</p> </item> <tag><c>running</c></tag> <item> <p>Traces scheduling of processes.</p> - <p>Message tags: <c>in</c> and <c>out</c>.</p> + <p>Message tags: <c><seealso marker="#trace_3_trace_messages_in_proc">in</seealso></c> and + <c><seealso marker="#trace_3_trace_messages_out_proc">out</seealso></c>.</p> </item> <tag><c>exiting</c></tag> <item> <p>Traces scheduling of exiting processes.</p> - <p>Message tags: <c>in_exiting</c>, <c>out_exiting</c>, and - <c>out_exited</c>.</p> + <p>Message tags: <c><seealso marker="#trace_3_trace_messages_in_exiting_proc">in_exiting</seealso></c>, + <c><seealso marker="#trace_3_trace_messages_out_exiting_proc">out_exiting</seealso></c>, and + <c><seealso marker="#trace_3_trace_messages_out_exited_proc">out_exited</seealso></c>.</p> + </item> + <tag><c>running_procs</c></tag> + <item> + <p>Traces scheduling of processes just like <c>running</c>. + However this option also includes schedule events when the + process executes within the context of a port without + being scheduled out itself.</p> + <p>Message tags: <c><seealso marker="#trace_3_trace_messages_in_proc">in</seealso></c> and + <c><seealso marker="#trace_3_trace_messages_out_proc">out</seealso></c>.</p> + </item> + <tag><c>running_ports</c></tag> + <item> + <p>Traces scheduling of ports.</p> + <p>Message tags: <c><seealso marker="#trace_3_trace_messages_in_port">in</seealso></c> and + <c><seealso marker="#trace_3_trace_messages_out_port">out</seealso></c>.</p> </item> <tag><c>garbage_collection</c></tag> <item> <p>Traces garbage collections of processes.</p> - <p>Message tags: <c>gc_start</c> and <c>gc_end</c>.</p> + <p>Message tags: <c><seealso marker="#trace_3_trace_messages_gc_start">gc_start</seealso></c> and <c><seealso marker="#trace_3_trace_messages_gc_end">gc_end</seealso></c>.</p> </item> <tag><c>timestamp</c></tag> <item> @@ -8470,8 +8571,8 @@ timestamp() -> in CPU time, not wall clock time. That is, <c>cpu_timestamp</c> will not be used if <c>monotonic_timestamp</c>, or <c>strict_monotonic_timestamp</c> is enabled. - Only allowed with <c>PidSpec==all</c>. If the host - machine OS does not support high-resolution + Only allowed with <c><anno>PidPortSpec</anno>==all</c>. If the + host machine OS does not support high-resolution CPU time measurements, <c>trace/3</c> exits with <c>badarg</c>. Notice that most OS do not synchronize this value across cores, so be prepared @@ -8483,8 +8584,8 @@ timestamp() -> <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang monotonic time</seealso> time-stamp in all trace messages. The time-stamp (Ts) has the same format and value as produced by - <c>erlang:monotonic_time(nano_seconds)</c>. This flag overrides - the <c>cpu_timestamp</c> flag.</p> + <c><seealso marker="#monotonic_time-1">erlang:monotonic_time(nano_seconds)</seealso></c>. + This flag overrides the <c>cpu_timestamp</c> flag.</p> </item> <tag><c>strict_monotonic_timestamp</c></tag> <item> @@ -8493,9 +8594,9 @@ timestamp() -> monotonic time</seealso> and a monotonically increasing integer in all trace messages. The time-stamp (Ts) has the same format and value as produced by - <c>{erlang:monotonic_time(nano_seconds), - erlang:unique_integer([monotonic])}</c>. This flag overrides - the <c>cpu_timestamp</c> flag.</p> + <c>{<seealso marker="#monotonic_time-1">erlang:monotonic_time(nano_seconds)</seealso>, + <seealso marker="#unique_integer-1">erlang:unique_integer([monotonic])</seealso>}</c>. + This flag overrides the <c>cpu_timestamp</c> flag.</p> </item> <tag><c>arity</c></tag> <item> @@ -8529,12 +8630,20 @@ timestamp() -> <item> <p>Specifies where to send the trace messages. <c>Tracer</c> must be the process identifier of a local process - or the port identifier - of a local port. If this flag is not given, trace - messages are sent to the process that called - <c>erlang:trace/3</c>.</p> + or the port identifier of a local port.</p> + </item> + <tag><c>{tracer, TracerModule, TracerState}</c></tag> + <item> + <p>Specifies that a tracer module should be called + instead of sending a trace message. The tracer module + can then ignore or change the trace message. For more details + on how to write a tracer module see <seealso marker="erl_tracer"> + erl_tracer</seealso> + </p> </item> </taglist> + <p>If no <c>tracer</c> is given, the calling process + will be receiving all of the trace messages</p> <p>The effect of combining <c>set_on_first_link</c> with <c>set_on_link</c> is the same as having <c>set_on_first_link</c> alone. Likewise for @@ -8555,21 +8664,36 @@ timestamp() -> the other one will become active.</p> <marker id="trace_3_trace_messages"></marker> <taglist> - <tag><c>{trace, Pid, 'receive', Msg}</c></tag> - <item> - <p>When <c>Pid</c> receives message <c>Msg</c>.</p> - </item> - <tag><c>{trace, Pid, send, Msg, To}</c></tag> + <tag> + <marker id="trace_3_trace_messages_send"></marker> + <c>{trace, PidPort, send, Msg, To}</c> + </tag> <item> - <p>When <c>Pid</c> sends message <c>Msg</c> to + <p>When <c>PidPort</c> sends message <c>Msg</c> to process <c>To</c>.</p> </item> - <tag><c>{trace, Pid, send_to_non_existing_process, Msg, To}</c></tag> + <tag> + <marker id="trace_3_trace_messages_send_to_non_existing_process"></marker> + <c>{trace, PidPort, send_to_non_existing_process, Msg, To}</c> + </tag> <item> - <p>When <c>Pid</c> sends message <c>Msg</c> to + <p>When <c>PidPort</c> sends message <c>Msg</c> to the non-existing process <c>To</c>.</p> </item> - <tag><c>{trace, Pid, call, {M, F, Args}}</c></tag> + <tag> + <marker id="trace_3_trace_messages_receive"></marker> + <c>{trace, PidPort, 'receive', Msg}</c> + </tag> + <item> + <p>When <c>PidPort</c> receives message <c>Msg</c>. + If <c>Msg</c> is set to timeout, then a receive + statement may have timedout, or the process received + a message with the payload <c>timeout</c>.</p> + </item> + <tag> + <marker id="trace_3_trace_messages_call"></marker> + <c>{trace, Pid, call, {M, F, Args}}</c> + </tag> <item> <p>When <c>Pid</c> calls a traced function. The return values of calls are never supplied, only the call and its @@ -8578,7 +8702,10 @@ timestamp() -> change the contents of this message, so that <c>Arity</c> is specified instead of <c>Args</c>.</p> </item> - <tag><c>{trace, Pid, return_to, {M, F, Arity}}</c></tag> + <tag> + <marker id="trace_3_trace_messages_return_to"></marker> + <c>{trace, Pid, return_to, {M, F, Arity}}</c> + </tag> <item> <p>When <c>Pid</c> returns <em>to</em> the specified function. This trace message is sent if both @@ -8590,73 +8717,172 @@ timestamp() -> (that is, the functions match specification matched, and <c>{message, false}</c> was not an action).</p> </item> - <tag><c>{trace, Pid, return_from, {M, F, Arity}, ReturnValue}</c></tag> + <tag> + <marker id="trace_3_trace_messages_return_from"></marker> + <c>{trace, Pid, return_from, {M, F, Arity}, ReturnValue}</c> + </tag> <item> <p>When <c>Pid</c> returns <em>from</em> the specified function. This trace message is sent if flag <c>call</c> is set, and the function has a match specification with a <c>return_trace</c> or <c>exception_trace</c> action.</p> </item> - <tag><c>{trace, Pid, exception_from, {M, F, Arity}, {Class, Value}}</c></tag> + <tag> + <marker id="trace_3_trace_messages_exception_from"></marker> + <c>{trace, Pid, exception_from, {M, F, Arity}, {Class, Value}}</c> + </tag> <item> <p>When <c>Pid</c> exits <em>from</em> the specified function because of an exception. This trace message is sent if flag <c>call</c> is set, and the function has a match specification with an <c>exception_trace</c> action.</p> </item> - <tag><c>{trace, Pid, spawn, Pid2, {M, F, Args}}</c></tag> + <tag> + <marker id="trace_3_trace_messages_spawn"></marker> + <c>{trace, Pid, spawn, Pid2, {M, F, Args}}</c> + </tag> <item> <p>When <c>Pid</c> spawns a new 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><c>{trace, Pid, exit, Reason}</c></tag> + <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> <item> <p>When <c>Pid</c> exits with reason <c>Reason</c>.</p> </item> - <tag><c>{trace, Pid, link, Pid2}</c></tag> + <tag> + <marker id="trace_3_trace_messages_register"></marker> + <c>{trace, PidPort, register, RegName}</c> + </tag> + <item> + <p>When <c>PidPort</c> gets the name <c>RegName</c> registered.</p> + </item> + <tag> + <marker id="trace_3_trace_messages_unregister"></marker> + <c>{trace, PidPort, unregister, RegName}</c> + </tag> + <item> + <p>When <c>PidPort</c> gets the name <c>RegName</c> unregistered. + This is done automatically when a registered + process or port exits.</p> + </item> + <tag> + <marker id="trace_3_trace_messages_link"></marker> + <c>{trace, Pid, link, Pid2}</c> + </tag> <item> <p>When <c>Pid</c> links to a process <c>Pid2</c>.</p> </item> - <tag><c>{trace, Pid, unlink, Pid2}</c></tag> + <tag> + <marker id="trace_3_trace_messages_unlink"></marker> + <c>{trace, Pid, unlink, Pid2}</c> + </tag> <item> <p>When <c>Pid</c> removes the link from a process <c>Pid2</c>.</p> </item> - <tag><c>{trace, Pid, getting_linked, Pid2}</c></tag> + <tag> + <marker id="trace_3_trace_messages_getting_linked"></marker> + <c>{trace, PidPort, getting_linked, Pid2}</c> + </tag> <item> - <p>When <c>Pid</c> gets linked to a process <c>Pid2</c>.</p> + <p>When <c>PidPort</c> gets linked to a process <c>Pid2</c>.</p> </item> - <tag><c>{trace, Pid, getting_unlinked, Pid2}</c></tag> + <tag> + <marker id="trace_3_trace_messages_getting_unlinked"></marker> + <c>{trace, PidPort, getting_unlinked, Pid2}</c> + </tag> <item> - <p>When <c>Pid</c> gets unlinked from a process <c>Pid2</c>.</p> + <p>When <c>PidPort</c> gets unlinked from a process <c>Pid2</c>.</p> </item> - <tag><c>{trace, Pid, register, RegName}</c></tag> + <tag> + <marker id="trace_3_trace_messages_exit"></marker> + <c>{trace, Pid, exit, Reason}</c> + </tag> <item> - <p>When <c>Pid</c> gets the name <c>RegName</c> registered.</p> + <p>When <c>Pid</c> exits with reason <c>Reason</c>.</p> </item> - <tag><c>{trace, Pid, unregister, RegName}</c></tag> + <tag> + <marker id="trace_3_trace_messages_open"></marker> + <c>{trace, Port, open, Pid, Driver}</c> + </tag> <item> - <p>When <c>Pid</c> gets the name <c>RegName</c> unregistered. - This is done automatically when a registered - process exits.</p> + <p>When <c>Pid</c> opens a new port <c>Port</c> with + the running the <c>Driver</c>.</p> + <p><c>Driver</c> is the name of the driver as an atom.</p> + </item> + <tag> + <marker id="trace_3_trace_messages_closed"></marker> + <c>{trace, Port, closed, Reason}</c> + </tag> + <item> + <p>When <c>Port</c> closed with <c>Reason</c>.</p> </item> - <tag><c>{trace, Pid, in, {M, F, Arity} | 0}</c></tag> + <tag> + <marker id="trace_3_trace_messages_in_proc"></marker> + <marker id="trace_3_trace_messages_in_exiting_proc"></marker> + <c>{trace, Pid, in | in_exiting, {M, F, Arity} | 0}</c> + </tag> <item> <p>When <c>Pid</c> is scheduled to run. The process runs in function <c>{M, F, Arity}</c>. On some rare occasions, the current function cannot be determined, then the last element is <c>0</c>.</p> </item> - <tag><c>{trace, Pid, out, {M, F, Arity} | 0}</c></tag> + <tag> + <marker id="trace_3_trace_messages_out_proc"></marker> + <marker id="trace_3_trace_messages_out_exiting_proc"></marker> + <marker id="trace_3_trace_messages_out_exited_proc"></marker> + <c>{trace, Pid, out | out_exiting | out_exited, {M, F, Arity} | 0}</c> + </tag> <item> <p>When <c>Pid</c> is scheduled out. The process was running in function {M, F, Arity}. On some rare occasions, the current function cannot be determined, then the last element is <c>0</c>.</p> </item> - <tag><c>{trace, Pid, gc_start, Info}</c></tag> + <tag> + <marker id="trace_3_trace_messages_in_port"></marker> + <c>{trace, Port, in, Command | 0}</c> + </tag> + <item> + <p>When <c>Port</c> is scheduled to run. <c>Command</c> is the + first thing the port will execute, it may however run several + commands before being scheduled out. On some rare + occasions, the current function cannot be determined, + then the last element is <c>0</c>.</p> + <p>The possible commands are: <c>call | close | command | connect | control | flush | info | link | open | unlink</c></p> + </item> + <tag> + <marker id="trace_3_trace_messages_out_port"></marker> + <c>{trace, Port, out, Command | 0}</c> + </tag> + <item> + <p>When <c>Port</c> is scheduled out. The last command run + was <c>Command</c>. On some rare occasions, + the current function cannot be determined, then the last + element is <c>0</c>. <c>Command</c> can contain the same + commands as <c>in</c> + </p> + </item> + <tag> + <marker id="trace_3_trace_messages_gc_start"></marker> + <c>{trace, Pid, gc_start, Info}</c> + </tag> <item> <marker id="gc_start"></marker> <p>Sent when garbage collection is about to be started. @@ -8698,7 +8924,10 @@ timestamp() -> </taglist> <p>All sizes are in words.</p> </item> - <tag><c>{trace, Pid, gc_end, Info}</c></tag> + <tag> + <marker id="trace_3_trace_messages_gc_end"></marker> + <c>{trace, Pid, gc_end, Info}</c> + </tag> <item> <p>Sent when garbage collection is finished. <c>Info</c> contains the same kind of list as in message <c>gc_start</c>, @@ -8706,18 +8935,18 @@ timestamp() -> garbage collection.</p> </item> </taglist> - <p>If the tracing process dies, the flags are silently - removed.</p> - <p>Only one process can trace a particular process. Therefore, + <p>If the tracing process/port dies or the tracer module returns + <c>remove</c>, the flags are silently removed.</p> + <p>Each process can only be traced by one tracer. Therefore, attempts to trace an already traced process fail.</p> <p>Returns: A number indicating the number of processes that - matched <c><anno>PidSpec</anno></c>. - If <c><anno>PidSpec</anno></c> is a process + matched <c><anno>PidPortSpec</anno></c>. + If <c><anno>PidPortSpec</anno></c> is a process identifier, the return value is <c>1</c>. - If <c><anno>PidSpec</anno></c> + If <c><anno>PidPortSpec</anno></c> is <c>all</c> or <c>existing</c>, the return value is - the number of processes running, excluding tracer processes. - If <c><anno>PidSpec</anno></c> is <c>new</c>, the return value is + the number of processes running. + If <c><anno>PidPortSpec</anno></c> is <c>new</c>, the return value is <c>0</c>.</p> <p>Failure: <c>badarg</c> if the specified arguments are not supported. For example, <c>cpu_timestamp</c> is not @@ -8729,7 +8958,11 @@ timestamp() -> <name name="trace_delivered" arity="1"/> <fsummary>Notification when trace has been delivered.</fsummary> <desc> - <p>The delivery of trace messages is dislocated on the time-line + <p>The delivery of trace messages (generated by + <seealso marker="#trace/3"><c>erlang:trace/3</c></seealso>, + <seealso marker="kernel:seq_trace"><c>seq_trace</c></seealso> or + <seealso marker="#system_profile/2"><c>erlang:system_profile/2</c></seealso>) + is dislocated on the time-line compared to other events in the system. If you know that <c><anno>Tracee</anno></c> has passed some specific point in its execution, @@ -8750,13 +8983,16 @@ timestamp() -> has not been traced by someone, but if this is the case, <em>no</em> trace messages have been delivered when the <c>trace_delivered</c> message arrives.</p> - <p>Notice that that <c><anno>Tracee</anno></c> must refer + <p>Notice that <c><anno>Tracee</anno></c> must refer to a process currently, or previously existing on the same node as the caller of <c>erlang:trace_delivered(<anno>Tracee</anno>)</c> resides on. The special <c><anno>Tracee</anno></c> atom <c>all</c> - denotes all processes - that currently are traced in the node.</p> + denotes all processes that currently are traced in the node.</p> + <p>When used together with an <seealso marker="#erl_tracer"> + Tracer Module</seealso> any message sent in the trace callback + is guaranteed to have reached it's recipient before the + <c>trace_delivered</c> message is sent.</p> <p>Example: Process <c>A</c> is <c><anno>Tracee</anno></c>, port <c>B</c> is tracer, and process <c>C</c> is the port owner of <c>B</c>. <c>C</c> wants to close <c>B</c> when @@ -8779,12 +9015,15 @@ timestamp() -> <type name="trace_info_flag"/> <type name="trace_match_spec"/> <desc> - <p>Returns trace information about a process or function.</p> - <p>To get information about a process, - <c><anno>PidOrFunc</anno></c> is to - be a process identifier (pid) or the atom <c>new</c>. - The atom <c>new</c> means that the default trace state for - processes to be created is returned.</p> + <p>Returns trace information about a port, process or function.</p> + <p>To get information about a port or process, + <c><anno>PidPortOrFunc</anno></c> is to + be a process identifier (pid), port identifier or one of + the atoms <c>new</c>, <c>new_processes</c>, <c>new_ports</c>. + The atom <c>new</c> or <c>new_processes</c> means that the default trace + state for processes to be created is returned. The atom <c>new_ports</c> + means that the default trace state for ports to be created is returned. + </p> <p>The following <c>Item</c>s are valid:</p> <taglist> <tag><c>flags</c></tag> @@ -8794,19 +9033,22 @@ timestamp() -> traces are enabled, and one or more of the followings atoms if traces are enabled: <c>send</c>, <c>'receive'</c>, <c>set_on_spawn</c>, <c>call</c>, - <c>return_to</c>, <c>procs</c>, <c>set_on_first_spawn</c>, - <c>set_on_link</c>, <c>running</c>, + <c>return_to</c>, <c>procs</c>, <c>ports</c>, <c>set_on_first_spawn</c>, + <c>set_on_link</c>, <c>running</c>, <c>running_procs</c>, + <c>running_ports</c>, <c>silent</c>, <c>exiting</c> + <c>monotonic_timestamp</c>, <c>strict_monotonic_timestamp</c>, <c>garbage_collection</c>, <c>timestamp</c>, and <c>arity</c>. The order is arbitrary.</p> </item> <tag><c>tracer</c></tag> <item> - <p>Returns the identifier for process or port tracing this + <p>Returns the identifier for process, port or a tuple containing + the tracer module and tracer state tracing this process. If this process is not being traced, the return value is <c>[]</c>.</p> </item> </taglist> - <p>To get information about a function, <c>PidOrFunc</c> is to + <p>To get information about a function, <c><anno>PidPortOrFunc</anno></c> is to be the three-element tuple <c>{Module, Function, Arity}</c> or the atom <c>on_load</c>. No wild cards are allowed. Returns <c>undefined</c> if the function does not exist, or @@ -8830,8 +9072,8 @@ timestamp() -> </item> <tag><c>meta</c></tag> <item> - <p>Returns the meta-trace tracer process or port for this - function, if it has one. If the function is not + <p>Returns the meta-trace tracer process, port or trace module + for this function, if it has one. If the function is not meta-traced, the returned value is <c>false</c>. If the function is meta-traced but has once detected that the tracer process is invalid, the returned value is [].</p> @@ -8874,7 +9116,7 @@ timestamp() -> <c>Value</c> is the requested information as described earlier. If a pid for a dead process was given, or the name of a non-existing function, <c>Value</c> is <c>undefined</c>.</p> - <p>If <c><anno>PidOrFunc</anno></c> is <c>on_load</c>, the information + <p>If <c><anno>PidPortOrFunc</anno></c> is <c>on_load</c>, the information returned refers to the default value for code that will be loaded.</p> </desc> @@ -8999,13 +9241,12 @@ timestamp() -> the process, a <c>return_to</c> message is also sent when this function returns to its caller.</p> </item> - <tag><c>meta | {meta, <anno>Pid</anno>}</c></tag> + <tag><c>meta | {meta, <anno>Pid</anno>} | {meta, <anno>TracerModule</anno>, <anno>TracerState</anno>}</c> + </tag> <item> <p>Turns on or off meta-tracing for all types of function - calls. Trace messages are sent to the tracer process - or port <c><anno>Pid</anno></c> whenever any of the specified - functions are called, regardless of how they are called. - If no <c><anno>Pid</anno></c> is specified, + calls. Trace messages are sent to the tracer whenever any of + the specified functions are called. If no tracer is specified, <c>self()</c> is used as a default tracer process.</p> <p>Meta-tracing traces all processes and does not care about the process trace flags set by <c>trace/3</c>, @@ -9013,7 +9254,7 @@ timestamp() -> <c>[call, timestamp]</c>.</p> <p>The match specification function <c>{return_trace}</c> works with meta-trace and sends its trace message to the - same tracer process.</p> + same tracer.</p> </item> <tag><c>call_count</c></tag> <item> diff --git a/erts/doc/src/erlc.xml b/erts/doc/src/erlc.xml index 9fc5864413..a64927fec2 100644 --- a/erts/doc/src/erlc.xml +++ b/erts/doc/src/erlc.xml @@ -4,7 +4,7 @@ <comref> <header> <copyright> - <year>1997</year><year>2013</year> + <year>1997</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/erlsrv.xml b/erts/doc/src/erlsrv.xml index ccb8b2dd76..fb00444aa4 100644 --- a/erts/doc/src/erlsrv.xml +++ b/erts/doc/src/erlsrv.xml @@ -4,7 +4,7 @@ <comref> <header> <copyright> - <year>1998</year><year>2013</year> + <year>1998</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml index 0965f9b49c..05be35e0af 100644 --- a/erts/doc/src/erts_alloc.xml +++ b/erts/doc/src/erts_alloc.xml @@ -4,7 +4,7 @@ <cref> <header> <copyright> - <year>2002</year><year>2015</year> + <year>2002</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/inet_cfg.xml b/erts/doc/src/inet_cfg.xml index 5caf232a62..027fe600d7 100644 --- a/erts/doc/src/inet_cfg.xml +++ b/erts/doc/src/inet_cfg.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2004</year><year>2013</year> + <year>2004</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/init.xml b/erts/doc/src/init.xml index 2a33096d04..84a5aea335 100644 --- a/erts/doc/src/init.xml +++ b/erts/doc/src/init.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2013</year> + <year>1996</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/match_spec.xml b/erts/doc/src/match_spec.xml index 08dad8cc10..3944f24f84 100644 --- a/erts/doc/src/match_spec.xml +++ b/erts/doc/src/match_spec.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1999</year><year>2013</year> + <year>1999</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -287,7 +287,7 @@ can <em>not</em> be one of the atoms <c><![CDATA[all]]></c>, <c><![CDATA[new]]></c> or <c><![CDATA[existing]]></c> (unless, of course, they are registered names). <c><![CDATA[P2]]></c> can <em>not</em> be <c><![CDATA[cpu_timestamp]]></c> nor - <c><![CDATA[{tracer,_}]]></c>. + <c><![CDATA[tracer]]></c>. Returns <c><![CDATA[true]]></c> and may only be used in the <c><![CDATA[MatchBody]]></c> part when tracing. </p> @@ -298,7 +298,7 @@ be either a process identifier or a registered name and is given as the first argument to the match_spec function. <c><![CDATA[P2]]></c> can <em>not</em> be <c><![CDATA[cpu_timestamp]]></c> nor - <c><![CDATA[{tracer,_}]]></c>. Returns + <c><![CDATA[tracer]]></c>. Returns <c><![CDATA[true]]></c> and may only be used in the <c><![CDATA[MatchBody]]></c> part when tracing. </p> @@ -308,11 +308,14 @@ disable list is applied first, but effectively all changes are applied atomically. The trace flags are the same as for <c><![CDATA[erlang:trace/3]]></c> not including - <c><![CDATA[cpu_timestamp]]></c> but including <c><![CDATA[{tracer,_}]]></c>. If a + <c><![CDATA[cpu_timestamp]]></c> but including <c><![CDATA[tracer]]></c>. If a tracer is specified in both lists, the tracer in the enable list takes precedence. If no tracer is specified the same tracer as the process executing the match spec is - used. With three parameters to this function the first is + used. When using a <seealso marker="erl_tracer">tracer module</seealso> + the module has to be loaded before the match specification is executed. + If it is not loaded the match will fail. + With three parameters to this function the first is either a process identifier or the registered name of a process to set trace flags on, the second is the disable list, and the third is the enable list. Returns @@ -525,7 +528,7 @@ </section> <section> - <title>Examples</title> + <title>ETS Examples</title> <p>Match an argument list of three where the first and third arguments are equal:</p> <code type="none"><![CDATA[ @@ -616,5 +619,44 @@ <p>The function <c><![CDATA[ets:test_ms/2]]></c> can be useful for testing complicated ets matches.</p> </section> + <section> + <title>Tracing Examples</title> + <p>Only generate trace message if trace control word is set to 1:</p> + <code type="none"><![CDATA[ +[{'_', + [{'==',{get_tcw},{const, 1}}], + []}] + ]]></code> + <p>Only generate trace message if there is a seq trace token:</p> + <code type="none"><![CDATA[ +[{'_', + [{'==',{is_seq_trace},{const, 1}}], + []}] + ]]></code> + <p>Remove 'silent' trace flag when first argument is 'verbose' + and add it when it is 'silent':</p> + <code type="none"><![CDATA[ +[{'$1', + [{'==',{hd, '$1'},verbose}], + [{trace, [silent],[]}]}, + {'$1', + [{'==',{hd, '$1'},silent}], + [{trace, [],[silent]}]}] + ]]></code> + <p>Add return_trace message if function is of arity 3:</p> + <code type="none"><![CDATA[ +[{'$1', + [{'==',{length, '$1'},3}], + [{return_trace}]}, + {'_',[],[]}] + ]]></code> + <p>Only generate trace message if function is of arity 3 and first argument is 'trace':</p> + <code type="none"><![CDATA[ +[{['trace','$2','$3'], + [], + []}, + {'_',[],[]}] + ]]></code> + </section> </chapter> diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml index acd816a81c..7501ccd9ce 100644 --- a/erts/doc/src/notes.xml +++ b/erts/doc/src/notes.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2004</year><year>2015</year> + <year>2004</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -32,6 +32,71 @@ <p>This document describes the changes made to the ERTS application.</p> +<section><title>Erts 7.3.1</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p> + <c>process_info(Pid, last_calls)</c> did not work for + <c>Pid /= self()</c>.</p> + <p> + Own Id: OTP-13418</p> + </item> + <item> + <p> + Make sure to create a crash dump when running out of + memory. This was accidentally removed in the erts-7.3 + release.</p> + <p> + Own Id: OTP-13419</p> + </item> + <item> + <p> + Schedulers could be woken by a premature timeout on + Linux. This premature wakeup was however harmless.</p> + <p> + Own Id: OTP-13420</p> + </item> + <item> + <p> + A process communicating with a port via one of the + <c>erlang:port_*</c> BIFs could potentially end up in an + inconsistent state if the port terminated during the + communication. When this occurred the process could later + block in a <c>receive</c> even though it had messages + matching in its message queue.</p> + <p> + This bug was introduced in erts version 5.10 (OTP R16A).</p> + <p> + Own Id: OTP-13424 Aux Id: OTP-10336 </p> + </item> + <item> + <p> + The reference count of a process structure could under + rare circumstances be erroneously managed. When this + happened invalid memory accesses occurred.</p> + <p> + Own Id: OTP-13446</p> + </item> + <item> + <p> + Fix race between <c>process_flag(trap_exit,true)</c> and + a received exit signal.</p> + <p> + A process could terminate due to exit signal even though + <c>process_flag(trap_exit,true)</c> had returned. A very + specific timing between call to <c>process_flag/2</c> and + exit signal from another scheduler was required for this + to happen.</p> + <p> + Own Id: OTP-13452</p> + </item> + </list> + </section> + +</section> + <section><title>Erts 7.3</title> <section><title>Fixed Bugs and Malfunctions</title> diff --git a/erts/doc/src/notes_history.xml b/erts/doc/src/notes_history.xml index 0886ae4039..0bc2ab1383 100644 --- a/erts/doc/src/notes_history.xml +++ b/erts/doc/src/notes_history.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2006</year><year>2013</year> + <year>2006</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/part.xml b/erts/doc/src/part.xml index 2f5eca93db..b2abfc62ca 100644 --- a/erts/doc/src/part.xml +++ b/erts/doc/src/part.xml @@ -4,7 +4,7 @@ <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>1996</year><year>2013</year> + <year>1996</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/part_notes.xml b/erts/doc/src/part_notes.xml index 83bb479715..e579b7635d 100644 --- a/erts/doc/src/part_notes.xml +++ b/erts/doc/src/part_notes.xml @@ -4,7 +4,7 @@ <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2004</year><year>2013</year> + <year>2004</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/part_notes_history.xml b/erts/doc/src/part_notes_history.xml index 055d1681d5..277683a2b5 100644 --- a/erts/doc/src/part_notes_history.xml +++ b/erts/doc/src/part_notes_history.xml @@ -4,7 +4,7 @@ <part xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>2006</year><year>2013</year> + <year>2006</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/ref_man.xml b/erts/doc/src/ref_man.xml index ac589f8cb5..e45402a397 100644 --- a/erts/doc/src/ref_man.xml +++ b/erts/doc/src/ref_man.xml @@ -4,7 +4,7 @@ <application xmlns:xi="http://www.w3.org/2001/XInclude"> <header> <copyright> - <year>1996</year><year>2013</year> + <year>1996</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -56,5 +56,6 @@ <xi:include href="driver_entry.xml"/> <xi:include href="erts_alloc.xml"/> <xi:include href="erl_nif.xml"/> + <xi:include href="erl_tracer.xml"/> </application> diff --git a/erts/doc/src/run_erl.xml b/erts/doc/src/run_erl.xml index faec3c68c1..6b0fef7c0a 100644 --- a/erts/doc/src/run_erl.xml +++ b/erts/doc/src/run_erl.xml @@ -4,7 +4,7 @@ <comref> <header> <copyright> - <year>1999</year><year>2013</year> + <year>1999</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/specs.xml b/erts/doc/src/specs.xml index 41a3984659..ed6be650e5 100644 --- a/erts/doc/src/specs.xml +++ b/erts/doc/src/specs.xml @@ -2,6 +2,7 @@ <specs xmlns:xi="http://www.w3.org/2001/XInclude"> <xi:include href="../specs/specs_erl_prim_loader.xml"/> <xi:include href="../specs/specs_erlang.xml"/> + <xi:include href="../specs/specs_erl_tracer.xml"/> <xi:include href="../specs/specs_init.xml"/> <xi:include href="../specs/specs_zlib.xml"/> </specs> diff --git a/erts/doc/src/start.xml b/erts/doc/src/start.xml index 386fbe6e88..adacf5b98d 100644 --- a/erts/doc/src/start.xml +++ b/erts/doc/src/start.xml @@ -4,7 +4,7 @@ <comref> <header> <copyright> - <year>1999</year><year>2013</year> + <year>1999</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/start_erl.xml b/erts/doc/src/start_erl.xml index 62610b43b0..243aeaa717 100644 --- a/erts/doc/src/start_erl.xml +++ b/erts/doc/src/start_erl.xml @@ -4,7 +4,7 @@ <comref> <header> <copyright> - <year>1998</year><year>2013</year> + <year>1998</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/tty.xml b/erts/doc/src/tty.xml index cd46d1203c..b2866c82cf 100644 --- a/erts/doc/src/tty.xml +++ b/erts/doc/src/tty.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1996</year><year>2013</year> + <year>1996</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/werl.xml b/erts/doc/src/werl.xml index 9e7ad584eb..1a3cb6f502 100644 --- a/erts/doc/src/werl.xml +++ b/erts/doc/src/werl.xml @@ -4,7 +4,7 @@ <comref> <header> <copyright> - <year>1998</year><year>2013</year> + <year>1998</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/erts/doc/src/zlib.xml b/erts/doc/src/zlib.xml index 0a641346d9..861661043f 100644 --- a/erts/doc/src/zlib.xml +++ b/erts/doc/src/zlib.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>2005</year><year>2013</year> + <year>2005</year><year>2016</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> |