aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/test')
-rw-r--r--erts/emulator/test/erts_debug_SUITE.erl47
-rw-r--r--erts/emulator/test/trace_port_SUITE.erl45
-rw-r--r--erts/emulator/test/trace_port_SUITE_data/echo_drv.c12
3 files changed, 91 insertions, 13 deletions
diff --git a/erts/emulator/test/erts_debug_SUITE.erl b/erts/emulator/test/erts_debug_SUITE.erl
index 3dd77eb920..35677f9953 100644
--- a/erts/emulator/test/erts_debug_SUITE.erl
+++ b/erts/emulator/test/erts_debug_SUITE.erl
@@ -139,23 +139,48 @@ flat_size_big_1(Term, Size0, Limit) when Size0 < Limit ->
flat_size_big_1(_, _, _) -> ok.
df(Config) when is_list(Config) ->
- ?line P0 = pps(),
- ?line PrivDir = ?config(priv_dir, Config),
- ?line ok = file:set_cwd(PrivDir),
- ?line erts_debug:df(?MODULE),
- ?line Beam = filename:join(PrivDir, ?MODULE_STRING++".dis"),
- ?line {ok,Bin} = file:read_file(Beam),
- ?line ok = io:put_chars(binary_to_list(Bin)),
- ?line ok = file:delete(Beam),
- ?line true = (P0 == pps()),
+ P0 = pps(),
+ PrivDir = ?config(priv_dir, Config),
+ ok = file:set_cwd(PrivDir),
+
+ AllLoaded = [M || {M,_} <- code:all_loaded()],
+ {Pid,Ref} = spawn_monitor(fun() -> df_smoke(AllLoaded) end),
+ receive
+ {'DOWN',Ref,process,Pid,Status} ->
+ normal = Status
+ after 20*1000 ->
+ %% Not finished (i.e. a slow computer). Stop now.
+ Pid ! stop,
+ receive
+ {'DOWN',Ref,process,Pid,Status} ->
+ normal = Status,
+ io:format("...")
+ end
+ end,
+ io:nl(),
+ _ = [_ = file:delete(atom_to_list(M) ++ ".dis") ||
+ M <- AllLoaded],
+
+ true = (P0 == pps()),
ok.
+df_smoke([M|Ms]) ->
+ io:format("~p", [M]),
+ erts_debug:df(M),
+ receive
+ stop ->
+ ok
+ after 0 ->
+ df_smoke(Ms)
+ end;
+df_smoke([]) -> ok.
+
pps() ->
{erlang:ports()}.
instructions(Config) when is_list(Config) ->
- ?line Is = erts_debug:instructions(),
- ?line _ = [list_to_atom(I) || I <- Is],
+ Is = erts_debug:instructions(),
+ _ = [list_to_atom(I) || I <- Is],
ok.
id(I) ->
diff --git a/erts/emulator/test/trace_port_SUITE.erl b/erts/emulator/test/trace_port_SUITE.erl
index d6346f3af0..a77710205e 100644
--- a/erts/emulator/test/trace_port_SUITE.erl
+++ b/erts/emulator/test/trace_port_SUITE.erl
@@ -35,7 +35,8 @@
fake_schedule_after_getting_linked/1,
fake_schedule_after_getting_unlinked/1,
gc/1,
- default_tracer/1]).
+ default_tracer/1,
+ tracer_port_crash/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -45,7 +46,7 @@ test_cases() ->
fake_schedule_after_register,
fake_schedule_after_getting_linked,
fake_schedule_after_getting_unlinked, gc,
- default_tracer].
+ default_tracer, tracer_port_crash].
suite() -> [{ct_hooks,[ts_install_cth]}].
@@ -473,6 +474,42 @@ default_tracer(Config) when is_list(Config) ->
?line M = N,
ok.
+tracer_port_crash(Config) when is_list(Config) ->
+ case test_server:is_native(?MODULE) orelse
+ test_server:is_native(lists) of
+ true ->
+ {skip,"Native code"};
+ false ->
+ Tr = start_tracer(Config),
+ Port = get(tracer_port),
+ Tracee = spawn(fun () ->
+ register(trace_port_linker, self()),
+ link(Port),
+ receive go -> ok end,
+ lists:reverse([1,b,c]),
+ receive die -> ok end
+ end),
+ Tr ! {unlink_tracer_port, self()},
+ receive {unlinked_tracer_port, Tr} -> ok end,
+ port_control(Port, $c, []), %% Make port commands crash tracer port...
+ trace_func({lists,reverse,1}, []),
+ trace_pid(Tracee, true, [call]),
+ trace_info(Tracee, flags),
+ trace_info(self(), tracer),
+ Tracee ! go,
+ receive after 1000 -> ok end,
+ case whereis(trace_port_linker) of
+ undefined ->
+ ok;
+ Id ->
+% erts_debug:set_internal_state(available_internal_state, true),
+% erts_debug:set_internal_state(abort, {trace_port_linker, Id})
+ ?t:fail({trace_port_linker, Id})
+ end,
+ undefined = process_info(Tracee),
+ ok
+ end.
+
%%% Help functions.
huge_data() -> huge_data(16384).
@@ -631,6 +668,10 @@ tracer_loop(RelayTo, Port) ->
{Port,{data,Msg}} ->
RelayTo ! binary_to_term(Msg),
tracer_loop(RelayTo, Port);
+ {unlink_tracer_port, From} ->
+ unlink(Port),
+ From ! {unlinked_tracer_port, self()},
+ tracer_loop(RelayTo, Port);
Other ->
exit({bad_message,Other})
end.
diff --git a/erts/emulator/test/trace_port_SUITE_data/echo_drv.c b/erts/emulator/test/trace_port_SUITE_data/echo_drv.c
index a8d4ede4fe..e40b9193ea 100644
--- a/erts/emulator/test/trace_port_SUITE_data/echo_drv.c
+++ b/erts/emulator/test/trace_port_SUITE_data/echo_drv.c
@@ -1,5 +1,6 @@
#include <stdio.h>
#include "erl_driver.h"
+#include <errno.h>
@@ -14,6 +15,7 @@ enum e_heavy {
typedef struct _erl_drv_data {
ErlDrvPort erlang_port;
enum e_heavy heavy;
+ int crash;
} EchoDrvData;
static EchoDrvData echo_drv_data, *echo_drv_data_p;
@@ -78,6 +80,7 @@ static EchoDrvData *echo_drv_start(ErlDrvPort port, char *command)
echo_drv_data_p = &echo_drv_data;
echo_drv_data_p->erlang_port = port;
echo_drv_data_p->heavy = heavy_off;
+ echo_drv_data_p->crash = 0;
return echo_drv_data_p;
}
@@ -87,6 +90,12 @@ static void echo_drv_stop(EchoDrvData *data_p) {
static void echo_drv_output(ErlDrvData drv_data, char *buf, ErlDrvSizeT len) {
EchoDrvData* data_p = (EchoDrvData *) drv_data;
+
+ if (data_p->crash) {
+ driver_failure_posix(data_p->erlang_port, EINTR);
+ return;
+ }
+
driver_output(data_p->erlang_port, buf, len);
switch (data_p->heavy) {
case heavy_off:
@@ -100,6 +109,7 @@ static void echo_drv_output(ErlDrvData drv_data, char *buf, ErlDrvSizeT len) {
data_p->heavy = heavy_off;
break;
}
+
}
static void echo_drv_finish() {
@@ -115,6 +125,8 @@ static ErlDrvSSizeT echo_drv_control(ErlDrvData drv_data,
case 'h':
data_p->heavy = heavy_set;
break;
+ case 'c':
+ data_p->crash = 1;
}
return 0;
}