erlc bug: no_bs_match_state (OTP-R10B-10 / compiler-4.3.12)
Pascal Brisset
pascal.brisset@REDACTED
Fri Apr 21 00:44:56 CEST 2006
Erlc crashes on the attached erlang module with this error:
| bug_bin: function foo/1+13:
| Internal consistency check failed - please report this bug.
| Instruction: {bs_restore,0}
| Error: no_bs_match_state:
This message comes from lib/compiler/src/beam_validator.erl,
which performs a kind of abstract interpretation on the beam code.
In particular, it keeps track of internal variables of the virtual
machine that are used for the implementation of pattern-matching
on binaries. The validity of these variables is stored in
(Vst#vst.current)#st.bsm throughout the control flow analysis.
Looking at the generated beam code with erlc -S:
10 {function, foo, 1, 2}.
11 {label,1}.
12 {func_info,{atom,bug_bin},{atom,foo},1}.
13 {label,2}.
14 {test,bs_start_match,{f,1},[{x,0}]}.
15 {bs_save,0}.
16 {test,bs_get_binary,
17 {f,3},
18 [{atom,all},8,{field_flags,[aligned,unsigned,big]},{x,1}]}.
19 {test,bs_test_tail,{f,3},[0]}.
20 {bs_init2,{f,3},0,0,2,{field_flags,[]},{x,2}}.
21 {test,is_ne,{f,3},[{x,1},{x,2}]}.
22 {move,{atom,ok},{x,0}}.
23 return.
24 {label,3}.
25 {bs_restore,0}.
26 {test,bs_test_tail,{f,1},[0]}.
27 {move,{atom,ok},{x,0}}.
28 return.
Lines 20-21 implement the guard Rest/=<<>>. An empty binary is
created and compared to register X1, which contains Rest.
beam_validator considers bsm to be invalid after bs_init2,
presumably in accordance with this comment:
%%% The bsm field is reset to 'undefined' by instructions that may cause a
%%% a garbage collection (might move the binary) and/or context switch
%%% (may invalidate the save points).
As a consequence, when beam_validator examines the control flow
from line 21 to line 25, it decides that bs_restore cannot execute
safely.
The problem also occurs whenever a guard allocates memory;
for example "foo(<<Rest/binary>>) when Rest/=[0]".
I'm not sure how this should be fixed. The GC could scan the
pointers in erts_mb and erts_save_mb. Or the allocator could
be prevented from relocating data while a binary match is in
progress.
Maybe earlier versions of erlc also generate "unsafe" code which
goes unnoticed because they don't have beam_validator. Or maybe
there is no risk at all and the validator is too strict.
Credit for isolating this problem goes to Florent and Christophe
at Cellicium.
-- Pascal
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: bug_bin.erl
URL: <http://erlang.org/pipermail/erlang-bugs/attachments/20060421/7cc902ff/attachment.ksh>
More information about the erlang-bugs
mailing list