aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/test')
-rw-r--r--erts/emulator/test/alloc_SUITE.erl7
-rw-r--r--erts/emulator/test/big_SUITE.erl7
-rw-r--r--erts/emulator/test/distribution_SUITE.erl98
-rw-r--r--erts/emulator/test/driver_SUITE.erl81
-rw-r--r--erts/emulator/test/efile_SUITE.erl49
-rw-r--r--erts/emulator/test/emulator_smoke.spec1
-rw-r--r--erts/emulator/test/erl_link_SUITE.erl85
-rw-r--r--erts/emulator/test/estone_SUITE.erl33
-rw-r--r--erts/emulator/test/exception_SUITE.erl82
-rw-r--r--erts/emulator/test/map_SUITE_data/badmap_17.beambin592 -> 1192 bytes
-rw-r--r--erts/emulator/test/map_SUITE_data/badmap_17.erl36
-rw-r--r--erts/emulator/test/nif_SUITE.erl11
-rw-r--r--erts/emulator/test/node_container_SUITE.erl1
-rw-r--r--erts/emulator/test/port_trace_SUITE.erl7
-rw-r--r--erts/emulator/test/scheduler_SUITE.erl13
-rw-r--r--erts/emulator/test/signal_SUITE.erl123
-rw-r--r--erts/emulator/test/smoke_test_SUITE.erl6
-rw-r--r--erts/emulator/test/statistics_SUITE.erl4
-rw-r--r--erts/emulator/test/system_profile_SUITE.erl5
-rw-r--r--erts/emulator/test/tuple_SUITE.erl7
20 files changed, 390 insertions, 266 deletions
diff --git a/erts/emulator/test/alloc_SUITE.erl b/erts/emulator/test/alloc_SUITE.erl
index 3a721095e2..f0871ead7d 100644
--- a/erts/emulator/test/alloc_SUITE.erl
+++ b/erts/emulator/test/alloc_SUITE.erl
@@ -65,12 +65,7 @@ mseg_clear_cache(Cfg) -> drv_case(Cfg).
cpool(Cfg) -> drv_case(Cfg).
migration(Cfg) ->
- case erlang:system_info(smp_support) of
- true ->
- drv_case(Cfg, concurrent, "+MZe true");
- false ->
- {skipped, "No smp"}
- end.
+ drv_case(Cfg, concurrent, "+MZe true").
erts_mmap(Config) when is_list(Config) ->
case {os:type(), mmsc_flags()} of
diff --git a/erts/emulator/test/big_SUITE.erl b/erts/emulator/test/big_SUITE.erl
index c308760211..5939d024ae 100644
--- a/erts/emulator/test/big_SUITE.erl
+++ b/erts/emulator/test/big_SUITE.erl
@@ -339,6 +339,13 @@ system_limit(Config) when is_list(Config) ->
{'EXIT',{system_limit,_}} = (catch apply(erlang, id('bsl'), [Maxbig,2])),
{'EXIT',{system_limit,_}} = (catch id(1) bsl (1 bsl 45)),
{'EXIT',{system_limit,_}} = (catch id(1) bsl (1 bsl 69)),
+
+ %% There should be no system_limit exception when shifting a zero.
+ 0 = id(0) bsl (1 bsl 128),
+ 0 = id(0) bsr -(1 bsl 128),
+ Erlang = id(erlang),
+ 0 = Erlang:'bsl'(id(0), 1 bsl 128),
+ 0 = Erlang:'bsr'(id(0), -(1 bsl 128)),
ok.
maxbig() ->
diff --git a/erts/emulator/test/distribution_SUITE.erl b/erts/emulator/test/distribution_SUITE.erl
index b4ec99f902..28be4bfe37 100644
--- a/erts/emulator/test/distribution_SUITE.erl
+++ b/erts/emulator/test/distribution_SUITE.erl
@@ -418,18 +418,20 @@ make_busy(Node, Time) when is_integer(Time) ->
Own = 500,
freeze_node(Node, Time+Own),
Data = make_busy_data(),
+ DCtrl = dctrl(Node),
%% first make port busy
Pid = spawn_link(fun () ->
forever(fun () ->
- dport_reg_send(Node,
- '__noone__',
- Data)
+ dctrl_dop_reg_send(Node,
+ '__noone__',
+ Data)
end)
end),
receive after Own -> ok end,
until(fun () ->
- case process_info(Pid, status) of
- {status, suspended} -> true;
+ case {DCtrl, process_info(Pid, status)} of
+ {DPrt, {status, suspended}} when is_port(DPrt) -> true;
+ {DPid, {status, waiting}} when is_pid(DPid) -> true;
_ -> false
end
end),
@@ -1703,37 +1705,38 @@ bad_dist_ext_check_msgs([M|Ms]) ->
bad_dist_ext_check_msgs(Ms)
end.
+ensure_dctrl(Node) ->
+ case dctrl(Node) of
+ undefined ->
+ pong = net_adm:ping(Node),
+ dctrl(Node);
+ DCtrl ->
+ DCtrl
+ end.
-dport_reg_send(Node, Name, Msg) ->
- DPrt = case dport(Node) of
- undefined ->
- pong = net_adm:ping(Node),
- dport(Node);
- Prt ->
- Prt
- end,
- port_command(DPrt, [dmsg_hdr(),
- dmsg_ext({?DOP_REG_SEND,
- self(),
- ?COOKIE,
- Name}),
- dmsg_ext(Msg)]).
-
-
-dport_send(To, Msg) ->
+dctrl_send(DPrt, Data) when is_port(DPrt) ->
+ port_command(DPrt, Data);
+dctrl_send(DPid, Data) when is_pid(DPid) ->
+ Ref = make_ref(),
+ DPid ! {send, self(), Ref, Data},
+ receive {Ref, Res} -> Res end.
+
+dctrl_dop_reg_send(Node, Name, Msg) ->
+ dctrl_send(ensure_dctrl(Node),
+ [dmsg_hdr(),
+ dmsg_ext({?DOP_REG_SEND,
+ self(),
+ ?COOKIE,
+ Name}),
+ dmsg_ext(Msg)]).
+
+dctrl_dop_send(To, Msg) ->
Node = node(To),
- DPrt = case dport(Node) of
- undefined ->
- pong = net_adm:ping(Node),
- dport(Node);
- Prt ->
- Prt
- end,
- port_command(DPrt, [dmsg_hdr(),
- dmsg_ext({?DOP_SEND,
- ?COOKIE,
- To}),
- dmsg_ext(Msg)]).
+ dctrl_send(ensure_dctrl(Node),
+ [dmsg_hdr(),
+ dmsg_ext({?DOP_SEND, ?COOKIE, To}),
+ dmsg_ext(Msg)]).
+
send_bad_structure(Offender,Victim,Bad,WhereToPutSelf) ->
send_bad_structure(Offender,Victim,Bad,WhereToPutSelf,[]).
send_bad_structure(Offender,Victim,Bad,WhereToPutSelf,PayLoad) ->
@@ -1743,7 +1746,7 @@ send_bad_structure(Offender,Victim,Bad,WhereToPutSelf,PayLoad) ->
fun () ->
Node = node(Victim),
pong = net_adm:ping(Node),
- DPrt = dport(Node),
+ DCtrl = dctrl(Node),
Bad1 = case WhereToPutSelf of
0 ->
Bad;
@@ -1756,7 +1759,7 @@ send_bad_structure(Offender,Victim,Bad,WhereToPutSelf,PayLoad) ->
[] -> [];
_Other -> [dmsg_ext(PayLoad)]
end,
- port_command(DPrt, DData),
+ dctrl_send(DCtrl, DData),
Parent ! {DData,Done}
end),
receive
@@ -1784,11 +1787,11 @@ send_bad_msgs(BadNode, To, Repeat) when is_atom(BadNode),
fun () ->
Node = node(To),
pong = net_adm:ping(Node),
- DPrt = dport(Node),
+ DCtrl = dctrl(Node),
DData = [dmsg_hdr(),
dmsg_ext({?DOP_SEND, ?COOKIE, To}),
dmsg_bad_atom_cache_ref()],
- repeat(fun () -> port_command(DPrt, DData) end, Repeat),
+ repeat(fun () -> dctrl_send(DCtrl, DData) end, Repeat),
Parent ! Done
end),
receive Done -> ok end.
@@ -1810,11 +1813,12 @@ send_bad_ctl(BadNode, ToNode) when is_atom(BadNode), is_atom(ToNode) ->
replace}),
CtlBeginSize = size(Ctl) - size(Replace),
<<CtlBegin:CtlBeginSize/binary, Replace/binary>> = Ctl,
- port_command(dport(ToNode),
- [dmsg_fake_hdr2(),
- CtlBegin,
- dmsg_bad_atom_cache_ref(),
- dmsg_ext({a, message})]),
+ DCtrl = dctrl(ToNode),
+ Data = [dmsg_fake_hdr2(),
+ CtlBegin,
+ dmsg_bad_atom_cache_ref(),
+ dmsg_ext({a, message})],
+ dctrl_send(DCtrl, Data),
Parent ! Done
end),
receive Done -> ok end.
@@ -1827,17 +1831,17 @@ send_bad_dhdr(BadNode, ToNode) when is_atom(BadNode), is_atom(ToNode) ->
spawn_link(BadNode,
fun () ->
pong = net_adm:ping(ToNode),
- port_command(dport(ToNode), dmsg_bad_hdr()),
+ dctrl_send(dctrl(ToNode), dmsg_bad_hdr()),
Parent ! Done
end),
receive Done -> ok end.
-dport(Node) when is_atom(Node) ->
+dctrl(Node) when is_atom(Node) ->
case catch erts_debug:get_internal_state(available_internal_state) of
true -> true;
_ -> erts_debug:set_internal_state(available_internal_state, true)
end,
- erts_debug:get_internal_state({dist_port, Node}).
+ erts_debug:get_internal_state({dist_ctrl, Node}).
dmsg_hdr() ->
[131, % Version Magic
@@ -1979,7 +1983,7 @@ freeze_node(Node, MS) ->
fun () ->
erts_debug:set_internal_state(available_internal_state,
true),
- dport_send(Freezer, DoingIt),
+ dctrl_dop_send(Freezer, DoingIt),
receive after Own -> ok end,
erts_debug:set_internal_state(block, MS+Own)
end),
diff --git a/erts/emulator/test/driver_SUITE.erl b/erts/emulator/test/driver_SUITE.erl
index 6810729285..5fca191679 100644
--- a/erts/emulator/test/driver_SUITE.erl
+++ b/erts/emulator/test/driver_SUITE.erl
@@ -1144,8 +1144,6 @@ check_si_res(["thread", "false"]) ->
false = erlang:system_info(threads);
check_si_res(["smp", "true"]) ->
true = erlang:system_info(smp_support);
-check_si_res(["smp", "false"]) ->
- false = erlang:system_info(smp_support);
%% Data added in second version of driver_system_info() (driver version 1.1)
check_si_res(["async_thrs", Value]) ->
@@ -1944,44 +1942,39 @@ thr_msg_blast_receiver_proc(Port, Max, Parent, Done) ->
end.
thr_msg_blast(Config) when is_list(Config) ->
- case erlang:system_info(smp_support) of
- false ->
- {skipped, "Non-SMP emulator; nothing to test..."};
- true ->
- Path = proplists:get_value(data_dir, Config),
- erl_ddll:start(),
- ok = load_driver(Path, thr_msg_blast_drv),
- MemBefore = driver_alloc_size(),
- Start = os:timestamp(),
- Port = open_port({spawn, thr_msg_blast_drv}, []),
- true = is_port(Port),
- Done = make_ref(),
- Me = self(),
- spawn(fun () ->
- thr_msg_blast_receiver_proc(Port, 1, Me, Done)
- end),
- receive
- Done -> ok
- end,
- ok = thr_msg_blast_receiver(Port, 0, 32*10000),
- port_close(Port),
- End = os:timestamp(),
- receive
- Garbage ->
- ct:fail({received_garbage, Port, Garbage})
- after 2000 ->
- ok
- end,
- MemAfter = driver_alloc_size(),
- io:format("MemBefore=~p, MemAfter=~p~n",
- [MemBefore, MemAfter]),
- ThrMsgBlastTime = timer:now_diff(End,Start)/1000000,
- io:format("ThrMsgBlastTime=~p~n", [ThrMsgBlastTime]),
- MemBefore = MemAfter,
- Res = {thr_msg_blast_time, ThrMsgBlastTime},
- erlang:display(Res),
- Res
- end.
+ Path = proplists:get_value(data_dir, Config),
+ erl_ddll:start(),
+ ok = load_driver(Path, thr_msg_blast_drv),
+ MemBefore = driver_alloc_size(),
+ Start = os:timestamp(),
+ Port = open_port({spawn, thr_msg_blast_drv}, []),
+ true = is_port(Port),
+ Done = make_ref(),
+ Me = self(),
+ spawn(fun () ->
+ thr_msg_blast_receiver_proc(Port, 1, Me, Done)
+ end),
+ receive
+ Done -> ok
+ end,
+ ok = thr_msg_blast_receiver(Port, 0, 32*10000),
+ port_close(Port),
+ End = os:timestamp(),
+ receive
+ Garbage ->
+ ct:fail({received_garbage, Port, Garbage})
+ after 2000 ->
+ ok
+ end,
+ MemAfter = driver_alloc_size(),
+ io:format("MemBefore=~p, MemAfter=~p~n",
+ [MemBefore, MemAfter]),
+ ThrMsgBlastTime = timer:now_diff(End,Start)/1000000,
+ io:format("ThrMsgBlastTime=~p~n", [ThrMsgBlastTime]),
+ MemBefore = MemAfter,
+ Res = {thr_msg_blast_time, ThrMsgBlastTime},
+ erlang:display(Res),
+ Res.
-define(IN_RANGE(LoW_, VaLuE_, HiGh_),
case in_range(LoW_, VaLuE_, HiGh_) of
@@ -2488,14 +2481,6 @@ wait_deallocations() ->
end.
driver_alloc_size() ->
- case erlang:system_info(smp_support) of
- true ->
- ok;
- false ->
- %% driver_alloc also used by elements in lock-free queues,
- %% give these some time to be deallocated...
- receive after 100 -> ok end
- end,
wait_deallocations(),
case erlang:system_info({allocator_sizes, driver_alloc}) of
false ->
diff --git a/erts/emulator/test/efile_SUITE.erl b/erts/emulator/test/efile_SUITE.erl
index f0e1bcf04b..08d5597d78 100644
--- a/erts/emulator/test/efile_SUITE.erl
+++ b/erts/emulator/test/efile_SUITE.erl
@@ -19,16 +19,20 @@
-module(efile_SUITE).
-export([all/0, suite/0]).
--export([iter_max_files/1, async_dist/1]).
+-export([async_dist/1,
+ iter_max_files/1,
+ proc_zero_sized_files/1
+ ]).
-export([do_iter_max_files/2, do_async_dist/1]).
-include_lib("common_test/include/ct.hrl").
+-include_lib("stdlib/include/assert.hrl").
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [iter_max_files, async_dist].
+ [iter_max_files, async_dist, proc_zero_sized_files].
do_async_dist(Dir) ->
X = 100,
@@ -162,3 +166,44 @@ open_files(Name) ->
% io:format("Error reason: ~p", [_Reason]),
[]
end.
+
+%% @doc If /proc filesystem exists (no way to know if it is real proc or just
+%% a /proc directory), let's read some zero sized files 500 times each, while
+%% ensuring that response isn't empty << >>
+proc_zero_sized_files(Config) when is_list(Config) ->
+ {Type, Flavor} = os:type(),
+ %% Some files which exist on Linux but might be missing on other systems
+ Inputs = ["/proc/cpuinfo",
+ "/proc/meminfo",
+ "/proc/partitions",
+ "/proc/swaps",
+ "/proc/version",
+ "/proc/uptime",
+ %% curproc is present on freebsd
+ "/proc/curproc/cmdline"],
+ case filelib:is_dir("/proc") of
+ false -> {skip, "/proc not found"}; % skip the test if no /proc
+ _ when Type =:= unix andalso Flavor =:= sunos ->
+ %% SunOS has a /proc, but no zero sized special files
+ {skip, "sunos does not have any zero sized special files"};
+ true ->
+ %% Take away files which do not exist in proc
+ Inputs1 = lists:filter(fun filelib:is_file/1, Inputs),
+
+ %% Fail if none of mentioned files exist in /proc, did we just get
+ %% a normal /proc directory without any special files?
+ ?assertNotEqual([], Inputs1),
+
+ %% For 6 inputs and 500 attempts each this do run anywhere
+ %% between 500 and 3000 function calls.
+ lists:foreach(
+ fun(Filename) -> do_proc_zero_sized(Filename, 500) end,
+ Inputs1)
+ end.
+
+%% @doc Test one file N times to also trigger possible leaking fds and memory
+do_proc_zero_sized(_Filename, 0) -> ok;
+do_proc_zero_sized(Filename, N) ->
+ Data = file:read_file(Filename),
+ ?assertNotEqual(<<>>, Data),
+ do_proc_zero_sized(Filename, N-1).
diff --git a/erts/emulator/test/emulator_smoke.spec b/erts/emulator/test/emulator_smoke.spec
index b2d0de8835..fc98ba6823 100644
--- a/erts/emulator/test/emulator_smoke.spec
+++ b/erts/emulator/test/emulator_smoke.spec
@@ -7,3 +7,4 @@
[consistency],"Not reliable in October and March"}.
{cases,'Dir',crypto_SUITE,[t_md5]}.
{cases,'Dir',float_SUITE,[fpe,cmp_integer]}.
+{cases,'Dir',erts_debug_SUITE,[df]}.
diff --git a/erts/emulator/test/erl_link_SUITE.erl b/erts/emulator/test/erl_link_SUITE.erl
index 5622cce980..d8c5b663e3 100644
--- a/erts/emulator/test/erl_link_SUITE.erl
+++ b/erts/emulator/test/erl_link_SUITE.erl
@@ -533,7 +533,7 @@ freeze_node(Node, MS) ->
fun () ->
erts_debug:set_internal_state(available_internal_state,
true),
- dport_send(Freezer, DoingIt),
+ dctrl_dop_send(Freezer, DoingIt),
receive after Own -> ok end,
erts_debug:set_internal_state(block, MS+Own)
end),
@@ -544,20 +544,22 @@ make_busy(Node, Time) when is_integer(Time) ->
Own = 500,
freeze_node(Node, Time+Own),
Data = busy_data(),
+ DCtrl = dctrl(Node),
%% first make port busy
Pid = spawn_link(fun () ->
forever(fun () ->
- dport_reg_send(Node,
- '__noone__',
- Data)
+ dctrl_dop_reg_send(Node,
+ '__noone__',
+ Data)
end)
end),
receive after Own -> ok end,
wait_until(fun () ->
- case process_info(Pid, status) of
- {status, suspended} -> true;
- _ -> false
- end
+ case {DCtrl, process_info(Pid, status)} of
+ {DPrt, {status, suspended}} when is_port(DPrt) -> true;
+ {DPid, {status, waiting}} when is_pid(DPid) -> true;
+ _ -> false
+ end
end),
%% then dist entry
make_busy(Node, [nosuspend], Data),
@@ -1048,42 +1050,45 @@ stop_node(Node) ->
-define(DOP_DEMONITOR_P, 20).
-define(DOP_MONITOR_P_EXIT, 21).
-dport_send(To, Msg) ->
- Node = node(To),
- DPrt = case dport(Node) of
- undefined ->
- pong = net_adm:ping(Node),
- dport(Node);
- Prt ->
- Prt
- end,
- port_command(DPrt, [dmsg_hdr(),
- dmsg_ext({?DOP_SEND,
- ?COOKIE,
- To}),
- dmsg_ext(Msg)]).
-
-dport_reg_send(Node, Name, Msg) ->
- DPrt = case dport(Node) of
- undefined ->
- pong = net_adm:ping(Node),
- dport(Node);
- Prt ->
- Prt
- end,
- port_command(DPrt, [dmsg_hdr(),
- dmsg_ext({?DOP_REG_SEND,
- self(),
- ?COOKIE,
- Name}),
- dmsg_ext(Msg)]).
-
-dport(Node) when is_atom(Node) ->
+ensure_dctrl(Node) ->
+ case dctrl(Node) of
+ undefined ->
+ pong = net_adm:ping(Node),
+ dctrl(Node);
+ DCtrl ->
+ DCtrl
+ end.
+
+dctrl_send(DPrt, Data) when is_port(DPrt) ->
+ port_command(DPrt, Data);
+dctrl_send(DPid, Data) when is_pid(DPid) ->
+ Ref = make_ref(),
+ DPid ! {send, self(), Ref, Data},
+ receive {Ref, Res} -> Res end.
+
+dctrl_dop_send(To, Msg) ->
+ dctrl_send(ensure_dctrl(node(To)),
+ [dmsg_hdr(),
+ dmsg_ext({?DOP_SEND,
+ ?COOKIE,
+ To}),
+ dmsg_ext(Msg)]).
+
+dctrl_dop_reg_send(Node, Name, Msg) ->
+ dctrl_send(ensure_dctrl(Node),
+ [dmsg_hdr(),
+ dmsg_ext({?DOP_REG_SEND,
+ self(),
+ ?COOKIE,
+ Name}),
+ dmsg_ext(Msg)]).
+
+dctrl(Node) when is_atom(Node) ->
case catch erts_debug:get_internal_state(available_internal_state) of
true -> true;
_ -> erts_debug:set_internal_state(available_internal_state, true)
end,
- erts_debug:get_internal_state({dist_port, Node}).
+ erts_debug:get_internal_state({dist_ctrl, Node}).
dmsg_hdr() ->
[131, % Version Magic
diff --git a/erts/emulator/test/estone_SUITE.erl b/erts/emulator/test/estone_SUITE.erl
index 8b336b366d..c9c1867049 100644
--- a/erts/emulator/test/estone_SUITE.erl
+++ b/erts/emulator/test/estone_SUITE.erl
@@ -20,7 +20,7 @@
-module(estone_SUITE).
%% Test functions
-export([all/0, suite/0, groups/0,
- estone/1, estone_bench/1]).
+ estone/1, estone_bench/1, pgo/0]).
%% Internal exports for EStone tests
-export([lists/1,
@@ -44,9 +44,9 @@
links/1,lproc/1,
run_micro/3,p1/1,ppp/3,macro/2,micros/0]).
-
--include_lib("common_test/include/ct.hrl").
+-ifndef(PGO).
-include_lib("common_test/include/ct_event.hrl").
+-endif.
%% EStone defines
-define(TOTAL, (3000 * 1000 * 100)). %% 300 secs
@@ -85,13 +85,28 @@ estone(Config) when is_list(Config) ->
estone_bench(Config) ->
DataDir = proplists:get_value(data_dir,Config),
L = ?MODULE:macro(?MODULE:micros(),DataDir),
- [ct_event:notify(
- #event{name = benchmark_data,
- data = [{name,proplists:get_value(title,Mark)},
- {value,proplists:get_value(estones,Mark)}]})
- || Mark <- L],
+ {Total, Stones} = sum_micros(L, 0, 0),
+ notify([[{title,"ESTONES"}, {estones, Stones}] | L]),
L.
+-ifndef(PGO).
+notify(Marks) ->
+ [ct_event:notify(
+ #event{name = benchmark_data,
+ data = [{name,proplists:get_value(title, Mark)},
+ {value,proplists:get_value(estones, Mark)}]})
+ || Mark <- Marks].
+-else.
+notify(_) ->
+ ok.
+-endif.
+
+%% The benchmarks to run in order to guide PGO (profile guided optimisation)
+pgo() ->
+ %% We run all benchmarks except the port_io as we don't want to
+ %% have to build a custom port.
+ Micros = ?MODULE:micros() -- [micro(port_io)],
+ ?MODULE:macro(Micros,[]).
%%
%% Calculate CPU speed
@@ -364,7 +379,7 @@ monotonic_time() ->
try erlang:monotonic_time() catch error:undef -> erlang:now() end.
subtr(Before, After) when is_integer(Before), is_integer(After) ->
- erlang:convert_time_unit(After-Before, native, microsecond);
+ erlang:convert_time_unit(After-Before, native, 1000000);
subtr({_,_,_}=Before, {_,_,_}=After) ->
timer:now_diff(After, Before).
diff --git a/erts/emulator/test/exception_SUITE.erl b/erts/emulator/test/exception_SUITE.erl
index aaca522da6..e473a10be7 100644
--- a/erts/emulator/test/exception_SUITE.erl
+++ b/erts/emulator/test/exception_SUITE.erl
@@ -21,7 +21,7 @@
-module(exception_SUITE).
-export([all/0, suite/0,
- badmatch/1, pending_errors/1, nil_arith/1,
+ badmatch/1, pending_errors/1, nil_arith/1, top_of_stacktrace/1,
stacktrace/1, nested_stacktrace/1, raise/1, gunilla/1, per/1,
exception_with_heap_frag/1, line_numbers/1]).
@@ -36,8 +36,8 @@ suite() ->
{timetrap, {minutes, 1}}].
all() ->
- [badmatch, pending_errors, nil_arith, stacktrace,
- nested_stacktrace, raise, gunilla, per,
+ [badmatch, pending_errors, nil_arith, top_of_stacktrace,
+ stacktrace, nested_stacktrace, raise, gunilla, per,
exception_with_heap_frag, line_numbers].
-define(try_match(E),
@@ -241,7 +241,54 @@ ba_bnot(A) ->
io:format("bnot ~p", [A]),
{'EXIT', {badarith, _}} = (catch bnot A).
+%% Test that BIFs are added to the top of the stacktrace.
+
+top_of_stacktrace(Conf) when is_list(Conf) ->
+ %% Arithmetic operators
+ {'EXIT', {badarith, [{erlang, '+', [1, ok], _} | _]}} = (catch my_add(1, ok)),
+ {'EXIT', {badarith, [{erlang, '-', [1, ok], _} | _]}} = (catch my_minus(1, ok)),
+ {'EXIT', {badarith, [{erlang, '*', [1, ok], _} | _]}} = (catch my_times(1, ok)),
+ {'EXIT', {badarith, [{erlang, 'div', [1, ok], _} | _]}} = (catch my_div(1, ok)),
+ {'EXIT', {badarith, [{erlang, 'div', [1, 0], _} | _]}} = (catch my_div(1, 0)),
+ {'EXIT', {badarith, [{erlang, 'rem', [1, ok], _} | _]}} = (catch my_rem(1, ok)),
+ {'EXIT', {badarith, [{erlang, 'rem', [1, 0], _} | _]}} = (catch my_rem(1, 0)),
+
+ %% Bit operators
+ {'EXIT', {badarith, [{erlang, 'band', [1, ok], _} | _]}} = (catch my_band(1, ok)),
+ {'EXIT', {badarith, [{erlang, 'bor', [1, ok], _} | _]}} = (catch my_bor(1, ok)),
+ {'EXIT', {badarith, [{erlang, 'bsl', [1, ok], _} | _]}} = (catch my_bsl(1, ok)),
+ {'EXIT', {badarith, [{erlang, 'bsr', [1, ok], _} | _]}} = (catch my_bsr(1, ok)),
+ {'EXIT', {badarith, [{erlang, 'bxor', [1, ok], _} | _]}} = (catch my_bxor(1, ok)),
+ {'EXIT', {badarith, [{erlang, 'bnot', [ok], _} | _]}} = (catch my_bnot(ok)),
+
+ %% Tuples
+ {'EXIT', {badarg, [{erlang, element, [1, ok], _} | _]}} = (catch my_element(1, ok)),
+ {'EXIT', {badarg, [{erlang, element, [ok, {}], _} | _]}} = (catch my_element(ok, {})),
+ {'EXIT', {badarg, [{erlang, element, [1, {}], _} | _]}} = (catch my_element(1, {})),
+ {'EXIT', {badarg, [{erlang, element, [1, {}], _} | _]}} = (catch element(1, erlang:make_tuple(0, ok))),
+
+ %% System limits
+ Maxbig = maxbig(),
+ MinusMaxbig = -Maxbig,
+ {'EXIT', {system_limit, [{erlang, '+', [Maxbig, 1], _} | _]}} = (catch my_add(Maxbig, 1)),
+ {'EXIT', {system_limit, [{erlang, '+', [Maxbig, 1], _} | _]}} = (catch my_add(maxbig_gc(), 1)),
+ {'EXIT', {system_limit, [{erlang, '-', [MinusMaxbig, 1], _} | _]}} = (catch my_minus(-Maxbig, 1)),
+ {'EXIT', {system_limit, [{erlang, '-', [MinusMaxbig, 1], _} | _]}} = (catch my_minus(-maxbig_gc(), 1)),
+ {'EXIT', {system_limit, [{erlang, '*', [Maxbig, 2], _} | _]}} = (catch my_times(Maxbig, 2)),
+ {'EXIT', {system_limit, [{erlang, '*', [Maxbig, 2], _} | _]}} = (catch my_times(maxbig_gc(), 2)),
+ {'EXIT', {system_limit, [{erlang, 'bnot', [Maxbig], _} | _]}} = (catch my_bnot(Maxbig)),
+ {'EXIT', {system_limit, [{erlang, 'bnot', [Maxbig], _} | _]}} = (catch my_bnot(maxbig_gc())),
+ ok.
+
+maxbig() ->
+ %% We assume that the maximum arity is (1 bsl 19) - 1.
+ Ws = erlang:system_info(wordsize),
+ (((1 bsl ((16777184 * (Ws div 4))-1)) - 1) bsl 1) + 1.
+maxbig_gc() ->
+ Maxbig = maxbig(),
+ erlang:garbage_collect(),
+ Maxbig.
stacktrace(Conf) when is_list(Conf) ->
Tag = make_ref(),
@@ -253,9 +300,9 @@ stacktrace(Conf) when is_list(Conf) ->
St1 = erase(stacktrace1),
St1 = erase(stacktrace2),
St1 = erlang:get_stacktrace(),
- {caught2,{error,badarith},[{?MODULE,my_add,2,_}|_]=St2} =
+ {caught2,{error,badarith},[{erlang,'+',[0,a],_},{?MODULE,my_add,2,_}|_]=St2} =
stacktrace_1({'div',{1,0}}, error, {'add',{0,a}}),
- [{?MODULE,my_div,2,_}|_] = erase(stacktrace1),
+ [{erlang,'div',[1,0],_},{?MODULE,my_div,2,_}|_] = erase(stacktrace1),
St2 = erase(stacktrace2),
St2 = erlang:get_stacktrace(),
{caught2,{error,{try_clause,V}},[{?MODULE,stacktrace_1,3,_}|_]=St3} =
@@ -308,13 +355,13 @@ nested_stacktrace(Conf) when is_list(Conf) ->
nested_stacktrace_1({{value,{V,x1}},void,{V,x1}},
{void,void,void}),
{caught1,
- [{?MODULE,my_add,2,_}|_],
+ [{erlang,'+',[V,x1],_},{?MODULE,my_add,2,_}|_],
value2,
- [{?MODULE,my_add,2,_}|_]} =
+ [{erlang,'+',[V,x1],_},{?MODULE,my_add,2,_}|_]} =
nested_stacktrace_1({{'add',{V,x1}},error,badarith},
{{value,{V,x2}},void,{V,x2}}),
{caught1,
- [{?MODULE,my_add,2,_}|_],
+ [{erlang,'+',[V,x1],_},{?MODULE,my_add,2,_}|_],
{caught2,[{erlang,abs,[V],_}|_]},
[{erlang,abs,[V],_}|_]} =
nested_stacktrace_1({{'add',{V,x1}},error,badarith},
@@ -355,7 +402,7 @@ raise(Conf) when is_list(Conf) ->
end,
A = erlang:get_stacktrace(),
A = get(raise),
- [{?MODULE,my_div,2,_}|_] = A,
+ [{erlang,'div',[1, 0], _},{?MODULE,my_div,2,_}|_] = A,
%%
N = 8, % Must be even
N = erlang:system_flag(backtrace_depth, N),
@@ -404,11 +451,20 @@ foo({raise,{Class,Reason,Stacktrace}}) ->
erlang:raise(Class, Reason, Stacktrace).
%%foo(function_clause) -> % must not be defined!
-my_div(A, B) ->
- A div B.
+my_add(A, B) -> A + B.
+my_minus(A, B) -> A - B.
+my_times(A, B) -> A * B.
+my_div(A, B) -> A div B.
+my_rem(A, B) -> A rem B.
+
+my_band(A, B) -> A band B.
+my_bor(A, B) -> A bor B.
+my_bsl(A, B) -> A bsl B.
+my_bsr(A, B) -> A bsr B.
+my_bxor(A, B) -> A bxor B.
+my_bnot(A) -> bnot A.
-my_add(A, B) ->
- A + B.
+my_element(A, B) -> element(A, B).
my_abs(X) -> abs(X).
diff --git a/erts/emulator/test/map_SUITE_data/badmap_17.beam b/erts/emulator/test/map_SUITE_data/badmap_17.beam
index 277fc34b94..6f79bb8c2c 100644
--- a/erts/emulator/test/map_SUITE_data/badmap_17.beam
+++ b/erts/emulator/test/map_SUITE_data/badmap_17.beam
Binary files differ
diff --git a/erts/emulator/test/map_SUITE_data/badmap_17.erl b/erts/emulator/test/map_SUITE_data/badmap_17.erl
index 0ec65e0e33..887fc2e5e3 100644
--- a/erts/emulator/test/map_SUITE_data/badmap_17.erl
+++ b/erts/emulator/test/map_SUITE_data/badmap_17.erl
@@ -1,7 +1,7 @@
-module(badmap_17).
-export([update/1]).
-%% Compile this source file with OTP 17.
+%% Compile this source file with OTP 17.0.
update(Map) ->
try
@@ -17,10 +17,42 @@ update(Map) ->
catch
error:{badmap,Map} ->
ok
- end.
+ end,
+ try
+ update_3(Map),
+ error(update_did_not_fail)
+ catch
+ error:{badmap,Map} ->
+ ok
+ end,
+ ok = update_4(Map),
+ ok = update_5(Map),
+ ok.
update_1(M) ->
M#{a=>42}.
update_2(M) ->
M#{a:=42}.
+
+update_3(M) ->
+ id(M),
+ M#{a=>42}.
+
+update_4(M) when M#{a=>b} =:= M ->
+ did_not_fail;
+update_4(_) ->
+ ok.
+
+update_5(M) ->
+ id(M),
+ case id(true) of
+ true when M#{a=>b} =:= M ->
+ did_not_fail;
+ true ->
+ ok
+ end.
+
+id(I) ->
+ I.
+
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index 4811244b98..223bd7d586 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -1723,14 +1723,9 @@ send2(Config) when is_list(Config) ->
%% Send msg from user thread
send_threaded(Config) when is_list(Config) ->
- case erlang:system_info(smp_support) of
- true ->
- send2_do1(fun(ME,To) -> send_blob_thread_dbg(ME,To,join) end),
- send2_do1(fun(ME,To) -> send_blob_thread_and_join(ME,To) end),
- ok;
- false ->
- {skipped,"No threaded send on non-SMP"}
- end.
+ send2_do1(fun(ME,To) -> send_blob_thread_dbg(ME,To,join) end),
+ send2_do1(fun(ME,To) -> send_blob_thread_and_join(ME,To) end),
+ ok.
send2_do1(SendBlobF) ->
diff --git a/erts/emulator/test/node_container_SUITE.erl b/erts/emulator/test/node_container_SUITE.erl
index 8e9e3cb05a..be90f929df 100644
--- a/erts/emulator/test/node_container_SUITE.erl
+++ b/erts/emulator/test/node_container_SUITE.erl
@@ -405,6 +405,7 @@ node_table_gc(Config) when is_list(Config) ->
PreKnown = nodes(known),
io:format("PreKnown = ~p~n", [PreKnown]),
make_node_garbage(0, 200000, 1000, []),
+ receive after 1000 -> ok end, %% Wait for thread progress...
PostKnown = nodes(known),
PostAreas = erlang:system_info(allocated_areas),
io:format("PostKnown = ~p~n", [PostKnown]),
diff --git a/erts/emulator/test/port_trace_SUITE.erl b/erts/emulator/test/port_trace_SUITE.erl
index c78dc754a9..a1986397a8 100644
--- a/erts/emulator/test/port_trace_SUITE.erl
+++ b/erts/emulator/test/port_trace_SUITE.erl
@@ -78,13 +78,6 @@ 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"),
diff --git a/erts/emulator/test/scheduler_SUITE.erl b/erts/emulator/test/scheduler_SUITE.erl
index af33de237c..12e26671c2 100644
--- a/erts/emulator/test/scheduler_SUITE.erl
+++ b/erts/emulator/test/scheduler_SUITE.erl
@@ -1083,7 +1083,6 @@ sbt_test(Config, CpuTCmd, ClBt, Bt, LP) ->
ok.
scheduler_threads(Config) when is_list(Config) ->
- SmpSupport = erlang:system_info(smp_support),
{Sched, SchedOnln, _} = get_sstate(Config, ""),
%% Configure half the number of both the scheduler threads and
%% the scheduler threads online.
@@ -1095,10 +1094,7 @@ scheduler_threads(Config) when is_list(Config) ->
%% setting using +SP to 50% scheduler threads and 25% scheduler
%% threads online. The result should be 2x scheduler threads and
%% 1x scheduler threads online.
- TwiceSched = case SmpSupport of
- false -> 1;
- true -> Sched*2
- end,
+ TwiceSched = Sched*2,
FourSched = integer_to_list(Sched*4),
FourSchedOnln = integer_to_list(SchedOnln*4),
CombinedCmd1 = "+S "++FourSched++":"++FourSchedOnln++" +SP50:25",
@@ -1121,8 +1117,8 @@ scheduler_threads(Config) when is_list(Config) ->
ResetCmd = "+S "++FourSched++":"++FourSchedOnln++" +S 0:0",
{LProc, LProcAvail, _} = get_sstate(Config, ResetCmd),
%% Test negative +S settings, but only for SMP-enabled emulators
- case {SmpSupport, LProc > 1, LProcAvail > 1} of
- {true, true, true} ->
+ case {LProc > 1, LProcAvail > 1} of
+ {true, true} ->
SchedMinus1 = LProc-1,
SchedOnlnMinus1 = LProcAvail-1,
{SchedMinus1, SchedOnlnMinus1, _} = get_sstate(Config, "+S -1"),
@@ -1157,9 +1153,6 @@ dirty_scheduler_threads_test(Config) ->
ok.
dirty_schedulers_online_test() ->
- dirty_schedulers_online_test(erlang:system_info(smp_support)).
-dirty_schedulers_online_test(false) -> ok;
-dirty_schedulers_online_test(true) ->
dirty_schedulers_online_smp_test(erlang:system_info(schedulers_online)).
dirty_schedulers_online_smp_test(SchedOnln) when SchedOnln < 4 -> ok;
dirty_schedulers_online_smp_test(SchedOnln) ->
diff --git a/erts/emulator/test/signal_SUITE.erl b/erts/emulator/test/signal_SUITE.erl
index f1d11d1814..61a8617165 100644
--- a/erts/emulator/test/signal_SUITE.erl
+++ b/erts/emulator/test/signal_SUITE.erl
@@ -139,71 +139,66 @@ pending_exit_gc(Config) when is_list(Config) ->
pending_exit_test(self(), gc).
pending_exit_test(From, Type) ->
- case catch erlang:system_info(smp_support) of
- true ->
- OTE = process_flag(trap_exit, true),
- Ref = make_ref(),
- Master = self(),
- ExitBySignal = case Type of
- gc ->
- lists:duplicate(10000,
- exit_by_signal);
- _ ->
- exit_by_signal
- end,
- Pid = spawn_link(
- fun () ->
- receive go -> ok end,
- false = have_pending_exit(),
- exit = fake_exit(From,
- self(),
- ExitBySignal),
- true = have_pending_exit(),
- Master ! {self(), Ref, Type},
- case Type of
- gc ->
- force_gc(),
- erlang:yield();
- unlink ->
- unlink(From);
- trap_exit ->
- process_flag(trap_exit, true);
- 'receive' ->
- receive _ -> ok
- after 0 -> ok
- end;
- exit ->
- ok
- end,
- exit(exit_by_myself)
- end),
- Mon = erlang:monitor(process, Pid),
- Pid ! go,
- Reason = receive
- {'DOWN', Mon, process, Pid, R} ->
- receive
- {Pid, Ref, Type} ->
- ok
- after 0 ->
- ct:fail(premature_exit)
- end,
- case Type of
- exit ->
- exit_by_myself = R;
- _ ->
- ExitBySignal = R
- end
+ OTE = process_flag(trap_exit, true),
+ Ref = make_ref(),
+ Master = self(),
+ ExitBySignal = case Type of
+ gc ->
+ lists:duplicate(10000,
+ exit_by_signal);
+ _ ->
+ exit_by_signal
+ end,
+ Pid = spawn_link(
+ fun () ->
+ receive go -> ok end,
+ false = have_pending_exit(),
+ exit = fake_exit(From,
+ self(),
+ ExitBySignal),
+ true = have_pending_exit(),
+ Master ! {self(), Ref, Type},
+ case Type of
+ gc ->
+ force_gc(),
+ erlang:yield();
+ unlink ->
+ unlink(From);
+ trap_exit ->
+ process_flag(trap_exit, true);
+ 'receive' ->
+ receive _ -> ok
+ after 0 -> ok
+ end;
+ exit ->
+ ok
+ end,
+ exit(exit_by_myself)
+ end),
+ Mon = erlang:monitor(process, Pid),
+ Pid ! go,
+ Reason = receive
+ {'DOWN', Mon, process, Pid, R} ->
+ receive
+ {Pid, Ref, Type} ->
+ ok
+ after 0 ->
+ ct:fail(premature_exit)
end,
- receive
- {'EXIT', Pid, R2} ->
- Reason = R2
- end,
- process_flag(trap_exit, OTE),
- ok,
- {comment, "Test only valid with current SMP emulator."};
- _ ->
- {skipped, "SMP support not enabled. Test only valid with current SMP emulator."}
- end.
+ case Type of
+ exit ->
+ exit_by_myself = R;
+ _ ->
+ ExitBySignal = R
+ end
+ end,
+ receive
+ {'EXIT', Pid, R2} ->
+ Reason = R2
+ end,
+ process_flag(trap_exit, OTE),
+ ok,
+ {comment, "Test only valid with current SMP emulator."}.
diff --git a/erts/emulator/test/smoke_test_SUITE.erl b/erts/emulator/test/smoke_test_SUITE.erl
index 41bb07b84c..adc6f56c06 100644
--- a/erts/emulator/test/smoke_test_SUITE.erl
+++ b/erts/emulator/test/smoke_test_SUITE.erl
@@ -88,11 +88,9 @@ native_atomics(Config) when is_list(Config) ->
{value,{NA32Key, NA32, _}} = lists:keysearch(NA32Key, 1, EthreadInfo),
{value,{NA64Key, NA64, _}} = lists:keysearch(NA64Key, 1, EthreadInfo),
{value,{DWNAKey, DWNA, _}} = lists:keysearch(DWNAKey, 1, EthreadInfo),
- case {erlang:system_info(build_type), erlang:system_info(smp_support), NA32, NA64, DWNA} of
- {opt, true, "no", "no", _} ->
+ case {erlang:system_info(build_type), NA32, NA64, DWNA} of
+ {opt, "no", "no", _} ->
ct:fail(optimized_smp_runtime_without_native_atomics);
- {_, false, "no", "no", _} ->
- {comment, "No native atomics"};
_ ->
{comment,
NA32 ++ " 32-bit, "
diff --git a/erts/emulator/test/statistics_SUITE.erl b/erts/emulator/test/statistics_SUITE.erl
index 40cc940a94..7a396d273c 100644
--- a/erts/emulator/test/statistics_SUITE.erl
+++ b/erts/emulator/test/statistics_SUITE.erl
@@ -638,9 +638,7 @@ msacc(Config) ->
(aux, 0) ->
%% aux will be zero if we do not have smp support
%% or no async threads
- case erlang:system_info(smp_support) orelse
- erlang:system_info(thread_pool_size) > 0
- of
+ case erlang:system_info(thread_pool_size) > 0 of
false ->
ok;
true ->
diff --git a/erts/emulator/test/system_profile_SUITE.erl b/erts/emulator/test/system_profile_SUITE.erl
index 9b678fcff9..c9be54f668 100644
--- a/erts/emulator/test/system_profile_SUITE.erl
+++ b/erts/emulator/test/system_profile_SUITE.erl
@@ -146,9 +146,8 @@ do_runnable_ports({TsType, TsTypeFlag}, Config) ->
%% Tests system_profiling with scheduler.
scheduler(Config) when is_list(Config) ->
- case {erlang:system_info(smp_support), erlang:system_info(schedulers_online)} of
- {false,_} -> {skipped, "No need for scheduler test when smp support is disabled."};
- {_, 1} -> {skipped, "No need for scheduler test when only one scheduler online."};
+ case erlang:system_info(schedulers_online) of
+ 1 -> {skipped, "No need for scheduler test when only one scheduler online."};
_ ->
Nodes = 10,
lists:foreach(fun (TsType) ->
diff --git a/erts/emulator/test/tuple_SUITE.erl b/erts/emulator/test/tuple_SUITE.erl
index 79b681b4d1..baf41180e0 100644
--- a/erts/emulator/test/tuple_SUITE.erl
+++ b/erts/emulator/test/tuple_SUITE.erl
@@ -134,6 +134,13 @@ t_element(Config) when is_list(Config) ->
{'EXIT', {badarg, _}} = (catch element(1, id(42))),
{'EXIT', {badarg, _}} = (catch element(id(1.5), id({a,b}))),
+ %% Make sure that the loader does not reject the module when
+ %% huge literal index values are used.
+ {'EXIT', {badarg, _}} = (catch element((1 bsl 24)-1, id({a,b,c}))),
+ {'EXIT', {badarg, _}} = (catch element(1 bsl 24, id({a,b,c}))),
+ {'EXIT', {badarg, _}} = (catch element(1 bsl 32, id({a,b,c}))),
+ {'EXIT', {badarg, _}} = (catch element(1 bsl 64, id({a,b,c}))),
+
ok.
get_elements([Element|Rest], Tuple, Pos) ->