aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/doc/src/erl_tracer.xml62
-rw-r--r--erts/doc/src/erlang.xml4
-rw-r--r--erts/doc/src/erts_alloc.xml2
-rw-r--r--erts/doc/src/match_spec.xml149
-rw-r--r--erts/emulator/beam/beam_load.c1
-rw-r--r--erts/emulator/beam/binary.c2
-rw-r--r--erts/emulator/beam/erl_alloc.c30
-rw-r--r--erts/emulator/beam/erl_bif_re.c8
-rw-r--r--erts/emulator/beam/erl_message.h4
-rw-r--r--erts/emulator/beam/erl_nif.c28
-rw-r--r--erts/emulator/beam/erl_process.h4
-rw-r--r--erts/emulator/beam/erl_unicode.c58
-rw-r--r--erts/emulator/beam/global.h2
-rw-r--r--erts/emulator/hipe/hipe_mode_switch.c27
-rw-r--r--erts/emulator/test/alloc_SUITE.erl22
-rw-r--r--erts/emulator/test/port_trace_SUITE.erl44
-rw-r--r--erts/emulator/test/port_trace_SUITE_data/echo_drv.c36
-rw-r--r--erts/emulator/test/time_SUITE.erl77
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin55780 -> 55732 bytes
-rw-r--r--erts/preloaded/src/erl_prim_loader.erl6
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src3
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE_data/einode.c3
-rw-r--r--lib/kernel/test/erl_prim_loader_SUITE.erl24
-rw-r--r--lib/os_mon/src/memsup.erl2
-rw-r--r--lib/os_mon/test/memsup_SUITE.erl14
-rw-r--r--lib/public_key/test/pbe_SUITE.erl7
-rw-r--r--lib/public_key/test/pkits_SUITE.erl2
-rw-r--r--lib/public_key/test/public_key_SUITE.erl53
-rw-r--r--lib/runtime_tools/c_src/trace_ip_drv.c3
-rw-r--r--lib/runtime_tools/doc/src/dbg.xml60
-rw-r--r--lib/stdlib/doc/src/ets.xml5
-rw-r--r--lib/wx/api_gen/gl_gen.erl14
-rw-r--r--lib/wx/c_src/wxe_helpers.cpp8
-rw-r--r--lib/wx/include/gl.hrl4
-rw-r--r--lib/wx/test/wx_class_SUITE.erl4
35 files changed, 500 insertions, 272 deletions
diff --git a/erts/doc/src/erl_tracer.xml b/erts/doc/src/erl_tracer.xml
index 7fd5512b33..d4c8bbad31 100644
--- a/erts/doc/src/erl_tracer.xml
+++ b/erts/doc/src/erl_tracer.xml
@@ -67,7 +67,7 @@
<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>
+ <seealso marker="#Module:trace/6">Module:trace/6</seealso>
</p>
</desc>
</datatype>
@@ -81,7 +81,7 @@
<datatype>
<name name="trace_opts" />
<desc>
- <p>The options for the tracee.
+ <p>The options for the tracee.</p>
<taglist>
<tag><c>timestamp</c></tag>
<item>If not set to <c>undefined</c>, the tracer has been requested to
@@ -93,7 +93,6 @@
<item>Set to a number if the scheduler id is to be included by the tracer.
Otherwise it is set to <c>undefined</c>.</item>
</taglist>
- </p>
</desc>
</datatype>
<datatype>
@@ -114,30 +113,30 @@
<p>The following functions
should be exported from a <c>erl_tracer</c> callback module.</p>
<taglist>
- <tag><seealso marker="#enabled"><c>Module:enabled/3</c></seealso></tag>
+ <tag><seealso marker="#Module:enabled/3"><c>Module:enabled/3</c></seealso></tag>
<item>Mandatory</item>
- <tag><seealso marker="#trace"><c>Module:trace/6</c></seealso></tag>
+ <tag><seealso marker="#Module:trace/6"><c>Module:trace/6</c></seealso></tag>
<item>Mandatory</item>
- <tag><seealso marker="#enabled_procs"><c>Module:enabled_procs/3</c></seealso></tag>
+ <tag><seealso marker="#Module:enabled_procs/3"><c>Module:enabled_procs/3</c></seealso></tag>
<item>Optional</item>
- <tag><seealso marker="#trace_procs"><c>Module:trace_procs/6</c></seealso></tag>
+ <tag><seealso marker="#Module:trace_procs/6"><c>Module:trace_procs/6</c></seealso></tag>
<item>Optional</item>
- <tag><seealso marker="#enabled_ports"><c>Module:enabled_ports/3</c></seealso></tag>
+ <tag><seealso marker="#Module:enabled_ports/3"><c>Module:enabled_ports/3</c></seealso></tag>
<item>Optional</item>
- <tag><seealso marker="#trace_ports"><c>Module:trace_ports/6</c></seealso></tag>
+ <tag><seealso marker="#Module:trace_ports/6"><c>Module:trace_ports/6</c></seealso></tag>
<item>Optional</item>
- <tag><seealso marker="#enabled_running_ports"><c>Module:enabled_running_ports/3</c></seealso></tag>
+ <tag><seealso marker="#Module:enabled_running_ports/3"><c>Module:enabled_running_ports/3</c></seealso></tag>
<item>Optional</item>
- <tag><seealso marker="#trace_running_ports"><c>Module:trace_running_ports/6</c></seealso></tag>
+ <tag><seealso marker="#Module:trace_running_ports/6"><c>Module:trace_running_ports/6</c></seealso></tag>
<item>Optional</item>
- <tag><seealso marker="#enabled_running_procs"><c>Module:enabled_running_procs/3</c></seealso></tag>
+ <tag><seealso marker="#Module:enabled_running_procs/3"><c>Module:enabled_running_procs/3</c></seealso></tag>
<item>Optional</item>
- <tag><seealso marker="#trace_running_procs"><c>Module:trace_running_procs/6</c></seealso></tag>
+ <tag><seealso marker="#Module:trace_running_procs/6"><c>Module:trace_running_procs/6</c></seealso></tag>
<item>Optional</item>
</taglist>
</section>
- <marker id="enabled"></marker>
+
<funcs>
<func>
<name>Module:enabled(TraceTag, TracerState, Tracee) -> Result</name>
@@ -166,7 +165,6 @@
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>
@@ -181,7 +179,7 @@
</type>
<desc>
<p>This callback will be called when a tracepoint is triggered and
- the <seealso marker="#enabled">Module:enabled/3</seealso>
+ the <seealso marker="#Module:enabled/3">Module:enabled/3</seealso>
callback returned <c>trace</c>. In it any side effects needed by
the tracer should be done. The tracepoint payload is located in
the <c>FirstTraceTerm</c> and <c>SecondTraceTerm</c>. The content
@@ -212,7 +210,6 @@
</desc>
</func>
- <marker id="enabled_procs"></marker>
<func>
<name>Module:enabled_procs(TraceTag, TracerState, Tracee) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -230,7 +227,6 @@
</desc>
</func>
- <marker id="trace_procs"></marker>
<func>
<name>Module:trace_procs(TraceTag, TracerState, Tracee, FirstTraceTerm, SecondTraceTerm, Opts) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -245,13 +241,12 @@
</type>
<desc>
<p>This callback will be called when a tracepoint is triggered and
- the <seealso marker="#enabled_procs">Module:enabled_procs/3</seealso>
+ the <seealso marker="#Module:enabled_procs/3">Module:enabled_procs/3</seealso>
callback returned <c>trace</c>.</p>
<p>If <c>trace_procs/6</c> is not defined <c>trace/6</c> will be called instead.</p>
</desc>
</func>
- <marker id="enabled_ports"></marker>
<func>
<name>Module:enabled_ports(TraceTag, TracerState, Tracee) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -269,7 +264,6 @@
</desc>
</func>
- <marker id="trace_ports"></marker>
<func>
<name>Module:trace_ports(TraceTag, TracerState, Tracee, FirstTraceTerm, SecondTraceTerm, Opts) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -284,13 +278,12 @@
</type>
<desc>
<p>This callback will be called when a tracepoint is triggered and
- the <seealso marker="#enabled_ports">Module:enabled_ports/3</seealso>
+ the <seealso marker="#Module:enabled_ports/3">Module:enabled_ports/3</seealso>
callback returned <c>trace</c>.</p>
<p>If <c>trace_ports/6</c> is not defined <c>trace/6</c> will be called instead.</p>
</desc>
</func>
- <marker id="enabled_running_procs"></marker>
<func>
<name>Module:enabled_running_procs(TraceTag, TracerState, Tracee) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -308,7 +301,6 @@
</desc>
</func>
- <marker id="trace_running_procs"></marker>
<func>
<name>Module:trace_running_procs(TraceTag, TracerState, Tracee, FirstTraceTerm, SecondTraceTerm, Opts) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -323,13 +315,12 @@
</type>
<desc>
<p>This callback will be called when a tracepoint is triggered and
- the <seealso marker="#enabled_running_procs">Module:enabled_running_procs/3</seealso>
+ the <seealso marker="#Module:enabled_running_procs/3">Module:enabled_running_procs/3</seealso>
callback returned <c>trace</c>.</p>
<p>If <c>trace_running_procs/6</c> is not defined <c>trace/6</c> will be called instead.</p>
</desc>
</func>
- <marker id="enabled_running_ports"></marker>
<func>
<name>Module:enabled_running_ports(TraceTag, TracerState, Tracee) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -347,7 +338,6 @@
</desc>
</func>
- <marker id="trace_running_ports"></marker>
<func>
<name>Module:trace_running_ports(TraceTag, TracerState, Tracee, FirstTraceTerm, SecondTraceTerm, Opts) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -362,13 +352,12 @@
</type>
<desc>
<p>This callback will be called when a tracepoint is triggered and
- the <seealso marker="#enabled_running_ports">Module:enabled_running_ports/3</seealso>
+ the <seealso marker="#Module:enabled_running_ports/3">Module:enabled_running_ports/3</seealso>
callback returned <c>trace</c>.</p>
<p>If <c>trace_running_ports/6</c> is not defined <c>trace/6</c> will be called instead.</p>
</desc>
</func>
- <marker id="enabled_call"></marker>
<func>
<name>Module:enabled_call(TraceTag, TracerState, Tracee) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -386,7 +375,6 @@
</desc>
</func>
- <marker id="trace_call"></marker>
<func>
<name>Module:trace_call(TraceTag, TracerState, Tracee, FirstTraceTerm, SecondTraceTerm, Opts) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -401,13 +389,12 @@
</type>
<desc>
<p>This callback will be called when a tracepoint is triggered and
- the <seealso marker="#enabled_call">Module:enabled_call/3</seealso>
+ the <seealso marker="#Module:enabled_call/3">Module:enabled_call/3</seealso>
callback returned <c>trace</c>.</p>
<p>If <c>trace_call/6</c> is not defined <c>trace/6</c> will be called instead.</p>
</desc>
</func>
- <marker id="enabled_send"></marker>
<func>
<name>Module:enabled_send(TraceTag, TracerState, Tracee) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -425,7 +412,6 @@
</desc>
</func>
- <marker id="trace_send"></marker>
<func>
<name>Module:trace_send(TraceTag, TracerState, Tracee, FirstTraceTerm, SecondTraceTerm, Opts) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -440,13 +426,12 @@
</type>
<desc>
<p>This callback will be called when a tracepoint is triggered and
- the <seealso marker="#enabled_send">Module:enabled_send/3</seealso>
+ the <seealso marker="#Module:enabled_send/3">Module:enabled_send/3</seealso>
callback returned <c>trace</c>.</p>
<p>If <c>trace_send/6</c> is not defined <c>trace/6</c> will be called instead.</p>
</desc>
</func>
- <marker id="enabled_receive"></marker>
<func>
<name>Module:enabled_receive(TraceTag, TracerState, Tracee) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -464,7 +449,6 @@
</desc>
</func>
- <marker id="trace_receive"></marker>
<func>
<name>Module:trace_receive(TraceTag, TracerState, Tracee, FirstTraceTerm, SecondTraceTerm, Opts) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -479,13 +463,12 @@
</type>
<desc>
<p>This callback will be called when a tracepoint is triggered and
- the <seealso marker="#enabled_receive">Module:enabled_receive/3</seealso>
+ the <seealso marker="#Module:enabled_receive/3">Module:enabled_receive/3</seealso>
callback returned <c>trace</c>.</p>
<p>If <c>trace_receive/6</c> is not defined <c>trace/6</c> will be called instead.</p>
</desc>
</func>
- <marker id="enabled_garbage_collection"></marker>
<func>
<name>Module:enabled_garbage_collection(TraceTag, TracerState, Tracee) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -503,7 +486,6 @@
</desc>
</func>
- <marker id="trace_garbage_collection"></marker>
<func>
<name>Module:trace_garbage_collection(TraceTag, TracerState, Tracee, FirstTraceTerm, SecondTraceTerm, Opts) -> Result</name>
<fsummary>Check if a trace event should be generated.</fsummary>
@@ -518,7 +500,7 @@
</type>
<desc>
<p>This callback will be called when a tracepoint is triggered and
- the <seealso marker="#enabled_garbage_collection">Module:enabled_garbage_collection/3</seealso>
+ the <seealso marker="#Module:enabled_garbage_collection/3">Module:enabled_garbage_collection/3</seealso>
callback returned <c>trace</c>.</p>
<p>If <c>trace_garbage_collection/6</c> is not defined <c>trace/6</c> will be called instead.</p>
</desc>
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 8724139c01..9287b32fec 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -5069,10 +5069,6 @@ os_prompt% </pre>
<p>Stops the execution of the calling process with an
exception of given class, reason, and call stack backtrace
(<em>stacktrace</em>).</p>
- <warning>
- <p>This BIF is intended for debugging. Avoid to use it in applications,
- unless you really know what you are doing.</p>
- </warning>
<p><c><anno>Class</anno></c> is <c>error</c>, <c>exit</c>, or
<c>throw</c>. So, if it were not for the stacktrace,
<c>erlang:raise(<anno>Class</anno>, <anno>Reason</anno>,
diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml
index 70775b9f0f..9aef1c0b1f 100644
--- a/erts/doc/src/erts_alloc.xml
+++ b/erts/doc/src/erts_alloc.xml
@@ -583,7 +583,7 @@
</taglist>
<p>The following flag is special for <c>exec_alloc</c>:</p>
<taglist>
- <tag><marker id="MIscs"/><c><![CDATA[+MXscs <size in MB>]]></c></tag>
+ <tag><marker id="MXscs"/><c><![CDATA[+MXscs <size in MB>]]></c></tag>
<item>
<c>exec_alloc</c> super carrier size (in MB). The amount of
<em>virtual</em> address space reserved for native executable code
diff --git a/erts/doc/src/match_spec.xml b/erts/doc/src/match_spec.xml
index 3944f24f84..7be3d15de6 100644
--- a/erts/doc/src/match_spec.xml
+++ b/erts/doc/src/match_spec.xml
@@ -33,21 +33,15 @@
<file>match_spec.xml</file>
</header>
<p>A "match specification" (match_spec) is an Erlang term describing a
- small "program" that will try to match something (either the
- parameters to a function as used in the <c><![CDATA[erlang:trace_pattern/2]]></c>
- BIF, or the objects in an ETS table.).
+ small "program" that will try to match something. It can be used
+ to either control tracing with
+ <seealso marker="erlang#trace_pattern/3">erlang:trace_pattern/3</seealso>
+ or to search for objects in an ETS table with for example
+ <seealso marker="stdlib:ets#select/2">ets:select/2</seealso>.
The match_spec in many ways works like a small function in Erlang, but is
interpreted/compiled by the Erlang runtime system to something much more
efficient than calling an Erlang function. The match_spec is also
very limited compared to the expressiveness of real Erlang functions.</p>
- <p>Match specifications are given to the BIF <c><![CDATA[erlang:trace_pattern/2]]></c> to
- execute matching of function arguments as well as to define some actions
- to be taken when the match succeeds (the <c><![CDATA[MatchBody]]></c> part). Match
- specifications can also be used in ETS, to specify objects to be
- returned from an <c><![CDATA[ets:select/2]]></c> call (or other select
- calls). The semantics and restrictions differ slightly when using
- match specifications for tracing and in ETS, the differences are
- defined in a separate paragraph below.</p>
<p>The most notable difference between a match_spec and an Erlang fun is
of course the syntax. Match specifications are Erlang terms, not
Erlang code. A match_spec also has a somewhat strange concept of
@@ -382,6 +376,51 @@
the pid() of the current process.</p>
</section>
+ <marker id="match_target"></marker>
+ <section>
+ <title>Match target</title>
+ <p>Each execution of a match specification is done against
+ a match target term. The format and content of the target term
+ depends on the context in which the match is done. The match
+ target for ETS is always a full table tuple. The match target
+ for call trace is always a list of all function arguments. The
+ match target for event trace depends on the event type, see
+ table below.</p>
+ <table>
+ <row>
+ <cell align="left" valign="middle">Context</cell>
+ <cell align="left" valign="middle">Type</cell>
+ <cell align="left" valign="middle">Match target</cell>
+ <cell align="left" valign="middle">Description</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">ETS</cell>
+ <cell align="left" valign="middle"></cell>
+ <cell align="left" valign="middle">{Key, Value1, Value2, ...}</cell>
+ <cell align="left" valign="middle">A table object</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">Trace</cell>
+ <cell align="left" valign="middle">call</cell>
+ <cell align="left" valign="middle">[Arg1, Arg2, ...]</cell>
+ <cell align="left" valign="middle">Function arguments</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">Trace</cell>
+ <cell align="left" valign="middle">send</cell>
+ <cell align="left" valign="middle">[Receiver, Message]</cell>
+ <cell align="left" valign="middle">Receiving process/port and message term</cell>
+ </row>
+ <row>
+ <cell align="left" valign="middle">Trace</cell>
+ <cell align="left" valign="middle">'receive'</cell>
+ <cell align="left" valign="middle">[Node, Sender, Message]</cell>
+ <cell align="left" valign="middle">Sending node, process/port and message term</cell>
+ </row>
+ <tcaption>Match target depending on context</tcaption>
+ </table>
+ </section>
+
<section>
<title>Variables and literals</title>
<p>Variables take the form <c><![CDATA['$<number>']]></c> where
@@ -396,10 +435,8 @@
<c><![CDATA[MatchCondition]]></c> parts, only variables bound previously may
be used. As a special case, in the
<c><![CDATA[MatchCondition/MatchBody]]></c> parts, the variable <c><![CDATA['$_']]></c>
- expands to the whole expression which matched the
- <c><![CDATA[MatchHead]]></c> (i.e., the whole parameter list to the possibly
- traced function or the whole matching object in the ets table)
- and the variable <c><![CDATA['$$']]></c> expands to a list
+ expands to the whole <seealso marker="#match_target">match target</seealso>
+ term and the variable <c><![CDATA['$$']]></c> expands to a list
of the values of all bound variables in order
(i.e. <c><![CDATA[['$1','$2', ...]]]></c>).
</p>
@@ -480,8 +517,8 @@
<p>For each tuple in the <c><![CDATA[MatchExpression]]></c> list and while no
match has succeeded:</p>
<list type="bulleted">
- <item>Match the <c><![CDATA[MatchHead]]></c> part against the arguments to the
- function,
+ <item>Match the <c><![CDATA[MatchHead]]></c> part against the
+ match target term,
binding the <c><![CDATA['$<number>']]></c> variables (much like in
<c><![CDATA[ets:match/2]]></c>).
If the <c><![CDATA[MatchHead]]></c> cannot match the arguments, the match fails.
@@ -522,13 +559,10 @@
term. The <c><![CDATA[ActionTerm]]></c>'s are executed as in an imperative
language, i.e. for their side effects. Functions with side effects
are also allowed when tracing.</p>
- <p>In ETS the match head is a <c><![CDATA[tuple()]]></c> (or a single match
- variable) while it is a list (or a single match variable) when
- tracing.</p>
</section>
<section>
- <title>ETS Examples</title>
+ <title>Tracing Examples</title>
<p>Match an argument list of three where the first and third arguments
are equal:</p>
<code type="none"><![CDATA[
@@ -585,42 +619,6 @@
parameter list with a single variable is a special case. In all
other cases the <c><![CDATA[MatchHead]]></c> has to be a <em>proper</em> list.
</p>
- <p>Match all objects in an ets table where the first element is
- the atom 'strider' and the tuple arity is 3 and return the whole
- object.</p>
- <code type="none"><![CDATA[
-[{{strider,'_','_'},
- [],
- ['$_']}]
- ]]></code>
- <p>Match all objects in an ets table with arity &gt; 1 and the first
- element is 'gandalf', return element 2.</p>
- <code type="none"><![CDATA[
-[{'$1',
- [{'==', gandalf, {element, 1, '$1'}},{'>=',{size, '$1'},2}],
- [{element,2,'$1'}]}]
- ]]></code>
- <p>In the above example, if the first element had been the key,
- it's much more efficient to match that key in the <c><![CDATA[MatchHead]]></c>
- part than in the <c><![CDATA[MatchConditions]]></c> part. The search space of
- the tables is restricted with regards to the <c><![CDATA[MatchHead]]></c> so
- that only objects with the matching key are searched.
- </p>
- <p>Match tuples of 3 elements where the second element is either
- 'merry' or 'pippin', return the whole objects.</p>
- <code type="none"><![CDATA[
-[{{'_',merry,'_'},
- [],
- ['$_']},
- {{'_',pippin,'_'},
- [],
- ['$_']}]
- ]]></code>
- <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[
[{'_',
@@ -658,5 +656,42 @@
{'_',[],[]}]
]]></code>
</section>
+
+ <section>
+ <title>ETS Examples</title>
+ <p>Match all objects in an ets table where the first element is
+ the atom 'strider' and the tuple arity is 3 and return the whole
+ object.</p>
+ <code type="none"><![CDATA[
+[{{strider,'_','_'},
+ [],
+ ['$_']}]
+ ]]></code>
+ <p>Match all objects in an ets table with arity &gt; 1 and the first
+ element is 'gandalf', return element 2.</p>
+ <code type="none"><![CDATA[
+[{'$1',
+ [{'==', gandalf, {element, 1, '$1'}},{'>=',{size, '$1'},2}],
+ [{element,2,'$1'}]}]
+ ]]></code>
+ <p>In the above example, if the first element had been the key,
+ it's much more efficient to match that key in the <c><![CDATA[MatchHead]]></c>
+ part than in the <c><![CDATA[MatchConditions]]></c> part. The search space of
+ the tables is restricted with regards to the <c><![CDATA[MatchHead]]></c> so
+ that only objects with the matching key are searched.
+ </p>
+ <p>Match tuples of 3 elements where the second element is either
+ 'merry' or 'pippin', return the whole objects.</p>
+ <code type="none"><![CDATA[
+[{{'_',merry,'_'},
+ [],
+ ['$_']},
+ {{'_',pippin,'_'},
+ [],
+ ['$_']}]
+ ]]></code>
+ <p>The function <c><![CDATA[ets:test_ms/2]]></c> can be useful for testing
+ complicated ets matches.</p>
+ </section>
</chapter>
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index 95489d9a63..0c2743beb2 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -4424,6 +4424,7 @@ gen_get_map_elements(LoaderState* stp, GenOpArg Fail, GenOpArg Src,
int good_hash;
#endif
+ ERTS_UNDEF(hx, 0);
ASSERT(Size.type == TAG_u);
NEW_GENOP(stp, op);
diff --git a/erts/emulator/beam/binary.c b/erts/emulator/beam/binary.c
index cfd8fbe2f5..071a356260 100644
--- a/erts/emulator/beam/binary.c
+++ b/erts/emulator/beam/binary.c
@@ -117,7 +117,7 @@ new_binary(Process *p, byte *buf, Uint len)
* When heap binary is not desired...
*/
-Eterm erts_new_mso_binary(Process *p, byte *buf, int len)
+Eterm erts_new_mso_binary(Process *p, byte *buf, Uint len)
{
ProcBin* pb;
Binary* bptr;
diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c
index c367d4162c..3c2c9def3b 100644
--- a/erts/emulator/beam/erl_alloc.c
+++ b/erts/emulator/beam/erl_alloc.c
@@ -137,10 +137,13 @@ static ErtsAllocatorState_t exec_alloc_state;
#endif
static ErtsAllocatorState_t test_alloc_state;
-#define ERTS_ALC_INFO_A_ALLOC_UTIL (ERTS_ALC_A_MAX + 1)
-#define ERTS_ALC_INFO_A_MSEG_ALLOC (ERTS_ALC_A_MAX + 2)
-#define ERTS_ALC_INFO_A_ERTS_MMAP (ERTS_ALC_A_MAX + 3)
-#define ERTS_ALC_INFO_A_MAX ERTS_ALC_INFO_A_ERTS_MMAP
+enum {
+ ERTS_ALC_INFO_A_ALLOC_UTIL = ERTS_ALC_A_MAX + 1,
+ ERTS_ALC_INFO_A_MSEG_ALLOC,
+ ERTS_ALC_INFO_A_ERTS_MMAP,
+ ERTS_ALC_INFO_A_DISABLED_EXEC, /* fake a disabled "exec_alloc" */
+ ERTS_ALC_INFO_A_END
+};
typedef struct {
erts_smp_atomic32_t refc;
@@ -150,7 +153,7 @@ typedef struct {
Process *proc;
Eterm ref;
Eterm ref_heap[REF_THING_SIZE];
- int allocs[ERTS_ALC_INFO_A_MAX - ERTS_ALC_A_MIN + 1 + 1];
+ int allocs[ERTS_ALC_INFO_A_END - ERTS_ALC_A_MIN + 1];
} ErtsAllocInfoReq;
ERTS_SCHED_PREF_QUICK_ALLOC_IMPL(aireq,
@@ -3260,6 +3263,12 @@ reply_alloc_info(void *vair)
am_false);
#endif
break;
+#ifndef ERTS_ALC_A_EXEC
+ case ERTS_ALC_INFO_A_DISABLED_EXEC:
+ alloc_atom = erts_bld_atom(hpp, szp, "exec_alloc");
+ ainfo = erts_bld_tuple2(hpp, szp, alloc_atom, am_false);
+ break;
+#endif
default:
alloc_atom = erts_bld_atom(hpp, szp,
(char *) ERTS_ALC_A2AD(ai));
@@ -3287,7 +3296,8 @@ reply_alloc_info(void *vair)
switch (ai) {
case ERTS_ALC_A_SYSTEM:
case ERTS_ALC_INFO_A_ALLOC_UTIL:
- case ERTS_ALC_INFO_A_ERTS_MMAP:
+ case ERTS_ALC_INFO_A_ERTS_MMAP:
+ case ERTS_ALC_INFO_A_DISABLED_EXEC:
break;
case ERTS_ALC_INFO_A_MSEG_ALLOC:
#if HAVE_ERTS_MSEG && defined(ERTS_SMP)
@@ -3359,7 +3369,7 @@ erts_request_alloc_info(struct process *c_p,
int internal)
{
ErtsAllocInfoReq *air = aireq_alloc();
- Eterm req_ai[ERTS_ALC_INFO_A_MAX+1] = {0};
+ Eterm req_ai[ERTS_ALC_INFO_A_END] = {0};
Eterm alist;
Eterm *hp;
int airix = 0, ai;
@@ -3399,6 +3409,12 @@ erts_request_alloc_info(struct process *c_p,
ai = ERTS_ALC_INFO_A_ERTS_MMAP;
goto save_alloc;
}
+#ifndef ERTS_ALC_A_EXEC
+ if (erts_is_atom_str("exec_alloc", alloc, 0)) {
+ ai = ERTS_ALC_INFO_A_DISABLED_EXEC;
+ goto save_alloc;
+ }
+#endif
if (erts_is_atom_str("alloc_util", alloc, 0)) {
ai = ERTS_ALC_INFO_A_ALLOC_UTIL;
save_alloc:
diff --git a/erts/emulator/beam/erl_bif_re.c b/erts/emulator/beam/erl_bif_re.c
index f4daecd2a4..ff7746ce1d 100644
--- a/erts/emulator/beam/erl_bif_re.c
+++ b/erts/emulator/beam/erl_bif_re.c
@@ -630,9 +630,15 @@ static Eterm build_exec_return(Process *p, int rc, RestartContext *restartp, Ete
}
} else {
ReturnInfo *ri;
- ReturnInfo defri = {RetIndex,0,{0}};
+ ReturnInfo defri;
if (restartp->ret_info == NULL) {
+ /* OpenBSD 5.8 gcc compiler for some reason creates
+ bad code if the above initialization is done
+ inline with the struct. So don't do that. */
+ defri.type = RetIndex;
+ defri.num_spec = 0;
+ defri.v[0] = 0;
ri = &defri;
} else {
ri = restartp->ret_info;
diff --git a/erts/emulator/beam/erl_message.h b/erts/emulator/beam/erl_message.h
index 851ac37fda..4493df1c1a 100644
--- a/erts/emulator/beam/erl_message.h
+++ b/erts/emulator/beam/erl_message.h
@@ -112,8 +112,8 @@ typedef struct erl_heap_fragment ErlHeapFragment;
struct erl_heap_fragment {
ErlHeapFragment* next; /* Next heap fragment */
ErlOffHeap off_heap; /* Offset heap data. */
- unsigned alloc_size; /* Size in (half)words of mem */
- unsigned used_size; /* With terms to be moved to heap by GC */
+ Uint alloc_size; /* Size in (half)words of mem */
+ Uint used_size; /* With terms to be moved to heap by GC */
Eterm mem[1]; /* Data */
};
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 159dc66ad5..606b73c7b5 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -96,7 +96,7 @@ void dtrace_nifenv_str(ErlNifEnv *, char *);
#endif
#define MIN_HEAP_FRAG_SZ 200
-static Eterm* alloc_heap_heavy(ErlNifEnv* env, unsigned need, Eterm* hp);
+static Eterm* alloc_heap_heavy(ErlNifEnv* env, size_t need, Eterm* hp);
static ERTS_INLINE int
is_scheduler(void)
@@ -135,7 +135,7 @@ execution_state(ErlNifEnv *env, Process **c_pp, int *schedp)
}
}
-static ERTS_INLINE Eterm* alloc_heap(ErlNifEnv* env, unsigned need)
+static ERTS_INLINE Eterm* alloc_heap(ErlNifEnv* env, size_t need)
{
Eterm* hp = env->hp;
env->hp += need;
@@ -145,7 +145,7 @@ static ERTS_INLINE Eterm* alloc_heap(ErlNifEnv* env, unsigned need)
return alloc_heap_heavy(env, need, hp);
}
-static Eterm* alloc_heap_heavy(ErlNifEnv* env, unsigned need, Eterm* hp)
+static Eterm* alloc_heap_heavy(ErlNifEnv* env, size_t need, Eterm* hp)
{
env->hp = hp;
if (env->heap_frag == NULL) {
@@ -166,7 +166,7 @@ static Eterm* alloc_heap_heavy(ErlNifEnv* env, unsigned need, Eterm* hp)
}
#if SIZEOF_LONG != ERTS_SIZEOF_ETERM
-static ERTS_INLINE void ensure_heap(ErlNifEnv* env, unsigned may_need)
+static ERTS_INLINE void ensure_heap(ErlNifEnv* env, size_t may_need)
{
if (env->hp + may_need > env->hp_end) {
alloc_heap_heavy(env, may_need, env->hp);
@@ -667,6 +667,9 @@ int enif_send(ErlNifEnv* env, const ErlNifPid* to_pid,
erts_smp_proc_trylock(rp, ERTS_PROC_LOCK_MSGQ) == EBUSY) {
if (!msgq) {
+#ifdef ERTS_SMP
+ ErtsThrPrgrDelayHandle dhndl;
+#endif
msgq = erts_alloc(ERTS_ALC_T_TRACE_MSG_QUEUE,
sizeof(ErlTraceMessageQueue));
@@ -681,8 +684,15 @@ int enif_send(ErlNifEnv* env, const ErlNifPid* to_pid,
erts_smp_proc_unlock(t_p, ERTS_PROC_LOCK_TRACE);
+#ifdef ERTS_SMP
+ if (!scheduler)
+ dhndl = erts_thr_progress_unmanaged_delay();
+#endif
erts_schedule_flush_trace_messages(t_p->common.id);
-
+#ifdef ERTS_SMP
+ if (!scheduler)
+ erts_thr_progress_unmanaged_continue(dhndl);
+#endif
} else {
msgq->len++;
*msgq->last = mp;
@@ -1197,7 +1207,7 @@ Eterm enif_make_sub_binary(ErlNifEnv* env, ERL_NIF_TERM bin_term,
Eterm orig;
Uint offset, bit_offset, bit_size;
#ifdef DEBUG
- unsigned src_size;
+ size_t src_size;
ASSERT(is_binary(bin_term));
src_size = binary_size(bin_term);
@@ -1669,7 +1679,8 @@ int enif_is_process_alive(ErlNifEnv* env, ErlNifPid *proc)
return !!rp;
#else
erts_exit(ERTS_ABORT_EXIT, "enif_is_process_alive: "
- "called from non-scheduler thread");
+ "called from non-scheduler thread "
+ "in non-smp emulator");
return 0;
#endif
}
@@ -1694,7 +1705,8 @@ int enif_is_port_alive(ErlNifEnv *env, ErlNifPort *port)
return !!prt;
#else
erts_exit(ERTS_ABORT_EXIT, "enif_is_port_alive: "
- "called from non-scheduler thread");
+ "called from non-scheduler thread "
+ "in non-smp emulator");
return 0;
#endif
}
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index 2801947613..b44ac442aa 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -960,7 +960,6 @@ struct process {
Uint heap_sz; /* Size of heap in words */
Uint min_heap_size; /* Minimum size of heap (in words). */
Uint min_vheap_size; /* Minimum size of virtual heap (in words). */
- Uint max_heap_size; /* Maximum size of heap (in words). */
#if !defined(NO_FPE_SIGNALS) || defined(HIPE)
volatile unsigned long fp_exception;
@@ -1061,6 +1060,7 @@ struct process {
Eterm *old_hend; /* Heap pointers for generational GC. */
Eterm *old_htop;
Eterm *old_heap;
+ Uint max_heap_size; /* Maximum size of heap (in words). */
Uint16 gen_gcs; /* Number of (minor) generational GCs. */
Uint16 max_gen_gcs; /* Max minor gen GCs before fullsweep. */
ErlOffHeap off_heap; /* Off-heap data updated by copy_struct(). */
@@ -1339,7 +1339,7 @@ ERTS_GLB_INLINE void erts_heap_frag_shrink(Process* p, Eterm* hp)
{
ErlHeapFragment* hf = MBUF(p);
- ASSERT(hf!=NULL && (hp - hf->mem < (unsigned long)hf->alloc_size));
+ ASSERT(hf!=NULL && (hp - hf->mem < hf->alloc_size));
hf->used_size = hp - hf->mem;
}
diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c
index 3c3536c021..bd5e1482fb 100644
--- a/erts/emulator/beam/erl_unicode.c
+++ b/erts/emulator/beam/erl_unicode.c
@@ -55,7 +55,7 @@ static BIF_RETTYPE finalize_list_to_list(Process *p,
Uint num_processed_bytes,
Uint num_bytes_to_process,
Uint num_resulting_chars,
- int state, int left,
+ int state, Sint left,
Eterm tail);
static BIF_RETTYPE characters_to_utf8_trap(BIF_ALIST_3);
static BIF_RETTYPE characters_to_list_trap_1(BIF_ALIST_3);
@@ -173,12 +173,13 @@ static ERTS_INLINE int allowed_iterations(Process *p)
else
return tmp;
}
-static ERTS_INLINE int cost_to_proc(Process *p, int cost)
+
+static ERTS_INLINE void cost_to_proc(Process *p, Sint cost)
{
- int x = (cost / LOOP_FACTOR);
+ Sint x = (cost / LOOP_FACTOR);
BUMP_REDS(p,x);
- return x;
}
+
static ERTS_INLINE int simple_loops_to_common(int cost)
{
int factor = (LOOP_FACTOR_SIMPLE / LOOP_FACTOR);
@@ -243,14 +244,15 @@ static int utf8_len(byte first)
return -1;
}
-static int copy_utf8_bin(byte *target, byte *source, Uint size,
- byte *leftover, int *num_leftovers,
- byte **err_pos, Uint *characters) {
- int copied = 0;
+static Uint copy_utf8_bin(byte *target, byte *source, Uint size,
+ byte *leftover, int *num_leftovers,
+ byte **err_pos, Uint *characters)
+{
+ Uint copied = 0;
if (leftover != NULL && *num_leftovers) {
int need = utf8_len(leftover[0]);
int from_source = need - (*num_leftovers);
- int c;
+ Uint c;
byte *tmp_err_pos = NULL;
ASSERT(need > 0);
ASSERT(from_source > 0);
@@ -502,8 +504,8 @@ L_Again: /* Restart with sublist, old listend was pushed on stack */
}
-static Eterm do_build_utf8(Process *p, Eterm ioterm, int *left, int latin1,
- byte *target, int *pos, Uint *characters, int *err,
+static Eterm do_build_utf8(Process *p, Eterm ioterm, Sint *left, int latin1,
+ byte *target, Uint *pos, Uint *characters, int *err,
byte *leftover, int *num_leftovers)
{
int c;
@@ -573,7 +575,7 @@ static Eterm do_build_utf8(Process *p, Eterm ioterm, int *left, int latin1,
}
if (!latin1) {
- int num;
+ Uint num;
byte *err_pos = NULL;
num = copy_utf8_bin(target + (*pos), bytes,
size, leftover, num_leftovers,&err_pos,characters);
@@ -804,7 +806,7 @@ static int check_leftovers(byte *source, int size)
-static BIF_RETTYPE build_utf8_return(Process *p,Eterm bin,int pos,
+static BIF_RETTYPE build_utf8_return(Process *p,Eterm bin,Uint pos,
Eterm rest_term,int err,
byte *leftover,int num_leftovers,Eterm latin1)
{
@@ -859,8 +861,8 @@ static BIF_RETTYPE characters_to_utf8_trap(BIF_ALIST_3)
#endif
byte* bytes;
Eterm rest_term;
- int left, sleft;
- int pos;
+ Sint left, sleft;
+ Uint pos;
int err;
byte leftover[4]; /* used for temp buffer too,
otherwise 3 bytes would have been enough */
@@ -874,7 +876,7 @@ static BIF_RETTYPE characters_to_utf8_trap(BIF_ALIST_3)
real_bin = binary_val(BIF_ARG_1);
ASSERT(*real_bin == HEADER_PROC_BIN);
#endif
- pos = (int) binary_size(BIF_ARG_1);
+ pos = binary_size(BIF_ARG_1);
bytes = binary_bytes(BIF_ARG_1);
sleft = left = allowed_iterations(BIF_P);
err = 0;
@@ -934,9 +936,9 @@ BIF_RETTYPE unicode_characters_to_binary_2(BIF_ALIST_2)
int latin1;
Eterm bin;
byte *bytes;
- int pos;
+ Uint pos;
int err;
- int left, sleft;
+ Sint left, sleft;
Eterm rest_term, subject;
byte leftover[4]; /* used for temp buffer too, o
therwise 3 bytes would have been enough */
@@ -999,7 +1001,7 @@ BIF_RETTYPE unicode_characters_to_binary_2(BIF_ALIST_2)
byte *t = NULL;
Uint sz = binary_size(bin);
byte *by = erts_get_aligned_binary_bytes(bin,&t);
- int i;
+ Uint i;
erts_printf("<<");
for (i = 0;i < sz; ++i) {
erts_printf((i == sz -1) ? "0x%X" : "0x%X, ", (unsigned) by[i]);
@@ -1007,7 +1009,7 @@ BIF_RETTYPE unicode_characters_to_binary_2(BIF_ALIST_2)
erts_printf(">>: ");
erts_free_aligned_binary_bytes(t);
}
- erts_printf("%d - %d = %d\n",sleft,left,sleft - left);
+ erts_printf("%ld - %ld = %ld\n", sleft, left, sleft - left);
}
#endif
cost_to_proc(BIF_P, sleft - left);
@@ -1015,10 +1017,10 @@ BIF_RETTYPE unicode_characters_to_binary_2(BIF_ALIST_2)
leftover,num_leftovers,BIF_ARG_2);
}
-static BIF_RETTYPE build_list_return(Process *p, byte *bytes, int pos, Uint characters,
+static BIF_RETTYPE build_list_return(Process *p, byte *bytes, Uint pos, Uint characters,
Eterm rest_term, int err,
byte *leftover, int num_leftovers,
- Eterm latin1, int left)
+ Eterm latin1, Sint left)
{
Eterm *hp;
@@ -1070,11 +1072,11 @@ static BIF_RETTYPE characters_to_list_trap_1(BIF_ALIST_3)
{
RestartContext *rc;
byte* bytes;
- int pos;
+ Uint pos;
Uint characters;
int err;
Eterm rest_term;
- int left, sleft;
+ Sint left, sleft;
int latin1 = 0;
byte leftover[4]; /* used for temp buffer too,
@@ -1107,9 +1109,9 @@ BIF_RETTYPE unicode_characters_to_list_2(BIF_ALIST_2)
int latin1;
Uint characters = 0;
byte *bytes;
- int pos;
+ Uint pos;
int err;
- int left, sleft;
+ Sint left, sleft;
Eterm rest_term;
byte leftover[4]; /* used for temp buffer too, o
therwise 3 bytes would have been enough */
@@ -1541,7 +1543,7 @@ static BIF_RETTYPE finalize_list_to_list(Process *p,
Uint num_processed_bytes,
Uint num_bytes_to_process,
Uint num_resulting_chars,
- int state, int left,
+ int state, Sint left,
Eterm tail)
{
Uint num_built; /* characters */
@@ -2016,7 +2018,7 @@ char *erts_convert_filename_to_encoding(Eterm name, char *statbuf, size_t statbu
++need;
}
if (used)
- *used = (Sint) need;
+ *used = need;
if (need+extra > statbuf_size) {
name_buf = (char *) erts_alloc(alloc_type, need+extra);
} else {
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 1abcc6cbf4..b76b9cd874 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -947,7 +947,7 @@ ERTS_GLB_INLINE Eterm erts_equeue_get(ErtsEQueue *q) {
void erts_emasculate_writable_binary(ProcBin* pb);
Eterm erts_new_heap_binary(Process *p, byte *buf, int len, byte** datap);
-Eterm erts_new_mso_binary(Process*, byte*, int);
+Eterm erts_new_mso_binary(Process*, byte*, Uint);
Eterm new_binary(Process*, byte*, Uint);
Eterm erts_realloc_binary(Eterm bin, size_t size);
diff --git a/erts/emulator/hipe/hipe_mode_switch.c b/erts/emulator/hipe/hipe_mode_switch.c
index f532d3151f..884331e969 100644
--- a/erts/emulator/hipe/hipe_mode_switch.c
+++ b/erts/emulator/hipe/hipe_mode_switch.c
@@ -174,6 +174,33 @@ void hipe_mode_switch_init(void)
make_catch(beam_catches_cons(hipe_beam_pc_throw, BEAM_CATCHES_NIL));
hipe_mfa_info_table_init();
+
+#if (defined(__i386__) || defined(__x86_64__)) && defined(__linux__)
+ /* Verify that the offset of c-p->hipe does not change.
+ The ErLLVM hipe backend depends on it being in a specific
+ position. Kostis et al has promised to fix this in upstream
+ llvm by OTP 20, so it should be possible to remove these asserts
+ after that. */
+ ERTS_CT_ASSERT(sizeof(ErtsPTabElementCommon) ==
+ (sizeof(Eterm) + /* id */
+ sizeof(((ErtsPTabElementCommon*)0)->refc) +
+ sizeof(ErtsTracer) + /* tracer */
+ sizeof(Uint) + /* trace_flags */
+ sizeof(erts_smp_atomic_t) + /* timer */
+ sizeof(((ErtsPTabElementCommon*)0)->u)));
+
+ ERTS_CT_ASSERT(offsetof(Process, hipe) ==
+ (sizeof(ErtsPTabElementCommon) + /* common */
+ sizeof(Eterm*) + /* htop */
+ sizeof(Eterm*) + /* stop */
+ sizeof(Eterm*) + /* heap */
+ sizeof(Eterm*) + /* hend */
+ sizeof(Uint) + /* heap_sz */
+ sizeof(Uint) + /* min_heap_size */
+ sizeof(Uint) + /* min_vheap_size */
+ sizeof(volatile unsigned long))); /* fp_exception */
+#endif
+
}
void hipe_set_call_trap(Uint *bfun, void *nfun, int is_closure)
diff --git a/erts/emulator/test/alloc_SUITE.erl b/erts/emulator/test/alloc_SUITE.erl
index 1f7b499dcb..84cf4921d3 100644
--- a/erts/emulator/test/alloc_SUITE.erl
+++ b/erts/emulator/test/alloc_SUITE.erl
@@ -73,16 +73,32 @@ migration(Cfg) ->
end.
erts_mmap(Config) when is_list(Config) ->
- case os:type() of
- {unix, _} ->
+ case {os:type(), mmsc_flags()} of
+ {{unix,_}, false} ->
[erts_mmap_do(Config, SCO, SCRPM, SCRFSD)
|| SCO <-[true,false], SCRFSD <-[1234,0], SCRPM <- [true,false]];
- {SkipOs,_} ->
+ {{unix,_}, Flags} ->
+ {skipped, Flags};
+ {{SkipOs,_},_} ->
{skipped,
lists:flatten(["Not run on "
| io_lib:format("~p",[SkipOs])])}
end.
+%% Check if there are ERL_FLAGS set that will mess up this test case
+mmsc_flags() ->
+ case mmsc_flags("ERL_FLAGS") of
+ false -> mmsc_flags("ERL_ZFLAGS");
+ Flags -> Flags
+ end.
+mmsc_flags(Env) ->
+ case os:getenv(Env) of
+ false -> false;
+ V -> case string:str(V, "+MMsc") of
+ 0 -> false;
+ P -> Env ++ "=" ++ string:substr(V, P)
+ end
+ end.
erts_mmap_do(Config, SCO, SCRPM, SCRFSD) ->
%% We use the number of schedulers + 1 * approx main carriers size
diff --git a/erts/emulator/test/port_trace_SUITE.erl b/erts/emulator/test/port_trace_SUITE.erl
index bfdea0761b..5d9a75bcd3 100644
--- a/erts/emulator/test/port_trace_SUITE.erl
+++ b/erts/emulator/test/port_trace_SUITE.erl
@@ -31,7 +31,8 @@
failure_atom/1, failure_posix/1,
failure/1, output_term/1,
driver_output_term/1,
- send_term/1, driver_send_term/1]).
+ send_term/1, driver_send_term/1,
+ driver_remote_send_term/1]).
-define(ECHO_DRV_NOOP, 0).
-define(ECHO_DRV_OUTPUT, 1).
@@ -48,6 +49,7 @@
-define(ECHO_DRV_SEND_TERM, 12).
-define(ECHO_DRV_DRIVER_SEND_TERM, 13).
-define(ECHO_DRV_SAVE_CALLER, 14).
+-define(ECHO_DRV_REMOTE_SEND_TERM, 15).
suite() -> [{ct_hooks,[ts_install_cth]},
{timetrap, {seconds, 30}}].
@@ -60,7 +62,8 @@ all() ->
failure_atom, failure_posix,
failure, output_term,
driver_output_term,
- send_term, driver_send_term].
+ send_term, driver_send_term,
+ driver_remote_send_term].
init_per_suite(Config) ->
Config.
@@ -75,6 +78,13 @@ end_per_group(_GroupName, Config) ->
Config.
+init_per_testcase(driver_remote_send_term, Config) ->
+ case erlang:system_info(smp_support) of
+ false ->
+ {skip,"Only supported on smp systems"};
+ true ->
+ init_per_testcase(driver_remote_send_term_smp, Config)
+ end;
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
erlang:trace(all, false, [all]),
os:unsetenv("OUTPUTV"),
@@ -543,6 +553,34 @@ driver_send_term(_Config) ->
ok.
+%% Test that driver_send_term from non-scheduler thread does not
+%% generate trace messages.
+driver_remote_send_term(_Config) ->
+
+ Flags = [send],
+ {Prt, S} = trace_and_open(Flags,[binary]),
+
+ erlang:port_command(Prt, <<?ECHO_DRV_REMOTE_SEND_TERM, 123456:32>>),
+ recv({echo, Prt, <<123456:32>>}),
+ [] = flush(),
+
+ Pid = spawn_link(
+ fun() ->
+ erlang:port_command(Prt, <<?ECHO_DRV_SAVE_CALLER>>),
+ S ! ok,
+ receive M -> S ! M end
+ end),
+ recv(ok),
+ erlang:trace(Pid, true, ['receive']),
+
+ erlang:port_command(Prt, <<?ECHO_DRV_REMOTE_SEND_TERM, 123456:32>>),
+ recv({echo, Prt, <<123456:32>>}),
+ [{trace, Pid, 'receive', {echo, Prt, <<123456:32>>}}] = flush(),
+
+ close(Prt, Flags),
+
+ ok.
+
%%%%%%%%%%%%%%%%%%%
%% Helper functions
%%%%%%%%%%%%%%%%%%%
@@ -598,7 +636,7 @@ f(From) ->
end.
recv(Msg) ->
- receive Msg -> ok after 100 -> ct:fail({did_not_get_data,Msg,flush()}) end.
+ receive Msg -> ok after 1000 -> ct:fail({did_not_get_data,Msg,flush()}) end.
load_drv(Config) ->
Path = proplists:get_value(data_dir, Config),
diff --git a/erts/emulator/test/port_trace_SUITE_data/echo_drv.c b/erts/emulator/test/port_trace_SUITE_data/echo_drv.c
index b5ae9389b4..b545523192 100644
--- a/erts/emulator/test/port_trace_SUITE_data/echo_drv.c
+++ b/erts/emulator/test/port_trace_SUITE_data/echo_drv.c
@@ -14,6 +14,13 @@ typedef struct _erl_drv_data {
ErlDrvTermData caller;
} EchoDrvData;
+struct remote_send_term {
+ char *buf;
+ int len;
+ ErlDrvTermData port;
+ ErlDrvTermData caller;
+};
+
#define ECHO_DRV_NOOP 0
#define ECHO_DRV_OUTPUT 1
#define ECHO_DRV_OUTPUT2 2
@@ -29,6 +36,7 @@ typedef struct _erl_drv_data {
#define ECHO_DRV_SEND_TERM 12
#define ECHO_DRV_DRIVER_SEND_TERM 13
#define ECHO_DRV_SAVE_CALLER 14
+#define ECHO_DRV_REMOTE_SEND_TERM 15
/* -------------------------------------------------------------------------
@@ -78,6 +86,8 @@ static ErlDrvEntry echo_drv_entry = {
NULL
};
+static void send_term_thread(void *);
+
/* -------------------------------------------------------------------------
** Entry functions
**/
@@ -200,6 +210,18 @@ static void echo_drv_output(ErlDrvData drv_data, char *buf, ErlDrvSizeT len) {
}
break;
}
+ case ECHO_DRV_REMOTE_SEND_TERM:
+ {
+ ErlDrvTid tid;
+ struct remote_send_term *t = malloc(sizeof(struct remote_send_term));
+ t->len = len-1;
+ t->buf = malloc(len-1);
+ t->port = driver_mk_port(port);
+ t->caller = data_p->caller;
+ memcpy(t->buf, buf+1, t->len);
+ erl_drv_thread_create("tmp_thread", &tid, send_term_thread, t, NULL);
+ break;
+ }
case ECHO_DRV_SAVE_CALLER:
data_p->caller = driver_caller(port);
break;
@@ -239,3 +261,17 @@ static ErlDrvSSizeT echo_drv_call(ErlDrvData drv_data,
memcpy(*rbuf, buf+command, len-command);
return len-command;
}
+
+static void send_term_thread(void *a)
+{
+ struct remote_send_term *t = (struct remote_send_term*)a;
+ ErlDrvTermData term[] = {
+ ERL_DRV_ATOM, driver_mk_atom("echo"),
+ ERL_DRV_PORT, t->port,
+ ERL_DRV_BUF2BINARY, (ErlDrvTermData)(t->buf),
+ (ErlDrvTermData)(t->len),
+ ERL_DRV_TUPLE, 3};
+ erl_drv_send_term(t->port, t->caller,
+ term, sizeof(term) / sizeof(ErlDrvTermData));
+ return;
+}
diff --git a/erts/emulator/test/time_SUITE.erl b/erts/emulator/test/time_SUITE.erl
index 76d440529f..87b8c62cfa 100644
--- a/erts/emulator/test/time_SUITE.erl
+++ b/erts/emulator/test/time_SUITE.erl
@@ -209,23 +209,17 @@ test_seconds_to_univ([]) ->
%% Test that the the different time functions return
-%% consistent results. (See the test case for assumptions
-%% and limitations.)
-consistency(Config) when is_list(Config) ->
- %% Test the following equations:
- %% date() & time() == erlang:localtime()
- %% erlang:universaltime() + timezone == erlang:localtime()
+%% consistent results.
+consistency(_Config) ->
+ %% Test that:
+ %% * date() & time() gives the same time as erlang:localtime()
%%
- %% Assumptions:
- %% Middle-European time zone, EU rules for daylight-saving time.
- %%
- %% Limitations:
- %% Localtime and universaltime must be in the same month.
- %% Daylight-saving calculations are incorrect from the last
- %% Sunday of March and October to the end of the month.
+ %% * the difference between erlang:universaltime() and
+ %% erlang:localtime() is reasonable (with assuming any
+ %% particular timezone)
ok = compare_date_time_and_localtime(16),
- ok = compare_local_and_universal(16).
+ compare_local_and_universal(16).
compare_date_time_and_localtime(Times) when Times > 0 ->
{Year, Mon, Day} = date(),
@@ -238,22 +232,18 @@ compare_date_time_and_localtime(0) ->
error.
compare_local_and_universal(Times) when Times > 0 ->
- case compare(erlang:universaltime(), erlang:localtime()) of
- true -> ok;
- false -> compare_local_and_universal(Times-1)
- end;
-compare_local_and_universal(0) ->
- error.
+ Utc = erlang:universaltime(),
+ Local = erlang:localtime(),
+ io:format("local = ~p, utc = ~p", [Local,Utc]),
-compare(Utc0, Local) ->
- io:format("local = ~p, utc = ~p", [Local, Utc0]),
- Utc = linear_time(Utc0)+effective_timezone(Utc0)*3600,
- case linear_time(Local) of
- Utc -> true;
- Other ->
- io:format("Failed: local = ~p, utc = ~p~n",
- [Other, Utc]),
- false
+ AcceptableDiff = 14*3600,
+ case linear_time(Utc) - linear_time(Local) of
+ Diff when abs(Diff) < AcceptableDiff ->
+ ok;
+ Diff ->
+ io:format("More than ~p seconds difference betwen "
+ "local and universal time", [Diff]),
+ ct:fail(huge_diff)
end.
%% This function converts a date and time to a linear time.
@@ -280,35 +270,6 @@ days_in_february(Year) ->
_ -> 28
end.
-%% This functions returns either the normal timezone or the
-%% the DST timezone, depending on the given UTC time.
-%%
-%% XXX This function uses an approximation of the EU rule for
-%% daylight saving time. This function will fail in the
-%% following intervals: After the last Sunday in March upto
-%% the end of March, and after the last Sunday in October
-%% upto the end of October.
-
-effective_timezone(Time) ->
- case os:type() of
- {unix,_} ->
- case os:cmd("date '+%Z'") of
- "SAST"++_ ->
- 2;
- _ ->
- effective_timezone1(Time)
- end;
- _ ->
- effective_timezone1(Time)
- end.
-
-effective_timezone1({{_Year,Mon,_Day}, _}) when Mon < 4 ->
- ?timezone;
-effective_timezone1({{_Year,Mon,_Day}, _}) when Mon > 10 ->
- ?timezone;
-effective_timezone1(_) ->
- ?dst_timezone.
-
%% Test (the bif) os:timestamp/0, which is something quite like, but not
%% similar to erlang:now...
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index de2693472a..66e443f396 100644
--- a/erts/preloaded/ebin/erl_prim_loader.beam
+++ b/erts/preloaded/ebin/erl_prim_loader.beam
Binary files differ
diff --git a/erts/preloaded/src/erl_prim_loader.erl b/erts/preloaded/src/erl_prim_loader.erl
index e18e187cb7..b3ec73a60e 100644
--- a/erts/preloaded/src/erl_prim_loader.erl
+++ b/erts/preloaded/src/erl_prim_loader.erl
@@ -558,11 +558,9 @@ efile_gm_get_1([P|Ps], File0, Mod, {Parent,Ref}=PR, Process) ->
Res = try prim_file:read_file(File) of
{ok,Bin} ->
gm_process(Mod, File, Bin, Process);
- {error,enoent} ->
- efile_gm_get_1(Ps, File0, Mod, PR, Process);
Error ->
- check_file_result(get_modules, File, Error),
- Error
+ _ = check_file_result(get_modules, File, Error),
+ efile_gm_get_1(Ps, File0, Mod, PR, Process)
catch
_:Reason ->
{error,{crash,Reason}}
diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src
index 5b82f0bfcf..c2d8261dd8 100644
--- a/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src
+++ b/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src
@@ -23,9 +23,10 @@ include @erl_interface_mk_include@
CC0 = @CC@
CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
LD = @LD@
+LIBERL = @erl_interface_lib@
LIBEI = @erl_interface_eilib@
LIBFLAGS = ../all_SUITE_data/ei_runner@obj@ \
- $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
+ $(LIBERL) $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
@erl_interface_threadlib@
CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
EI_CONNECT_OBJS = ei_connect_test@obj@ ei_connect_test_decl@obj@
diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/einode.c b/lib/erl_interface/test/ei_connect_SUITE_data/einode.c
index e1d46ae59a..bb71575740 100644
--- a/lib/erl_interface/test/ei_connect_SUITE_data/einode.c
+++ b/lib/erl_interface/test/ei_connect_SUITE_data/einode.c
@@ -35,6 +35,7 @@
#endif
#include "ei.h"
+#include "erl_interface.h"
#ifdef VXWORKS
#define MAIN cnode
@@ -115,6 +116,8 @@ MAIN(int argc, char *argv[])
if (argc < 3)
exit(1);
+ erl_init(NULL, 0);
+
cookie = argv[1];
n = atoi(argv[2]);
if (n > 100)
diff --git a/lib/kernel/test/erl_prim_loader_SUITE.erl b/lib/kernel/test/erl_prim_loader_SUITE.erl
index 4f3881d27e..b6417210b9 100644
--- a/lib/kernel/test/erl_prim_loader_SUITE.erl
+++ b/lib/kernel/test/erl_prim_loader_SUITE.erl
@@ -108,13 +108,18 @@ get_file(Config) when is_list(Config) ->
error = erl_prim_loader:get_file({dummy}),
ok.
-get_modules(_Config) ->
+get_modules(Config) ->
case test_server:is_cover() of
- false -> do_get_modules();
+ false -> do_get_modules(Config);
true -> {skip,"Cover"}
end.
-do_get_modules() ->
+do_get_modules(Config) ->
+ PrivDir = proplists:get_value(priv_dir, Config),
+ NotADir = atom_to_list(?FUNCTION_NAME) ++ "_not_a_dir",
+ ok = file:write_file(filename:join(PrivDir, NotADir), <<>>),
+ ok = file:set_cwd(PrivDir),
+
MsGood = lists:sort([lists,gen_server,gb_trees,code_server]),
Ms = [certainly_not_existing|MsGood],
SuccExp = [begin
@@ -129,8 +134,10 @@ do_get_modules() ->
Path = code:get_path(),
Process = fun(_, F, Code) -> {ok,{F,erlang:md5(Code)}} end,
- {ok,{Succ,FailExp}} = erl_prim_loader:get_modules(Ms, Process, Path),
- SuccExp = lists:sort(Succ),
+ {ok,{SuccExp,FailExp}} = get_modules_sorted(Ms, Process, Path),
+
+ %% Test that an 'enotdir' error can be handled.
+ {ok,{SuccExp,FailExp}} = get_modules_sorted(Ms, Process, [NotADir|Path]),
Name = inet_get_modules,
{ok, Node, BootPid} = complete_start_node(Name),
@@ -147,6 +154,13 @@ do_get_modules() ->
ok.
+get_modules_sorted(Ms, Process, Path) ->
+ case erl_prim_loader:get_modules(Ms, Process, Path) of
+ {ok,{Succ,FailExp}} ->
+ {ok,{lists:sort(Succ),lists:sort(FailExp)}};
+ Other ->
+ Other
+ end.
normalize_and_backslash(Config) ->
%% Test OTP-11170
diff --git a/lib/os_mon/src/memsup.erl b/lib/os_mon/src/memsup.erl
index d9d3083540..4729d090f8 100644
--- a/lib/os_mon/src/memsup.erl
+++ b/lib/os_mon/src/memsup.erl
@@ -699,6 +699,8 @@ get_os_wordsize_with_uname() ->
case String of
"x86_64" -> 64;
"sparc64" -> 64;
+ "amd64" -> 64;
+ "ppc64" -> 64;
_ -> 32
end.
diff --git a/lib/os_mon/test/memsup_SUITE.erl b/lib/os_mon/test/memsup_SUITE.erl
index fcd1417693..e40ed574e7 100644
--- a/lib/os_mon/test/memsup_SUITE.erl
+++ b/lib/os_mon/test/memsup_SUITE.erl
@@ -100,10 +100,16 @@ api(Config) when is_list(Config) ->
%% get_os_wordsize()
ok = case memsup:get_os_wordsize() of
- 32 -> ok;
- 64 -> ok;
- unsupported_os -> ok;
- _ -> error
+ 32 ->
+ 32 = 8*erlang:system_info({wordsize,external}),
+ ok;
+ 64 ->
+ % No reliable test here
+ ok;
+ unsupported_os ->
+ ok;
+ _ ->
+ error
end,
%% get_check_interval()
diff --git a/lib/public_key/test/pbe_SUITE.erl b/lib/public_key/test/pbe_SUITE.erl
index 4b7ebf4309..004eaefc27 100644
--- a/lib/public_key/test/pbe_SUITE.erl
+++ b/lib/public_key/test/pbe_SUITE.erl
@@ -30,7 +30,8 @@
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-suite() -> [{ct_hooks,[ts_install_cth]}].
+suite() ->
+ [].
all() ->
[
@@ -199,7 +200,7 @@ pbdkdf2(Config) when is_list(Config) ->
old_enc() ->
[{doc,"Tests encode/decode RSA key encrypted with different ciphers using old PEM encryption scheme"}].
old_enc(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
%% key generated with ssh-keygen -N hello_aes -f old_aes_128_cbc_enc_key.pem
{ok, PemAesCbc} = file:read_file(filename:join(Datadir, "old_aes_128_cbc_enc_key.pem")),
@@ -226,7 +227,7 @@ check_key_info(#'PrivateKeyInfo'{privateKeyAlgorithm =
#'RSAPrivateKey'{} = public_key:der_decode('RSAPrivateKey', iolist_to_binary(Key)).
decode_encode_key_file(File, Password, Cipher, Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, PemKey} = file:read_file(filename:join(Datadir, File)),
PemEntry = public_key:pem_decode(PemKey),
diff --git a/lib/public_key/test/pkits_SUITE.erl b/lib/public_key/test/pkits_SUITE.erl
index 17be99b52d..487b3dbe3f 100644
--- a/lib/public_key/test/pkits_SUITE.erl
+++ b/lib/public_key/test/pkits_SUITE.erl
@@ -53,7 +53,7 @@
%%--------------------------------------------------------------------
suite() ->
- [{ct_hooks,[ts_install_cth]}].
+ [].
all() ->
[{group, signature_verification},
diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl
index 51050c4480..9c39c36be4 100644
--- a/lib/public_key/test/public_key_SUITE.erl
+++ b/lib/public_key/test/public_key_SUITE.erl
@@ -34,7 +34,8 @@
%% Common Test interface functions -----------------------------------
%%--------------------------------------------------------------------
-suite() -> [{ct_hooks,[ts_install_cth]}].
+suite() ->
+ [].
all() ->
[app, appup,
@@ -108,7 +109,7 @@ appup(Config) when is_list(Config) ->
dsa_pem() ->
[{doc, "DSA PEM-file decode/encode"}].
dsa_pem(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
[{'DSAPrivateKey', DerDSAKey, not_encrypted} = Entry0 ] =
erl_make_certs:pem_to_der(filename:join(Datadir, "dsa.pem")),
@@ -131,7 +132,7 @@ dsa_pem(Config) when is_list(Config) ->
rsa_pem() ->
[{doc, "RSA PEM-file decode/encode"}].
rsa_pem(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
[{'RSAPrivateKey', DerRSAKey, not_encrypted} = Entry0 ] =
erl_make_certs:pem_to_der(filename:join(Datadir, "client_key.pem")),
@@ -166,7 +167,7 @@ rsa_pem(Config) when is_list(Config) ->
ec_pem() ->
[{doc, "EC key PEM-file decode/encode"}].
ec_pem(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, ECPubPem} = file:read_file(filename:join(Datadir, "ec_pubkey.pem")),
[{'SubjectPublicKeyInfo', _, _} = PubEntry0] =
public_key:pem_decode(ECPubPem),
@@ -192,7 +193,7 @@ ec_pem(Config) when is_list(Config) ->
encrypted_pem() ->
[{doc, "Encrypted PEM-file decode/encode"}].
encrypted_pem(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
[{'RSAPrivateKey', DerRSAKey, not_encrypted}] =
erl_make_certs:pem_to_der(filename:join(Datadir, "client_key.pem")),
@@ -225,7 +226,7 @@ encrypted_pem(Config) when is_list(Config) ->
dh_pem() ->
[{doc, "DH parametrs PEM-file decode/encode"}].
dh_pem(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
[{'DHParameter', _DerDH, not_encrypted} = Entry] =
erl_make_certs:pem_to_der(filename:join(Datadir, "dh.pem")),
asn1_encode_decode(Entry).
@@ -235,7 +236,7 @@ dh_pem(Config) when is_list(Config) ->
pkcs10_pem() ->
[{doc, "PKCS-10 PEM-file decode/encode"}].
pkcs10_pem(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
[{'CertificationRequest', _DerPKCS10, not_encrypted} = Entry] =
erl_make_certs:pem_to_der(filename:join(Datadir, "req.pem")),
asn1_encode_decode(Entry).
@@ -243,7 +244,7 @@ pkcs10_pem(Config) when is_list(Config) ->
pkcs7_pem() ->
[{doc, "PKCS-7 PEM-file decode/encode"}].
pkcs7_pem(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
[{'ContentInfo', _, not_encrypted} = Entry0] =
erl_make_certs:pem_to_der(filename:join(Datadir, "pkcs7_cert.pem")),
[{'ContentInfo', _, not_encrypted} = Entry1] =
@@ -255,7 +256,7 @@ pkcs7_pem(Config) when is_list(Config) ->
cert_pem() ->
[{doc, "Certificate PEM-file decode/encode"}].
cert_pem(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
[{'Certificate', _, not_encrypted} = Entry0] =
erl_make_certs:pem_to_der(filename:join(Datadir, "client_cert.pem")),
@@ -273,7 +274,7 @@ cert_pem(Config) when is_list(Config) ->
ssh_rsa_public_key() ->
[{doc, "ssh rsa public key decode/encode"}].
ssh_rsa_public_key(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, RSARawSsh2} = file:read_file(filename:join(Datadir, "ssh2_rsa_pub")),
[{PubKey, Attributes1}] = public_key:ssh_decode(RSARawSsh2, public_key),
@@ -299,7 +300,7 @@ ssh_rsa_public_key(Config) when is_list(Config) ->
ssh_dsa_public_key() ->
[{doc, "ssh dsa public key decode/encode"}].
ssh_dsa_public_key(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, DSARawSsh2} = file:read_file(filename:join(Datadir, "ssh2_dsa_pub")),
[{PubKey, Attributes1}] = public_key:ssh_decode(DSARawSsh2, public_key),
@@ -325,7 +326,7 @@ ssh_dsa_public_key(Config) when is_list(Config) ->
ssh_ecdsa_public_key() ->
[{doc, "ssh ecdsa public key decode/encode"}].
ssh_ecdsa_public_key(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, ECDSARawSsh2} = file:read_file(filename:join(Datadir, "ssh2_ecdsa_pub")),
[{PubKey, Attributes1}] = public_key:ssh_decode(ECDSARawSsh2, public_key),
@@ -350,7 +351,7 @@ ssh_ecdsa_public_key(Config) when is_list(Config) ->
ssh_rfc4716_rsa_comment() ->
[{doc, "Test comment header and rsa key"}].
ssh_rfc4716_rsa_comment(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, RSARawSsh2} = file:read_file(filename:join(Datadir, "ssh2_rsa_comment_pub")),
[{#'RSAPublicKey'{} = PubKey, Attributes}] =
@@ -366,7 +367,7 @@ ssh_rfc4716_rsa_comment(Config) when is_list(Config) ->
ssh_rfc4716_dsa_comment() ->
[{doc, "Test comment header and dsa key"}].
ssh_rfc4716_dsa_comment(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, DSARawSsh2} = file:read_file(filename:join(Datadir, "ssh2_dsa_comment_pub")),
[{{_, #'Dss-Parms'{}} = PubKey, Attributes}] =
@@ -386,7 +387,7 @@ ssh_rfc4716_dsa_comment(Config) when is_list(Config) ->
ssh_rfc4716_rsa_subject() ->
[{doc, "Test another header value than comment"}].
ssh_rfc4716_rsa_subject(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, RSARawSsh2} = file:read_file(filename:join(Datadir, "ssh2_subject_pub")),
[{#'RSAPublicKey'{} = PubKey, Attributes}] =
@@ -406,7 +407,7 @@ ssh_rfc4716_rsa_subject(Config) when is_list(Config) ->
ssh_known_hosts() ->
[{doc, "ssh known hosts file encode/decode"}].
ssh_known_hosts(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, SshKnownHosts} = file:read_file(filename:join(Datadir, "known_hosts")),
[{#'RSAPublicKey'{}, Attributes1}, {#'RSAPublicKey'{}, Attributes2},
@@ -435,7 +436,7 @@ ssh_known_hosts(Config) when is_list(Config) ->
ssh1_known_hosts() ->
[{doc, "ssh (ver 1) known hosts file encode/decode"}].
ssh1_known_hosts(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, SshKnownHosts} = file:read_file(filename:join(Datadir, "ssh1_known_hosts")),
[{#'RSAPublicKey'{}, Attributes1}, {#'RSAPublicKey'{}, Attributes2},{#'RSAPublicKey'{}, Attributes3}]
@@ -455,7 +456,7 @@ ssh1_known_hosts(Config) when is_list(Config) ->
ssh_auth_keys() ->
[{doc, "ssh authorized keys file encode/decode"}].
ssh_auth_keys(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, SshAuthKeys} = file:read_file(filename:join(Datadir, "auth_keys")),
[{#'RSAPublicKey'{}, Attributes1}, {{_, #'Dss-Parms'{}}, Attributes2},
@@ -481,7 +482,7 @@ ssh_auth_keys(Config) when is_list(Config) ->
ssh1_auth_keys() ->
[{doc, "ssh (ver 1) authorized keys file encode/decode"}].
ssh1_auth_keys(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, SshAuthKeys} = file:read_file(filename:join(Datadir, "ssh1_auth_keys")),
[{#'RSAPublicKey'{}, Attributes1},
@@ -509,7 +510,7 @@ ssh1_auth_keys(Config) when is_list(Config) ->
ssh_openssh_public_key_with_comment() ->
[{doc, "Test that emty lines and lines starting with # are ignored"}].
ssh_openssh_public_key_with_comment(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, DSARawOpenSsh} = file:read_file(filename:join(Datadir, "openssh_dsa_with_comment_pub")),
[{{_, #'Dss-Parms'{}}, _}] = public_key:ssh_decode(DSARawOpenSsh, openssh_public_key).
@@ -518,7 +519,7 @@ ssh_openssh_public_key_with_comment(Config) when is_list(Config) ->
ssh_openssh_public_key_long_header() ->
[{doc, "Test that long headers are handled"}].
ssh_openssh_public_key_long_header(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok,RSARawOpenSsh} = file:read_file(filename:join(Datadir, "ssh_rsa_long_header_pub")),
[{#'RSAPublicKey'{}, _}] = Decoded = public_key:ssh_decode(RSARawOpenSsh, public_key),
@@ -577,7 +578,7 @@ dsa_sign_verify(Config) when is_list(Config) ->
public_key:pem_entry_decode(CertKey1),
true = public_key:pkix_verify(Cert2, {Y, #'Dss-Parms'{p=P, q=Q, g=G}}),
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
[DsaKey = {'DSAPrivateKey', _, _}] =
erl_make_certs:pem_to_der(filename:join(Datadir, "dsa.pem")),
DSAPrivateKey = public_key:pem_entry_decode(DsaKey),
@@ -606,7 +607,7 @@ dsa_sign_verify(Config) when is_list(Config) ->
pkix() ->
[{doc, "Misc pkix tests not covered elsewhere"}].
pkix(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
Certs0 = erl_make_certs:pem_to_der(filename:join(Datadir, "cacerts.pem")),
Certs1 = erl_make_certs:pem_to_der(filename:join(Datadir, "client_cert.pem")),
TestTransform = fun({'Certificate', CertDer, not_encrypted}) ->
@@ -749,7 +750,7 @@ pkix_iso_rsa_oid() ->
[{doc, "Test workaround for supporting certs that use ISO oids"
" 1.3.14.3.2.29 instead of PKIX/PKCS oid"}].
pkix_iso_rsa_oid(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, PemCert} = file:read_file(filename:join(Datadir, "rsa_ISO.pem")),
[{_, Cert, _}] = public_key:pem_decode(PemCert),
OTPCert = public_key:pkix_decode_cert(Cert, otp),
@@ -761,7 +762,7 @@ pkix_iso_dsa_oid() ->
[{doc, "Test workaround for supporting certs that use ISO oids"
"1.3.14.3.2.27 instead of PKIX/PKCS oid"}].
pkix_iso_dsa_oid(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, PemCert} = file:read_file(filename:join(Datadir, "dsa_ISO.pem")),
[{_, Cert, _}] = public_key:pem_decode(PemCert),
OTPCert = public_key:pkix_decode_cert(Cert, otp),
@@ -774,7 +775,7 @@ pkix_crl() ->
[{doc, "test pkix_crl_* functions"}].
pkix_crl(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
+ Datadir = proplists:get_value(data_dir, Config),
{ok, PemCRL} = file:read_file(filename:join(Datadir, "idp_crl.pem")),
[{_, CRL, _}] = public_key:pem_decode(PemCRL),
diff --git a/lib/runtime_tools/c_src/trace_ip_drv.c b/lib/runtime_tools/c_src/trace_ip_drv.c
index c73630f702..195558f958 100644
--- a/lib/runtime_tools/c_src/trace_ip_drv.c
+++ b/lib/runtime_tools/c_src/trace_ip_drv.c
@@ -374,6 +374,7 @@ static void trace_ip_output(ErlDrvData handle, char *buff, ErlDrvSizeT bufflen)
}
return;
}
+ ASSERT(!IS_INVALID_SOCKET(data->fd));
if (data->que[data->questart] != NULL) {
trace_ip_ready_output(handle, sock2event(data->fd));
}
@@ -412,6 +413,7 @@ static void trace_ip_ready_input(ErlDrvData handle, ErlDrvEvent fd)
/*
** Maybe accept, we are a listen port...
*/
+ ASSERT(IS_INVALID_SOCKET(data->fd));
if (!IS_INVALID_SOCKET((client = my_accept(data->listenfd)))) {
data->fd = client;
set_nonblocking(client);
@@ -735,6 +737,7 @@ static void close_client(TraceIpData *data)
{
my_driver_select(data, data->fd, FLAG_WRITE | FLAG_READ, SELECT_CLOSE);
data->flags |= FLAG_LISTEN_PORT;
+ data->fd = INVALID_SOCKET;
if (!(data->flags & FLAG_FILL_ALWAYS)) {
clean_que(data);
}
diff --git a/lib/runtime_tools/doc/src/dbg.xml b/lib/runtime_tools/doc/src/dbg.xml
index 103b8b52e9..49b11ddc3c 100644
--- a/lib/runtime_tools/doc/src/dbg.xml
+++ b/lib/runtime_tools/doc/src/dbg.xml
@@ -439,6 +439,50 @@ Error: fun containing local erlang function calls ('is_atomm' called in guard)\
global calls (and functions).</p>
</desc>
</func>
+
+
+ <func>
+ <name>tpe(Event, MatchSpec) -> {ok, MatchDesc} | {error, term()}</name>
+ <fsummary>Set pattern for traced event</fsummary>
+ <type>
+ <v>Event = send | 'receive'</v>
+ <v>MatchSpec = integer() | Built-inAlias | [] | match_spec()</v>
+ <v>Built-inAlias = x | c | cx</v>
+ <v>MatchDesc = [MatchInfo]</v>
+ <v>MatchInfo = {saved, integer()} | MatchNum</v>
+ <v>MatchNum = {matched, node(), 1} | {matched, node(), 0, RPCError}</v>
+ </type>
+ <desc>
+ <p>This function associates a match specification with trace event
+ <c>send</c> or <c>'receive'</c>. By default all executed <c>send</c>
+ and <c>'receive'</c> events are traced if enabled for a process.
+ A match specification can be used to filter traced events
+ based on sender, receiver and/or message content.</p>
+ <p>For a description of the <c>match_spec()</c> syntax,
+ please turn to the <em>User's guide</em> part of the online
+ documentation for the runtime system (<em>erts</em>). The
+ chapter <seealso marker="erts:match_spec"><em>Match Specifications in Erlang</em></seealso>
+ explains the general match specification "language".</p>
+ <p>For <c>send</c>, the matching is done on the list <c>[Receiver, Msg]</c>.
+ <c>Receiver</c> is the process or port identity of the receiver and
+ <c>Msg</c> is the message term. The pid of the sending process can be
+ accessed with the guard function <c>self/0</c>.</p>
+ <p>For <c>'receive'</c>, the matching is done on the list <c>[Node, Sender, Msg]</c>.
+ <c>Node</c> is the node name of the sender. <c>Sender</c> is the
+ process or port identity of the sender, or the atom
+ <c>undefined</c> if the sender is not known (which may
+ be the case for remote senders). <c>Msg</c> is the
+ message term. The pid of the receiving process can be
+ accessed with the guard function <c>self/0</c>.</p>
+ <p>All nodes added with <seealso marker="#n-1"><c>n/1</c></seealso> or
+ <seealso marker="#tracer-3"><c>tracer/3</c></seealso> will
+ be affected by this call.</p>
+ <p>The return value is the same as for
+ <seealso marker="#tp-2"><c>tp/2</c></seealso>. The number of matched
+ events are never larger than 1 as <c>tpe/2</c> does not
+ accept any form of wildcards for argument <c>Event</c>.</p>
+ </desc>
+ </func>
<func>
<name>ctp()</name>
<fsummary>Clear call trace pattern for the specified functions</fsummary>
@@ -563,6 +607,22 @@ Error: fun containing local erlang function calls ('is_atomm' called in guard)\
</desc>
</func>
<func>
+ <name>ctpe(Event) -> {ok, MatchDesc} | {error, term()}</name>
+ <fsummary>Clear trace pattern for the specified event</fsummary>
+ <type>
+ <v>Event = send | 'receive'</v>
+ <v>MatchDesc = [MatchNum]</v>
+ <v>MatchNum = {matched, node(), 1} | {matched, node(), 0, RPCError}</v>
+ </type>
+ <desc>
+ <p>This function clears match specifications for the specified
+ trace event (<c>send</c> or <c>'receive'</c>). It will revert back
+ to the default behavior of tracing all triggered events.</p>
+ <p>The return value follow the same style as for
+ <seealso marker="#ctp-1"><c>ctp/1</c></seealso>.</p>
+ </desc>
+ </func>
+ <func>
<name>ltp() -> ok</name>
<fsummary>List saved and built-in match specifications on the console.</fsummary>
<desc>
diff --git a/lib/stdlib/doc/src/ets.xml b/lib/stdlib/doc/src/ets.xml
index 0fdcf8282f..ad7591e214 100644
--- a/lib/stdlib/doc/src/ets.xml
+++ b/lib/stdlib/doc/src/ets.xml
@@ -123,8 +123,9 @@
<p>Some of the functions uses a <em>match specification</em>,
match_spec. A brief explanation is given in
<seealso marker="#select/2">select/2</seealso>. For a detailed
- description, see the chapter "Match specifications in Erlang" in
- <em>ERTS User's Guide</em>.</p>
+ description, see chapter
+ <seealso marker="erts:match_spec">Match Specifications in Erlang</seealso>
+ in <em>ERTS User's Guide</em>.</p>
</section>
<datatypes>
diff --git a/lib/wx/api_gen/gl_gen.erl b/lib/wx/api_gen/gl_gen.erl
index 0473b7d771..54635bdd2e 100644
--- a/lib/wx/api_gen/gl_gen.erl
+++ b/lib/wx/api_gen/gl_gen.erl
@@ -191,8 +191,9 @@ parse_define([#xmlElement{name=initializer,content=Contents}|_R],Def,_Os) ->
try
case Val0 of
"0x" ++ Val1 ->
- _ = list_to_integer(Val1, 16),
- Def#def{val=Val1, type=hex};
+ Val2 = strip_type_cast(Val1),
+ _ = list_to_integer(Val2, 16),
+ Def#def{val=Val2, type=hex};
_ ->
Val = list_to_integer(Val0),
Def#def{val=Val, type=int}
@@ -214,6 +215,15 @@ extract_def2([#xmlElement{content=Cs}|R]) ->
extract_def2(Cs) ++ extract_def2(R);
extract_def2([]) -> [].
+strip_type_cast(Int) ->
+ lists:reverse(strip_type_cast2(lists:reverse(Int))).
+
+strip_type_cast2("u"++Rest) -> Rest; %% unsigned
+strip_type_cast2("lu"++Rest) -> Rest; %% unsigned long
+strip_type_cast2("llu"++Rest) -> Rest; %% unsigned long long
+strip_type_cast2(Rest) -> Rest.
+
+
strip_comment("/*" ++ Rest) ->
strip_comment_until_end(Rest);
strip_comment("//" ++ _) -> [];
diff --git a/lib/wx/c_src/wxe_helpers.cpp b/lib/wx/c_src/wxe_helpers.cpp
index 4798e605e8..d1f607d2af 100644
--- a/lib/wx/c_src/wxe_helpers.cpp
+++ b/lib/wx/c_src/wxe_helpers.cpp
@@ -48,7 +48,7 @@ void wxeCommand::Delete()
driver_free(buffer);
buffer = NULL;
}
- op = -1;
+ op = -2;
}
/* ****************************************************************************
@@ -84,7 +84,7 @@ wxeCommand * wxeFifo::Get()
pos = m_first++;
m_n--;
m_first %= m_max;
- } while(m_q[pos].op == -1);
+ } while(m_q[pos].op < 0);
return &m_q[pos];
}
@@ -96,7 +96,7 @@ wxeCommand * wxeFifo::Peek(unsigned int *i)
return NULL;
pos = (m_first+*i) % m_max;
(*i)++;
- } while(m_q[pos].op == -1);
+ } while(m_q[pos].op < 0);
return &m_q[pos];
}
@@ -213,7 +213,7 @@ void wxeFifo::Realloc()
// Strip end of queue if ops are already taken care of, avoids reallocs
void wxeFifo::Strip()
{
- while((m_n > 0) && (m_q[(m_first + m_n - 1)%m_max].op == -1)) {
+ while((m_n > 0) && (m_q[(m_first + m_n - 1)%m_max].op < -1)) {
m_n--;
}
}
diff --git a/lib/wx/include/gl.hrl b/lib/wx/include/gl.hrl
index 39cd474fcb..d708515e1b 100644
--- a/lib/wx/include/gl.hrl
+++ b/lib/wx/include/gl.hrl
@@ -1723,7 +1723,7 @@
-define(GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER, 16#8A44).
-define(GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER, 16#8A45).
-define(GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, 16#8A46).
--define(GL_INVALID_INDEX, 16#FFFFFFFFu).
+-define(GL_INVALID_INDEX, 16#FFFFFFFF).
-define(GL_COPY_READ_BUFFER, 16#8F36).
-define(GL_COPY_WRITE_BUFFER, 16#8F37).
-define(GL_DEPTH_CLAMP, 16#864F).
@@ -1746,7 +1746,7 @@
-define(GL_CONDITION_SATISFIED, 16#911C).
-define(GL_WAIT_FAILED, 16#911D).
-define(GL_SYNC_FLUSH_COMMANDS_BIT, 16#00000001).
--define(GL_TIMEOUT_IGNORED, 16#FFFFFFFFFFFFFFFFull).
+-define(GL_TIMEOUT_IGNORED, 16#FFFFFFFFFFFFFFFF).
-define(GL_SAMPLE_POSITION, 16#8E50).
-define(GL_SAMPLE_MASK, 16#8E51).
-define(GL_SAMPLE_MASK_VALUE, 16#8E52).
diff --git a/lib/wx/test/wx_class_SUITE.erl b/lib/wx/test/wx_class_SUITE.erl
index 6944a78360..0a3c4659bf 100644
--- a/lib/wx/test/wx_class_SUITE.erl
+++ b/lib/wx/test/wx_class_SUITE.erl
@@ -646,8 +646,8 @@ modal(Config) ->
%% need to sleep so we know that the window is stuck in
%% the ShowModal event loop and not in an earlier event loop
%% wx2.8 invokes the event loop from more calls than wx-3
- receive {dialog, M1, 1} -> timer:sleep(1200), ets:insert(test_state, {M1, ready}) end,
- receive {dialog, M2, 2} -> timer:sleep(1200), ets:insert(test_state, {M2, ready}) end,
+ M1 = receive {dialog, W1, 1} -> timer:sleep(1200), ets:insert(test_state, {W1, ready}), W1 end,
+ M2 = receive {dialog, W2, 2} -> timer:sleep(1200), ets:insert(test_state, {W2, ready}), W2 end,
receive done -> ok end,
receive {dialog_done, M2, 2} -> M2 end,