aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib/src/beam_lib.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2010-05-06 15:37:46 +0200
committerBjörn Gustavsson <[email protected]>2010-05-06 16:50:24 +0200
commit3f8f87ec0ec647884111186968271eff990decc5 (patch)
tree1e4b150654207cb3199105381930307cefc24559 /lib/stdlib/src/beam_lib.erl
parent56bb6dd185486f993c944ca0aa08cba571f36522 (diff)
downloadotp-3f8f87ec0ec647884111186968271eff990decc5.tar.gz
otp-3f8f87ec0ec647884111186968271eff990decc5.tar.bz2
otp-3f8f87ec0ec647884111186968271eff990decc5.zip
Make beam_lib:cmp/2 stricter
The beam_lib:cmp/2 function only compares the executable parts of the BEAM files, not attributes or abstract code. Since the types and specs (used by Dialyzer) are contained in the abstract code, beam_lib:cmp/2 will return 'ok' if the only difference between two BEAM file are in the types or specs. If an Erlang/OTP system is installed in a revision control system, and beam_lib:cmp/2 is used to avoid committing unchanged but newly compiled BEAM files, BEAM files with no other changes than in types or specs may not get updated, which can problems if Dialyzer or the debugger is run. To avoid that problem, change beam_lib:cmp/2 to compare all chunks *except* for the "CInf" chunk. The "CInf" chunk contains the compilation time, compiler options, and compiler version.
Diffstat (limited to 'lib/stdlib/src/beam_lib.erl')
-rw-r--r--lib/stdlib/src/beam_lib.erl22
1 files changed, 17 insertions, 5 deletions
diff --git a/lib/stdlib/src/beam_lib.erl b/lib/stdlib/src/beam_lib.erl
index 820afd3739..0f853daafc 100644
--- a/lib/stdlib/src/beam_lib.erl
+++ b/lib/stdlib/src/beam_lib.erl
@@ -331,13 +331,11 @@ beam_files(Dir) ->
%% -> ok | throw(Error)
cmp_files(File1, File2) ->
- {ok, {M1, L1}} = read_significant_chunks(File1),
- {ok, {M2, L2}} = read_significant_chunks(File2),
+ {ok, {M1, L1}} = read_all_but_useless_chunks(File1),
+ {ok, {M2, L2}} = read_all_but_useless_chunks(File2),
if
M1 =:= M2 ->
- List1 = filter_funtab(L1),
- List2 = filter_funtab(L2),
- cmp_lists(List1, List2);
+ cmp_lists(L1, L2);
true ->
error({modules_different, M1, M2})
end.
@@ -408,6 +406,20 @@ pad(Size) ->
end.
%% -> {ok, {Module, Chunks}} | throw(Error)
+read_all_but_useless_chunks(File0) when is_atom(File0);
+ is_list(File0);
+ is_binary(File0) ->
+ File = beam_filename(File0),
+ {ok, Module, ChunkIds0} = scan_beam(File, info),
+ ChunkIds = [Name || {Name,_,_} <- ChunkIds0,
+ not is_useless_chunk(Name)],
+ {ok, Module, Chunks} = scan_beam(File, ChunkIds),
+ {ok, {Module, lists:reverse(Chunks)}}.
+
+is_useless_chunk("CInf") -> true;
+is_useless_chunk(_) -> false.
+
+%% -> {ok, {Module, Chunks}} | throw(Error)
read_significant_chunks(File) ->
case read_chunk_data(File, significant_chunks(), [allow_missing_chunks]) of
{ok, {Module, Chunks0}} ->