-
Notifications
You must be signed in to change notification settings - Fork 472
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix constant folding & constraint set slicing #1706
Changes from 3 commits
0cd1bc5
609a37e
b29f3ac
79aa5cc
7339eb9
c121c38
3ff6b95
02b4c69
00e8199
6b7f671
6732eb2
4adeac2
7565b4a
1680397
cbe55b9
315ef64
6155a4d
38dbfd6
1491cbd
264eb04
e0130a4
d0e9abf
9807b37
728e021
e584fb2
bf3a2b9
3eb96f8
5e54189
a0ab429
536ec71
a83e8c2
37144d9
1b8754d
787e51f
dca9adb
dfa7a84
b841038
735a963
b54a448
02563cd
3fab981
f7fb8bb
2f5d4d2
18064f8
52d8eb4
f1dfb80
d5b577e
79b42ed
ec8489f
2113a73
c2a21ba
f87e1e2
2eb630d
8818ea3
27db1b8
64a03a7
380fb31
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -353,6 +353,40 @@ def test_mulmod(self): | |
# 0x8000000000000000000000000000000000000000000000000000000082000011 | ||
self.assertEqual(Z3Solver.instance().get_all_values(constraints, result), [2423129]) | ||
|
||
def test_related_to(self): | ||
import gzip | ||
from manticore import config | ||
from manticore.core.smtlib.visitors import translate_to_smtlib | ||
from manticore.core.smtlib import ConstraintSet, Z3Solver, Operators, BitVecConstant | ||
import pickle, sys | ||
filename = os.path.abspath(os.path.join(DIRPATH, "data", "ErrRelated.pkl.gz")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's in this file? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, should this test be in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My guess is that it's a state that exhibits the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. Not the state but the ConstraintSet that showed the problem. This is not really ethereum specific. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it expensive to construct from source? A binary isn't easy to peruse over the web, for example. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I saved the constraint and the constraintset that found to have trouble with old get_related. |
||
|
||
constraints, constraint = pickle.loads(gzip.open(filename,'rb').read()) | ||
|
||
consts = config.get_group("smt") | ||
feliam marked this conversation as resolved.
Show resolved
Hide resolved
|
||
consts.related_constraints = False | ||
|
||
Z3Solver.instance().can_be_true.cache_clear() | ||
ground_truth = Z3Solver.instance().can_be_true(constraints, constraint) | ||
self.assertEqual(ground_truth, False) | ||
|
||
consts.related_constraints = True | ||
Z3Solver.instance().can_be_true.cache_clear() | ||
self.assertEqual(ground_truth, Z3Solver.instance().can_be_true(constraints, constraint)) | ||
|
||
#Replace | ||
new_constraint = Operators.UGE( Operators.SEXTEND(BitVecConstant(256,0x1a),256,512) * BitVecConstant(512,1), 0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000 ) | ||
self.assertEqual(translate_to_smtlib(constraint), translate_to_smtlib(new_constraint)) | ||
|
||
consts.related_constraints = False | ||
Z3Solver.instance().can_be_true.cache_clear() | ||
self.assertEqual(ground_truth, Z3Solver.instance().can_be_true(constraints, new_constraint)) | ||
|
||
consts.related_constraints = True | ||
Z3Solver.instance().can_be_true.cache_clear() | ||
self.assertEqual(ground_truth, Z3Solver.instance().can_be_true(constraints, new_constraint)) | ||
|
||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With this added "this" test passes with both get_related enabled and disabled
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As long as both are passing, let's set the default back to
True
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well I'm not 100% This single testcase representes all possible fails explained in issue #1679
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Devils advocate, here... What if
related_to
isA
andconstraint
is something likeB && !B
, i.e.,constraint
is unsatisfiable and has variables, but they do not overlap with those ofrelated_to
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes get_related should work only on previously feasible path contraints.
If you have feasible
A & B & C
and want to check ifB \/ C
can be True then you do not need to bother the solver with the A.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I know it is not enforced.
We should make it a pre-condition or attempt to solve the full constraint set and trust that some cache magic prevents it to do the solving over the whole thing again and again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know how reasonable this approach is.
__get_related
is called byto_string
, andto_string
is something that one might reasonably call to debug a bad constraint set.Moreover,
to_string
is called bycan_be_true
:manticore/manticore/core/smtlib/solver.py
Line 433 in 2c90ee0
So there's a little bit of a chicken-and-egg problem here.
If it were up to me, I would not insist that
__get_related
be called on only satisfiable constraint sets.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Many constraints do not overlap in terms of the memory they reference. Constraint independence divides constraint sets into disjoint independent subsets based on the symbolic variables and memory cells they reference. By explicitly tracking these subsets, it can frequently eliminate irrelevant constraints prior to sending it to the solver.
For example, given the constraint set {i < j, j < 20, k > 0}, a query of whether i = 20 just requires the first two constraints. This was first explained in [EXE] https://web.stanford.edu/~engler/exe-ccs-06.pdf
We can move the optimizations/transformations that are controlled via kwargs in the
to_string()
to a differentConstraintSet
method. Likeslice_related_to(..)
andmake_bindings
so it is done more explicit.If the problem is to print a ConstraintSet for debugging you can just just do not slice the ConstraintSet.
print (str(cs))
There is also a forgotten
pretty_print
for expressions.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fwiw, I use the
pretty_print
all the time while debuggingThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved the disabled get_related as a special method of a ConstraintSet to slice it when the user wants it.
Also added "some" tests for it.