diff options
author | Björn Gustavsson <bjorn@erlang.org> | 2010-05-06 15:37:46 +0200 |
---|---|---|
committer | Björn Gustavsson <bjorn@erlang.org> | 2010-05-06 16:50:24 +0200 |
commit | 3f8f87ec0ec647884111186968271eff990decc5 (patch) | |
tree | 1e4b150654207cb3199105381930307cefc24559 /lib/stdlib/src | |
parent | 56bb6dd185486f993c944ca0aa08cba571f36522 (diff) | |
download | otp-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')
-rw-r--r-- | lib/stdlib/src/beam_lib.erl | 22 |
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}} -> |