aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kernel')
-rw-r--r--lib/kernel/doc/src/Makefile2
-rw-r--r--lib/kernel/src/erts_debug.erl26
-rw-r--r--lib/kernel/test/zlib_SUITE.erl79
3 files changed, 84 insertions, 23 deletions
diff --git a/lib/kernel/doc/src/Makefile b/lib/kernel/doc/src/Makefile
index c9d23ac4c4..0759f362d4 100644
--- a/lib/kernel/doc/src/Makefile
+++ b/lib/kernel/doc/src/Makefile
@@ -71,7 +71,7 @@ XML_REF4_FILES = app.xml config.xml
XML_REF6_FILES = kernel_app.xml
XML_PART_FILES =
-XML_CHAPTER_FILES = notes.xml notes_history.xml
+XML_CHAPTER_FILES = notes.xml
BOOK_FILES = book.xml
diff --git a/lib/kernel/src/erts_debug.erl b/lib/kernel/src/erts_debug.erl
index 480db6814e..9662f8fa90 100644
--- a/lib/kernel/src/erts_debug.erl
+++ b/lib/kernel/src/erts_debug.erl
@@ -21,7 +21,7 @@
%% Low-level debugging support. EXPERIMENTAL!
--export([size/1,df/1,df/2,df/3,ic/1]).
+-export([size/1,df/1,df/2,df/3,df/4,ic/1]).
%% This module contains the following *experimental* BIFs:
%% disassemble/1
@@ -347,31 +347,39 @@ is_term_seen(_, []) -> false.
-spec df(module()) -> df_ret().
df(Mod) when is_atom(Mod) ->
+ df(lists:concat([Mod, ".dis"]), Mod).
+
+-spec df(module(), atom()) -> df_ret();
+ (file:io_device() | file:filename(), module()) -> df_ret().
+
+df(Mod, Func) when is_atom(Mod), is_atom(Func) ->
+ df(lists:concat([Mod, "_", Func, ".dis"]), Mod, Func);
+df(Name, Mod) when is_atom(Mod) ->
try Mod:module_info(functions) of
Fs0 when is_list(Fs0) ->
- Name = lists:concat([Mod, ".dis"]),
Fs = [{Mod,Func,Arity} || {Func,Arity} <- Fs0],
dff(Name, Fs)
catch _:_ -> {undef,Mod}
end.
--spec df(module(), atom()) -> df_ret().
-df(Mod, Func) when is_atom(Mod), is_atom(Func) ->
+-spec df(module(), atom(), arity()) -> df_ret();
+ (file:io_device() | file:filename(), module(), atom()) -> df_ret().
+
+df(Mod, Func, Arity) when is_atom(Mod), is_atom(Func), is_integer(Arity) ->
+ df(lists:concat([Mod, "_", Func, "_", Arity, ".dis"]), Mod, Func, Arity);
+df(Name, Mod, Func) when is_atom(Mod), is_atom(Func) ->
try Mod:module_info(functions) of
Fs0 when is_list(Fs0) ->
- Name = lists:concat([Mod, "_", Func, ".dis"]),
Fs = [{Mod,Func1,Arity} || {Func1,Arity} <- Fs0, Func1 =:= Func],
dff(Name, Fs)
catch _:_ -> {undef,Mod}
end.
--spec df(module(), atom(), arity()) -> df_ret().
-
-df(Mod, Func, Arity) when is_atom(Mod), is_atom(Func) ->
+-spec df(file:io_device() | file:filename(), module(), atom(), arity()) -> df_ret().
+df(Name, Mod, Func, Arity) when is_atom(Mod), is_atom(Func), is_integer(Arity) ->
try Mod:module_info(functions) of
Fs0 when is_list(Fs0) ->
- Name = lists:concat([Mod, "_", Func, "_", Arity, ".dis"]),
Fs = [{Mod,Func1,Arity1} || {Func1,Arity1} <- Fs0,
Func1 =:= Func, Arity1 =:= Arity],
dff(Name, Fs)
diff --git a/lib/kernel/test/zlib_SUITE.erl b/lib/kernel/test/zlib_SUITE.erl
index d17eded811..26602bdcda 100644
--- a/lib/kernel/test/zlib_SUITE.erl
+++ b/lib/kernel/test/zlib_SUITE.erl
@@ -166,7 +166,7 @@ api_deflateInit(Config) when is_list(Config) ->
?m(ok, zlib:deflateInit(Z12,default,deflated,-Wbits,8,default)),
?m(ok,zlib:close(Z11)),
?m(ok,zlib:close(Z12))
- end, lists:seq(8, 15)),
+ end, lists:seq(9, 15)),
lists:foreach(fun(MemLevel) ->
Z = zlib:open(),
@@ -213,12 +213,46 @@ api_deflateReset(Config) when is_list(Config) ->
%% Test deflateParams.
api_deflateParams(Config) when is_list(Config) ->
+ Levels = [none, default, best_speed, best_compression] ++ lists:seq(0, 9),
+ Strategies = [filtered, huffman_only, rle, default],
+
Z1 = zlib:open(),
?m(ok, zlib:deflateInit(Z1, default)),
- ?m(L when is_list(L), zlib:deflate(Z1, <<1,1,1,1,1,1,1,1,1>>, none)),
- ?m(ok, zlib:deflateParams(Z1, best_compression, huffman_only)),
- ?m(L when is_list(L), zlib:deflate(Z1, <<1,1,1,1,1,1,1,1,1>>, sync)),
- ?m(ok, zlib:close(Z1)).
+
+ ApiTest =
+ fun(Level, Strategy) ->
+ ?m(ok, zlib:deflateParams(Z1, Level, Strategy)),
+ ?m(ok, zlib:deflateReset(Z1))
+ end,
+
+ [ ApiTest(Level, Strategy) || Level <- Levels, Strategy <- Strategies ],
+
+ ?m(ok, zlib:close(Z1)),
+
+ FlushTest =
+ fun FlushTest(Size, Level, Strategy) ->
+ Z = zlib:open(),
+ ok = zlib:deflateInit(Z, default),
+ Data = gen_determ_rand_bytes(Size),
+ case zlib:deflate(Z, Data, none) of
+ [<<120, 156>>] ->
+ %% All data is present in the internal zlib state, and will
+ %% be flushed on deflateParams.
+
+ ok = zlib:deflateParams(Z, Level, Strategy),
+ Compressed = [<<120, 156>>, zlib:deflate(Z, <<>>, finish)],
+ Data = zlib:uncompress(Compressed),
+ zlib:close(Z),
+
+ FlushTest(Size + (1 bsl 10), Level, Strategy);
+ _Other ->
+ ok
+ end
+ end,
+
+ [ FlushTest(1, Level, Strategy) || Level <- Levels, Strategy <- Strategies ],
+
+ ok.
%% Test deflate.
api_deflate(Config) when is_list(Config) ->
@@ -652,6 +686,11 @@ api_g_un_zip(Config) when is_list(Config) ->
Concatenated = <<Bin/binary, Bin/binary>>,
?m(Concatenated, zlib:gunzip([Comp, Comp])),
+ %% Don't explode if the uncompressed size is a perfect multiple of the
+ %% internal inflate chunk size.
+ ChunkSizedData = <<0:16384/unit:8>>,
+ ?m(ChunkSizedData, zlib:gunzip(zlib:gzip(ChunkSizedData))),
+
%% Bad CRC; bad length.
BadCrc = bad_crc_data(),
?m(?EXIT(data_error),(catch zlib:gunzip(BadCrc))),
@@ -762,13 +801,13 @@ zip_usage({run,ZIP,ORIG}) ->
?m(ok, zlib:deflateInit(Z, default, deflated, -15, 8, default)),
C2 = zlib:deflate(Z, ORIG, finish),
- ?m(true, C1 == list_to_binary(C2)),
+ ?m(ORIG, zlib:unzip(C2)),
?m(ok, zlib:deflateEnd(Z)),
?m(ok, zlib:deflateInit(Z, none, deflated, -15, 8, filtered)),
?m(ok, zlib:deflateParams(Z, default, default)),
C3 = zlib:deflate(Z, ORIG, finish),
- ?m(true, C1 == list_to_binary(C3)),
+ ?m(ORIG, zlib:unzip(C3)),
?m(ok, zlib:deflateEnd(Z)),
ok = zlib:close(Z),
@@ -978,23 +1017,37 @@ split_bin(Last,Acc) ->
only_allow_owner(Config) when is_list(Config) ->
Z = zlib:open(),
+ Owner = self(),
?m(ok, zlib:inflateInit(Z)),
?m(ok, zlib:inflateReset(Z)),
{Pid, Ref} = spawn_monitor(
fun() ->
- ?m(?EXIT(not_on_controlling_process), zlib:inflateReset(Z))
+ ?m(?EXIT(not_on_controlling_process), zlib:inflateReset(Z)),
+ Owner ! '$transfer_ownership',
+ receive
+ '$ownership_transferred' ->
+ ?m(ok, zlib:inflateReset(Z))
+ after 200 ->
+ ct:fail("Never received transfer signal.")
+ end
end),
+ ownership_transfer_check(Z, Pid, Ref).
+ownership_transfer_check(Z, WorkerPid, Ref) ->
receive
- {'DOWN', Ref, process, Pid, _Reason} ->
- ok
+ '$transfer_ownership' ->
+ zlib:set_controlling_process(Z, WorkerPid),
+ WorkerPid ! '$ownership_transferred',
+ ownership_transfer_check(Z, WorkerPid, Ref);
+ {'DOWN', Ref, process, WorkerPid, normal} ->
+ ok;
+ {'DOWN', Ref, process, WorkerPid, Reason} ->
+ ct:fail("Spawned worker crashed with reason ~p.", [Reason])
after 200 ->
ct:fail("Spawned worker timed out.")
- end,
-
- ?m(ok, zlib:inflateReset(Z)).
+ end.
sub_heap_binaries(Config) when is_list(Config) ->
Compressed = zlib:compress(<<"gurka">>),