aboutsummaryrefslogtreecommitdiffstats
path: root/lib/debugger
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2011-03-22 05:23:09 +0100
committerBjörn Gustavsson <[email protected]>2011-08-16 08:58:48 +0200
commitf2e0e976382eddd3d120110c87882a2185e868aa (patch)
treeb257e405877983d48fb428c9ac2797b5ba7f28c5 /lib/debugger
parent19713d214462b863def874385844521f00a2bac5 (diff)
downloadotp-f2e0e976382eddd3d120110c87882a2185e868aa.tar.gz
otp-f2e0e976382eddd3d120110c87882a2185e868aa.tar.bz2
otp-f2e0e976382eddd3d120110c87882a2185e868aa.zip
Fix binary matching in the debugger
'eval_bits' is a common utility module used for evaluting binary construction and matching. The functions that do matching (match_bits/{6,7} and bin_gen/6) are supposed to treat the bindings as an abstract data type, but they assume that the bindings have the same representation as in the erl_eval module. That may cause binary matching to fail in the debugger, because the debugger represents the bindings as an unordered list of two-tuples, while the erl_eval modules uses an ordered list of two-tuple (an ordset). One way to fix the problem would be to let the debugger to use ordered lists to represent the bindings. Unfortunately, that would also change how the bindings are presented in the user interface. Currently, the variable have most been recently assigned is shown first, which is convenient. Fix the matching problem by mending the leaky abstraction in eval_bits. The matching functions needs to be passed two additional operations: one for looking up a variable in the bindings and one for adding a binding. Those operations could be passed as two more funs (in addition to the evaluation and match fun already passed), but the functions already have too many arguments. Therefore, change the meaning of the match fun, so that the first argument is the operation to perform ('match', 'binding', or 'add_binding') and second argument is a tuple with arguments for the operation.
Diffstat (limited to 'lib/debugger')
-rw-r--r--lib/debugger/src/dbg_ieval.erl16
-rw-r--r--lib/debugger/test/bs_match_misc_SUITE.erl15
2 files changed, 23 insertions, 8 deletions
diff --git a/lib/debugger/src/dbg_ieval.erl b/lib/debugger/src/dbg_ieval.erl
index 9b6919074f..b0792b05f0 100644
--- a/lib/debugger/src/dbg_ieval.erl
+++ b/lib/debugger/src/dbg_ieval.erl
@@ -1023,7 +1023,7 @@ eval_generate(Term, _P, Bs, _CompFun, Ieval) ->
exception(error, {bad_generator,Term}, Bs, Ieval).
eval_b_generate(<<_/bitstring>>=Bin, P, Bs0, CompFun, Ieval) ->
- Mfun = fun(L, R, Bs) -> match1(L, R, Bs, Bs0) end,
+ Mfun = match_fun(Bs0),
Efun = fun(Exp, Bs) -> expr(Exp, Bs, #ieval{}) end,
case eval_bits:bin_gen(P, Bin, erl_eval:new_bindings(), Bs0, Mfun, Efun) of
{match,Rest,Bs1} ->
@@ -1392,11 +1392,9 @@ match1({cons,_,H,T}, [H1|T1], Bs0, BBs) ->
match1({tuple,_,Elts}, Tuple, Bs, BBs)
when length(Elts) =:= tuple_size(Tuple) ->
match_tuple(Elts, Tuple, 1, Bs, BBs);
-match1({bin,_,Fs}, B, Bs0, BBs0) when is_bitstring(B) ->
- Bs1 = lists:sort(Bs0), %Kludge.
- BBs = lists:sort(BBs0),
- try eval_bits:match_bits(Fs, B, Bs1, BBs,
- fun(L, R, Bs) -> match1(L, R, Bs, BBs) end,
+match1({bin,_,Fs}, B, Bs0, BBs) when is_bitstring(B) ->
+ try eval_bits:match_bits(Fs, B, Bs0, BBs,
+ match_fun(BBs),
fun(E, Bs) -> expr(E, Bs, #ieval{}) end,
false)
catch
@@ -1405,6 +1403,12 @@ match1({bin,_,Fs}, B, Bs0, BBs0) when is_bitstring(B) ->
match1(_,_,_,_) ->
throw(nomatch).
+match_fun(BBs) ->
+ fun(match, {L,R,Bs}) -> match1(L, R, Bs, BBs);
+ (binding, {Name,Bs}) -> binding(Name, Bs);
+ (add_binding, {Name,Val,Bs}) -> add_binding(Name, Val, Bs)
+ end.
+
match_tuple([E|Es], Tuple, I, Bs0, BBs) ->
{match,Bs} = match1(E, element(I, Tuple), Bs0, BBs),
match_tuple(Es, Tuple, I+1, Bs, BBs);
diff --git a/lib/debugger/test/bs_match_misc_SUITE.erl b/lib/debugger/test/bs_match_misc_SUITE.erl
index 5244a358bd..89fce263f5 100644
--- a/lib/debugger/test/bs_match_misc_SUITE.erl
+++ b/lib/debugger/test/bs_match_misc_SUITE.erl
@@ -25,7 +25,8 @@
bound_var/1,bound_tail/1,t_float/1,little_float/1,sean/1,
kenneth/1,encode_binary/1,native/1,happi/1,
size_var/1,wiger/1,x0_context/1,huge_float_field/1,
- writable_binary_matched/1,otp_7198/1]).
+ writable_binary_matched/1,otp_7198/1,
+ unordered_bindings/1]).
-include_lib("test_server/include/test_server.hrl").
@@ -35,7 +36,7 @@ all() ->
[bound_var, bound_tail, t_float, little_float, sean,
kenneth, encode_binary, native, happi, size_var, wiger,
x0_context, huge_float_field, writable_binary_matched,
- otp_7198].
+ otp_7198, unordered_bindings].
groups() ->
[].
@@ -566,5 +567,15 @@ otp_7198_scan(<<C, Rest/binary>>, TokAcc) when
otp_7198_scan(Rest, [{'KEYWORD', C} | TokAcc])
end.
+unordered_bindings(Config) when is_list(Config) ->
+ {<<1,2,3,4>>,<<42,42>>,<<3,3,3>>} =
+ unordered_bindings(4, 2, 3, <<1,2,3,4, 42,42, 3,3,3, 3>>),
+ ok.
+
+unordered_bindings(CompressedLength, HashSize, PadLength, T) ->
+ <<Content:CompressedLength/binary,Mac:HashSize/binary,
+ Padding:PadLength/binary,PadLength>> = T,
+ {Content,Mac,Padding}.
+
id(I) -> I.