[klee-dev] Bool vs i1 in STPBuilder
Alastair Reid
adreid at google.com
Wed Dec 16 15:54:38 GMT 2020
I am trying to chase down a bug that occurs while applying KLEE to a
multi-module Rust program (assembly.ll is approx 200k lines).
I'm hoping for suggestions of what might be wrong and/or how to narrow down
the cause of the bug.
What I am seeing in the stack trace is
that klee::STPBuilder::constructActual calls vc_bvConcatExpr (in STP) which
calls stp::checkChildrenAreBV which prints an error message and dies.
The error message involves a very large term but the start of it is as
follows (I have bold-faced the top two levels of the term)
The type is: 0
Fatal Error: BVTypeCheck:ChildNodes of bitvector-terms must be bitvectors
*14808:(BVCONCAT*
* 14806:(BVSGT*
988:0x00
14798:(ITE
....))
* 14774:(BVSGT* 988:0x00
14766:(ITE
14760:(EQ
14724:(READ
[14720]
14386:(BVEXTRACT
[14380]
13594:0x0000001F
60:0x00000000))
[14758])
14406:0xFF
988:0x00)))
0
error: STP Error: BVTypeCheck:ChildNodes of bitvector-terms must be
bitvectors
The first argument of BVCONCAT is the result of BVSGT and STP distinguishes
between booleans and bitvectors.
So I think that the error is in the code in KLEE that constructed this term.
But, after that, I am not sure what is going on - here are my confused
thoughts...
I suspect that the problem is that LLVM represents booleans as bitvectors
of length 1.
So there must be a part of KLEE (in STPBuilder???) that is responsible for
deciding whether a bitvector of length 1 should be represented by an STP
bitvector or by an STP boolean?
And, I see this comment above klee::STPBuilder::constructActual
and klee::STPBuilder::construct
/** if *width_out!=1 then result is a bitvector,
otherwise it is a bool */
There are two potential problems with this (but these might be
red-herrings?)
1) The width_out pointer can be null - in which case the width is not
written.
And the code that converts Expr::Concat to STP passes a null pointer.
this code (from STPBuilder.cpp) is not distinguishing booleans
571 case Expr::Concat: {
572 ConcatExpr *ce = cast<ConcatExpr>(e);
573 unsigned numKids = ce->getNumKids();
574 ExprHandle res = construct(ce->getKid(numKids-1), 0);
575 for (int i=numKids-2; i>=0; i--) {
576 res = vc_bvConcatExpr(vc, construct(ce->getKid(i), 0), res);
577 }
578 *width_out = ce->getWidth();
579 return res;
580 }
2) This seems to treat all 1-bit bitvectors as booleans - is this always
true?
In particular, I wonder whether the Rust compiler satisfies this
assumption?
But these could be red-herrings. The expression being converted is a bit
unusual
concat(sgt(_,_), sgt(_,_))
It's not impossible but it is a bit odd. So maybe something went wrong
elsewhere in KLEE to construct this code?
Any thoughts on how to debug this or on my interpretation of the code above
would be great!
Are there any command line flags that would generate a trace as the Expr is
being constructed? This would let me find the part of assembly.ll that is
triggering the problem and hopefully figure out if the problem is in
STPBuilder or elsewhere.
Thanks,
Alastair
-------------- next part --------------
HTML attachment scrubbed and removed
More information about the klee-dev
mailing list