aboutsummaryrefslogtreecommitdiffstats
path: root/lib/observer/test
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2017-10-20 14:07:29 +0200
committerBjörn Gustavsson <[email protected]>2017-10-20 14:07:29 +0200
commit806c2de5ca3806ad8110531c99749063e5603ac0 (patch)
treee340c1edd12135e1413a2eb890eb2773a17ffe02 /lib/observer/test
parent202d62c473e00fd066a70c85ba1d5c26ef2607a1 (diff)
parent7f8e605b242913b6f58f008aaa27a2edd1ab94b2 (diff)
downloadotp-806c2de5ca3806ad8110531c99749063e5603ac0.tar.gz
otp-806c2de5ca3806ad8110531c99749063e5603ac0.tar.bz2
otp-806c2de5ca3806ad8110531c99749063e5603ac0.zip
Merge branch 'bjorn/improve-crash-dumps/OTP-14685' into maint
* bjorn/improve-crash-dumps/OTP-14685: Bump version of crash dumps to 0.4 Verify that binaries of different sizes are dumped correctly Don't dump literal areas that are not referenced at all Dump literals separately to avoid incomplete heap data Implement dumping of maps in crash dumps Buffer writing of crash dumps
Diffstat (limited to 'lib/observer/test')
-rw-r--r--lib/observer/test/crashdump_helper.erl40
-rw-r--r--lib/observer/test/crashdump_viewer_SUITE.erl47
2 files changed, 84 insertions, 3 deletions
diff --git a/lib/observer/test/crashdump_helper.erl b/lib/observer/test/crashdump_helper.erl
index f37d9057cb..41041682c2 100644
--- a/lib/observer/test/crashdump_helper.erl
+++ b/lib/observer/test/crashdump_helper.erl
@@ -19,7 +19,9 @@
%%
-module(crashdump_helper).
--export([n1_proc/2,remote_proc/2]).
+-export([n1_proc/2,remote_proc/2,
+ dump_maps/0,create_maps/0,
+ create_binaries/0]).
-compile(r18).
-include_lib("common_test/include/ct.hrl").
@@ -60,6 +62,7 @@ n1_proc(Creator,_N2,Pid2,Port2,_L) ->
put(ref,Ref),
put(pid,Pid),
put(bin,Bin),
+ put(bins,create_binaries()),
put(sub_bin,SubBin),
put(bignum,83974938738373873),
put(neg_bignum,-38748762783736367),
@@ -92,3 +95,38 @@ remote_proc(P1,Creator) ->
Creator ! {self(),done},
receive after infinity -> ok end
end).
+
+create_binaries() ->
+ Sizes = lists:seq(60, 70) ++ lists:seq(120, 140),
+ [begin
+ <<H:16/unit:8>> = erlang:md5(<<Size:32>>),
+ Data = ((H bsl (8*150)) div (H+7919)),
+ <<Data:Size/unit:8>>
+ end || Size <- Sizes].
+
+%%%
+%%% Test dumping of maps. Dumping of maps only from OTP 20.2.
+%%%
+
+dump_maps() ->
+ Parent = self(),
+ F = fun() ->
+ register(aaaaaaaa_maps, self()),
+ put(maps, create_maps()),
+ Parent ! {self(),done},
+ receive _ -> ok end
+ end,
+ Pid = spawn_link(F),
+ receive
+ {Pid,done} ->
+ {ok,Pid}
+ end.
+
+create_maps() ->
+ Map0 = maps:from_list([{I,[I,I+1]} || I <- lists:seq(1, 40)]),
+ Map1 = maps:from_list([{I,{a,[I,I*I],{}}} || I <- lists:seq(1, 100)]),
+ Map2 = maps:from_list([{{I},(I*I) bsl 24} || I <- lists:seq(1, 10000)]),
+ Map3 = lists:foldl(fun(I, A) ->
+ A#{I=>I*I}
+ end, Map2, lists:seq(-10, 0)),
+ #{a=>Map0,b=>Map1,c=>Map2,d=>Map3,e=>#{}}.
diff --git a/lib/observer/test/crashdump_viewer_SUITE.erl b/lib/observer/test/crashdump_viewer_SUITE.erl
index f9ac884743..86a60e15f4 100644
--- a/lib/observer/test/crashdump_viewer_SUITE.erl
+++ b/lib/observer/test/crashdump_viewer_SUITE.erl
@@ -364,6 +364,10 @@ special(File,Procs) ->
crashdump_viewer:expand_binary({SOffset,SSize,SPos}),
io:format(" expand binary ok",[]),
+ Binaries = crashdump_helper:create_binaries(),
+ verify_binaries(Binaries, proplists:get_value(bins,Dict)),
+ io:format(" binaries ok",[]),
+
#proc{last_calls=LastCalls} = ProcDetails,
true = length(LastCalls) =< 4,
@@ -513,11 +517,36 @@ special(File,Procs) ->
io:format(" unicode table name ok",[]),
ok;
+ ".maps" ->
+ %% I registered a process as aaaaaaaa_maps in the map dump
+ %% to make sure it will be the first in the list when sorted
+ %% on names.
+ [#proc{pid=Pid0,name=Name}|_Rest] = lists:keysort(#proc.name,Procs),
+ "aaaaaaaa_maps" = Name,
+ Pid = pid_to_list(Pid0),
+ {ok,ProcDetails=#proc{},[]} = crashdump_viewer:proc_details(Pid),
+ io:format(" process details ok",[]),
+
+ #proc{dict=Dict} = ProcDetails,
+ io:format("~p\n", [Dict]),
+ Maps = crashdump_helper:create_maps(),
+ Maps = proplists:get_value(maps,Dict),
+ io:format(" maps ok",[]),
+ ok;
_ ->
ok
end,
ok.
+verify_binaries([H|T1], [H|T2]) ->
+ %% Heap binary.
+ verify_binaries(T1, T2);
+verify_binaries([Bin|T1], [['#CDVBin',Offset,Size,Pos]|T2]) ->
+ %% Refc binary.
+ {ok,<<Bin:Size/binary>>} = crashdump_viewer:expand_binary({Offset,Size,Pos}),
+ verify_binaries(T1, T2);
+verify_binaries([], []) ->
+ ok.
lookat_all_pids([]) ->
ok;
@@ -582,8 +611,9 @@ do_create_dumps(DataDir,Rel) ->
"-env ERL_CRASH_DUMP_BYTES " ++
integer_to_list(Bytes)),
CD6 = dump_with_unicode_atoms(DataDir,Rel,"unicode"),
+ CD7 = dump_with_maps(DataDir,Rel,"maps"),
TruncatedDumps = truncate_dump(CD1),
- {[CD1,CD2,CD3,CD4,CD5,CD6|TruncatedDumps], DosDump};
+ {[CD1,CD2,CD3,CD4,CD5,CD6,CD7|TruncatedDumps], DosDump};
_ ->
{[CD1,CD2], DosDump}
end.
@@ -596,7 +626,10 @@ truncate_dump(File) ->
{win32,_} -> <<"\r\n">>;
_ -> <<"\n">>
end,
- [StartBin,AfterTag] = binary:split(Bin,BinTag),
+ %% Split after "our binary" created by crashdump_helper
+ %% (it may not be the first binary).
+ RE = <<"\n=binary:(?=[0-9A-Z]+",NewLine/binary,"FF:010203)">>,
+ [StartBin,AfterTag] = re:split(Bin,RE,[{parts,2}]),
[AddrAndSize,BinaryAndRest] = binary:split(AfterTag,Colon),
[Binary,_Rest] = binary:split(BinaryAndRest,NewLine),
TruncSize = byte_size(Binary) - 2,
@@ -699,6 +732,16 @@ dump_with_unicode_atoms(DataDir,Rel,DumpName) ->
?t:stop_node(n1),
CD.
+dump_with_maps(DataDir,Rel,DumpName) ->
+ Opt = rel_opt(Rel),
+ Pz = "-pz \"" ++ filename:dirname(code:which(?MODULE)) ++ "\"",
+ PzOpt = [{args,Pz}],
+ {ok,N1} = ?t:start_node(n1,peer,Opt ++ PzOpt),
+ {ok,_Pid} = rpc:call(N1,crashdump_helper,dump_maps,[]),
+ CD = dump(N1,DataDir,Rel,DumpName),
+ ?t:stop_node(n1),
+ CD.
+
dump(Node,DataDir,Rel,DumpName) ->
Crashdump = filename:join(DataDir, dump_prefix(Rel)++DumpName),
rpc:call(Node,os,putenv,["ERL_CRASH_DUMP",Crashdump]),