seahorn / crab Goto Github PK
View Code? Open in Web Editor NEWA library for building abstract interpretation-based analyses
License: Apache License 2.0
A library for building abstract interpretation-based analyses
License: Apache License 2.0
Problem07_label52_true-unreach-call.pp.bc.zip
Command to reproduce the problem using crab-llvm:
crabllvm Problem07_label52_true-unreach-call.pp.bc --crab-verbose=2 --crab-dom=int --crab-widening-delay=2 --crab-widening-jump-set=0 --crab-narrowing-iterations=2 --crab-track=arr --crab-singleton-aliases --crab-check=assert --crab-stats --crab-disable-warnings
silently produces signal 11 (SEGFAULT).
I did some gdb and it seems that we run out of stack while computing WTO using recursion.
From @caballa on June 25, 2017 23:18
it takes two parameters that delimits a symbolic interval: lower and upper bounds, which can only be number or variables but the current type is a linear expression. So it's more general than it should be.
Copied from original issue: caballa/crab#18
From @caballa on April 9, 2017 8:34
The current implementation works for toy programs but two main things
must to be done for being able to analyze real programs:
landmarks must be kept as local state as part of each abstract
state.
reduction between scalar and weight domains must be done
incrementally. For that, we need some assumptions about the
underlying scalar domain. For instance, if we assume zones then
after each operation we know which are the indexes affected by
the operation. We can use that information for doing reduction
only on those indexes. This would remove the need of having
methods such as array_sgraph_domain_traits::is_unsat
and
array_sgraph_domain_traits::active_variables
which are anyway
domain dependent.
Copied from original issue: caballa/crab#15
From @caballa on October 15, 2016 23:18
For intervals and zones, we need at least:
Copied from original issue: caballa/crab#4
From @caballa on October 15, 2016 23:37
Create a combined domain between e.g., (zones x terms) and intervals such that the domain is zones x terms if the number of variables does not exceed a threshold, otherwise it degrades to intervals.
Copied from original issue: caballa/crab#8
Hello, is it possible to add a reaching definitions analysis to this framework to obtain a data dependence graph?
I am interested in obtaining a program dependence graph of a control flow graph, however, currently only the control dependence graph is obtainable.
CMake top-level options should be prefixed with CRAB
. For example,
USE_LDD
--> CRAB_ENABLE_LDD
USE_APRON
--> CRAB_ENABLE_APRON
etc.
If so, is there any related installation document on MacOS? Thank you very much!
Hello, this might be a silly question but I can not wrap my head around on how to encode my cfg representation to the crab cfg representation properly. Consider given the following program P:
As I can not express statements such as NOT(activate) AND b
I converted my input to SSA and three-address code as follows:
where SEQ is simply my representation of a basic block. The marshaling to crab looks as follows:
entry:
havoc(P.activate_1003);
goto bb_1;
bb_1:
P.v_bool_1001 = true;
P.b_1002 = P.v_bool_1001;
goto bb_2;
bb_2:
P.temp_0 = not(P.activate_1003);
P.temp_1 = P.temp_0&P.b_1002;
goto bb_3,bb_4;
bb_3:
assume(P.temp_1);
P.v_int_1004 = 0;
P.y_1005 = P.v_int_1004;
goto exit;
exit:
bb_4:
assume(not(P.temp_1));
P.temp_2 = not(P.b_1002);
P.temp_3 = P.activate_1003|P.temp_2;
goto bb_5,bb_6;
bb_5:
assume(P.temp_3);
P.v_int_1006 = 1;
P.y_1007 = P.v_int_1006;
goto exit;
bb_6:
assume(not(P.temp_3));
P.v_int_1008 = 2;
P.y_1009 = P.v_int_1008;
goto exit;
and running a forward analysis using a flat boolean numerical domain with intervals results in the following output:
bb_6:({P.b_1002 -> true; P.temp_1 -> false; P.temp_2 -> false; P.v_bool_1001 -> true}, {})
bb_5:({P.b_1002 -> true; P.temp_1 -> false; P.temp_2 -> false; P.v_bool_1001 -> true}, {})
bb_3:({P.b_1002 -> true; P.v_bool_1001 -> true}, {})
bb_4:({P.b_1002 -> true; P.v_bool_1001 -> true}, {})
bb_2:({P.b_1002 -> true; P.v_bool_1001 -> true}, {})
bb_1:({}, {})
exit:({P.b_1002 -> true; P.v_bool_1001 -> true}, {})
entry:({}, {})
which, sadly, is not helpful to me. I was hoping to detect the unreachability of bb_6, but the information of the value P.activate_1003 is dropped somewhere in between. Any hints on how to encode my problem instance properly such that information is not dropped?
I have code that looks like this:
using z_wrapped_interval_domain = wrapped_interval_domain<z_number, varname_t>;
using powerset_of_z_wrapped_intervals =
powerset_domain<z_wrapped_interval_domain>;
using analysis_domain = powerset_of_z_wrapped_intervals;
int main(void) {
variable_factory_t vfac;
z_var y(vfac["y"], crab::INT_TYPE, 32);
z_var x(vfac["x"], crab::INT_TYPE, 32);
analysis_domain d1;
d1 += (y > 10);
d1.assign(x, 0);
analysis_domain d2;
d2 += (y > 20);
d2.assign(x, 1);
analysis_domain d3;
d3 += (y > 30);
d3.assign(x, 2);
analysis_domain d4 = d1 | d2 | d3;
crab::outs() << d4 << "\n\n\n";
std::vector<z_var> vars;
vars.push_back(x);
analysis_domain proj = d4;
proj.project(vars);
crab::outs() << proj << "\n\n\n";
return 0;
}
(the code is purposely brain-dead, but that's fine)
Which gives this:
{y -> [[11, 2147483647]]_32; x -> [[0, 0]]_32} or
{y -> [[21, 2147483647]]_32; x -> [[1, 1]]_32} or
{y -> [[31, 2147483647]]_32; x -> [[2, 2]]_32}
{x -> [[0, 0]]_32} or
{x -> [[1, 1]]_32} or
{x -> [[2, 2]]_32}
After doing the projection, I get a powerset domain that has three elements (0
, 1
and 2
). Is it possible to ask crab
to "compress" this domain into a single range of [0, 2]
?
From @caballa on April 17, 2017 4:40
Copied from original issue: caballa/crab#16
abstract_domain
api with the operations from domain_traits_api
:
expand
forget
project
domain_traits_api
The tests
simple/test-arr-4.c
simple/test-arr-4.unsafe.c
simple/fntest-1.c
simple/fntest-1.unsafe.c
from crab-llvm do not pass if we use:
typedef SDBM_impl::BigNumDefaultParams<number_t> SplitDBMGraph;
typedef SplitDBM<number_t, varname_t, SplitDBMGraph> BASE(split_dbm_domain_t);
in include/crab_llvm/crab_domains.hh
From @caballa on October 15, 2016 23:33
Copied from original issue: caballa/crab#7
I want to analyze PLC programs which exhibit "cyclic" behavior using symbolic execution but sometimes the code is written poorly and there are unreachable branches. For this purpose I need some kind of value-set analysis, but I stumbled upon a few problems. Here is an example of a simple program as a crab cfg:
void declare main()
initialization:
cycle = 0;
x = 0;
goto main_entry;
main_entry:
assume(cycle <= 100);
goto cycle_entry;
cycle_entry:
cycle = cycle+1;
goto main_body;
main_body:
x_res:int32 = call increment(x:int32);
goto cycle_exit;
cycle_exit:
x = x_res;
goto main_entry,main_exit;
main_exit:
assume(-cycle < -100);
x_out:int32 declare increment(x_in:int32)
entry:
goto body;
body:
x_out = x_in+1;
goto exit;
exit:
The program should simply increment the value of x
by 1 through the use of a function call in each "iteration" for a couple of "cycles".
Using the top-down interprocedural analyzer with the boxes domain of the ldd library I get the following invariants:
Callgraph=
main--> increment
=================================
void declare main()
cycle_exit={-cycle <= -1; cycle <= 101; -x <= -1; -x_res <= -1}
main_exit={-cycle <= -101; cycle <= 101; -x <= -1; -x_res <= -1}
main_body={-cycle <= -2; cycle <= 101; -x <= -1; -x_res <= -1} or
{-cycle <= -1; cycle <= 1; -x <= 0; x <= 0; -x_res <= -1}
cycle_entry={-cycle <= -2; cycle <= 101; -x <= -1; -x_res <= -1} or
{-cycle <= -1; cycle <= 1; -x <= 0; x <= 0}
main_entry={-cycle <= -1; cycle <= 100; -x <= -1; -x_res <= -1} or
{-cycle <= 0; cycle <= 0; -x <= 0; x <= 0}
initialization={-cycle <= 0; cycle <= 0; -x <= 0; x <= 0}
=================================
x_out:int32 declare increment(x_in:int32)
exit={-x_in <= 0; -x_out <= -1}
body={-x_in <= 0; -x_out <= -1}
entry={-x_in <= 0}
=================================
I would have expected that the value of x
is propagated, e.g., main_exit={x>=1;x<=101,...}
and that the generated function summary holds must summaries for each valuation of x_in
, e.g., x_in = 0, x_in = 1, x_in = 2, ...
.
What is wrong with my encoding?
Strict inequalities are needed for rationals. For integers we can always replace
x < y
with x <= y-1
. This issue is related to issue #10 .
This line looks very suspicious. Shouldn't the inequation be the other way around? I didn't try to create an example that triggers the bug (if it is one), I just stumbled across this line when I was looking at the code to understand how Booleans are handled.
Following on from #34, I am able to successfully represent something like:
void foo(int y) {
int w = 0;
if (y > 10) {
w = 1;
} else {
w = 2;
}
}
which I can correctly encode and obtain:
{y -> [[11, 2147483647]]_32; w -> [[2, 2]]_32} or
{y -> [[-2147483648, 10]]_32; w -> [[3, 3]]_32}
My code looks like this like:
using z_wrapped_interval_domain = wrapped_interval_domain<z_number, varname_t>;
using powerset_of_z_wrapped_intervals =
powerset_domain<z_wrapped_interval_domain>;
using analysis_domain = powerset_of_z_wrapped_intervals;
int main(void) {
variable_factory_t vfac;
z_var y(vfac["y"], crab::INT_TYPE, 32);
z_var w(vfac["w"], crab::INT_TYPE, 32);
analysis_domain start;
start.assign(w, 0);
analysis_domain tt_1 = start;
tt_1 += (y > 10);
tt_1.assign(w, 1);
analysis_domain ff_1 = start;
ff_1 += (y <= 10);
ff_1.assign(w, 2);
analysis_domain after1 = tt_1 | ff_1;
crab::outs() << after1 << "\n\n\n";
return 0;
}
However, I am not sure how to encode things when the condition in the false branch is "more complicated":
void foo(int y) {
int w = 0;
if (y > 10 && y < 20) {
w = 1;
} else {
w = 2;
}
}
(notice the if
now contains a conjunction)
While encoding the true branch is fine:
analysis_domain tt_1 = start;
tt_1 += (y > 10);
tt_1 += (y < 20);
tt_1.assign(w, 1);
the false branch is more complicated:
analysis_domain ff_1 = start;
ff_1 += (y <= 10);
ff_1 += (y >= 20);
ff_1.assign(w, 2);
because it seems that crab
says that this is bottom.
What is the best way to represent the negation of a conditional that contains Booleans when working with crab
?
Is there a simple way to build up a Boolean expression, and then use that both positively and then negate it (to represent an else)? It is fine if I need to manually build-up the else, but I'm really unsure about how to encode it.
I noticed that this bitwise operation type is not included in Crab, and there is no need to add specialized abstraction design of this operation for each abstract domain in Crab. So, should we add the bitwise complement (~) operation in Crab? Or perhaps we have already implemented this operation in some other way, since -x = ~x +1 ?
The wrapped interval domain is a good candidate:
https://jorgenavas.github.io/papers/wrapped-intervals-aplas12.pdf
From @caballa on February 16, 2017 21:22
Added test case in branch crab2 (commit 9a21877) that triggers the bug.
The test is actually quite simple. If we just add two constraints x >= 1/2
and x <= 1/2
we get bottom
rather than x = 1/2
.
If we use integers we get the expected result so something is wrong with how we handle rationals.
Copied from original issue: caballa/crab#12
Two questions:
void foo(int y)
{
y++;
if (y > 10); // <-- if this was SSA, it would be something like "y__0 > 9"
}
(seems like an issue in elina, but I thought it might be helpful to open it here)
ebpf-verifier$ make crab_install
[...]
[ 75%] Performing build step for 'elina'
CMake Error at [...]/workspace/ebpf-verifier/external/crab/build/elina-prefix/src/elina-stamp/elina-build-RelWithDebInfo.cmake:16 (message):
Command failed: 2
'make' 'CC=/Library/Developer/CommandLineTools/usr/bin/cc' 'CXX=/Library/Developer/CommandLineTools/usr/bin/c++' 'IS_VECTOR=-DVECTOR' 'ELINA_PREFIX=[...]/workspace/ebpf-verifier/external/crab/build/run/elina' 'GMP_PREFIX=/usr/local' 'MPFR_PREFIX=/usr/local'
See also
[...]/workspace/ebpf-verifier/external/crab/build/elina-prefix/src/elina-stamp/elina-build-*.log
make[4]: *** [elina-prefix/src/elina-stamp/elina-build] Error 1
make[3]: *** [CMakeFiles/elina.dir/all] Error 2
make[2]: *** [CMakeFiles/elina.dir/rule] Error 2
make[1]: *** [elina] Error 2
make: *** [crab_install] Error 2
Error:
$ cat elina-build-err.log
clang: warning: -lmpfr: 'linker' input unused [-Wunused-command-line-argument]
clang: warning: -lgmp: 'linker' input unused [-Wunused-command-line-argument]
clang: warning: -lm: 'linker' input unused [-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '-L../elina_linearize' [-Wunused-command-line-argument]
elina_scalar.c:27:10: fatal error: 'stdlib.h' file not found
#include <stdlib.h>
^~~~~~~~~~
1 error generated.
make[6]: *** [elina_scalar.o] Error 1
make[5]: *** [c] Error 2
From @caballa on October 15, 2016 23:32
One simple option is to integrate BDDApron but it is implemented in OCaml so it will add more dependencies to Crab and it would still require changes for supporting Crab domains.
Instead, I prefer to re-implement BDDApron by combining the ADD library (MTBDD) provided by CUDD with the existing Crab domains.
Copied from original issue: caballa/crab#6
From @caballa on June 25, 2017 21:40
A crab variable can contain a pointer (e.g., crab-llvm stores Value*
in a crab variable and seahorn stores Expr
). This is very useful when we want to map back crab results to the client. The boxes domain keeps a global map from variables to internal ids. If the destructor of the factory that created the pointer to Value
or Expr
is called before than the global map is released then it leaves the instance of the boxes domain in an inconsistent state.
Copied from original issue: caballa/crab#17
I tried playing with the dev
branch today (71fea99), but got this warning:
In file included from /home/avj/clones/crab/dev/build/_INSTALL_DIR_/../../tests/./crab_dom.hpp:6,
from /home/avj/clones/crab/dev/build/_INSTALL_DIR_/../../tests/common.hpp:6,
from 01_simple_crab.cpp:1:
/home/avj/clones/crab/dev/build/_INSTALL_DIR_/crab/include/crab/domains/array_adaptive.hpp:64:35: warning: comparison between ‘enum crab::domains::array_adaptive_impl::DefaultParams::<unnamed>’ and ‘enum crab::domains::array_adaptive_impl::DefaultParams::<unnamed>’ [-Wenum-compare]
static_assert(max_array_size <= max_smashable_cells,
^~~~~~~~~~~~~~~~~~~
/home/avj/clones/crab/dev/build/_INSTALL_DIR_/crab/include/crab/domains/array_adaptive.hpp:77:35: warning: comparison between ‘enum crab::domains::array_adaptive_impl::NoSmashableParams::<unnamed>’ and ‘enum crab::domains::array_adaptive_impl::NoSmashableParams::<unnamed>’ [-Wenum-compare]
static_assert(max_array_size <= max_smashable_cells,
It seems that this is a legitimate issue, as max_array_size
and max_smashable_cells
come from different enums.
GCC version
g++ (GCC) 8.3.1 20191121 (Red Hat 8.3.1-5)
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Abstract domains only support arithmetic operations in three-address form (e.g., +,-,*,/) and addition of linear constraints.
Abstract domains do not support addition of non-linear constraints. Moreover, linear constraints are simplified on-the-fly to keep a normalized form. This does not work well if linear constraints are defined over machine arithmetic because those simplifications are not sound. To address these issues, we should have tree expressions (similar to those defined by Apron) which can be converted to linear constraints (if possible/wanted) by each abstract domain.
g++-8 now warns about "writing to an object of non-trivially copyable type" using memcpy:
crab/install/include/crab/domains/graphs/adapt_sgraph.hpp:59:15:
error: ‘void* memcpy(void*, const void*, size_t)’
writing to an object of non-trivially copyable type ‘class crab::AdaptSMap<long unsigned int>::elt_t’;
use copy-assignment or copy-initialization instead [-Werror=class-memaccess]
memcpy(dense, o.dense, sizeof(elt_t)*sz);
~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The warning is enabled automatically on -Wall
.
From @caballa on June 30, 2017 16:49
If we have x - y + z >= 5
we can translate into three interval constraints:
x >= Intervals(y-z) + 5
y <= Intervals(x+z) - 5
z >= Intervals(y-x) + 5
where Intervals
evaluate each variable to an interval constraint.
Copied from original issue: caballa/crab#19
adapt_sgraph.hpp
assumes that the graph weights are basic types. The assumption for basic types is because we use memcpy
and realloc
for efficiency reasons. Thus, to use bignums as weights we should change the implementation which might affect performance. The changes are needed here:
domains/graphs/adapt_sgraph.hpp
domains/graphs/util/Vec.h
This is related to issue #21. Thanks to @elazarg to bring it in!
Hi,
I just started playing around with crab
(so I am very inexperienced here!) and I wanted to model something like this:
void foo(int x) {
int y = 0;
if (x >= 10 && x <= 20) {
y = x;
} else if (x >= -20 && x <= -10) {
y = x;
} else {
y = 0;
}
// y = ([-20, -10], [0], [10, 20])
++y;
// y = ([-10, -9], [1], [11, 21])
}
Using one of the examples, I got this far:
#include <crab/common/types.hpp>
#include <crab/config.h>
#include <crab/domains/wrapped_interval_domain.hpp>
#include <crab/numbers/wrapint.hpp>
#include <iostream>
using namespace std;
using namespace crab::domains;
typedef wrapped_interval<ikos::z_number> wrapped_interval_t;
int main(void) {
wrapped_interval_t i1(crab::wrapint(10, 32), crab::wrapint(20, 32));
wrapped_interval_t i2(crab::wrapint(-10, 32), crab::wrapint(-20, 32));
crab::outs() << "i1 & i2: " << (i1 & i2) << "\n";
return 0;
}
but this just seems to expand the domain to be [-20, 20]
, rather than join the "disjointly" (apologies for wrong terminology) -- that is, what I want is ([-20, -10], [10, 20])
.
Is this something I can do with crab
or are these just "disjoint intervals" not possible with the library?
Thanks!
I noticed that these operations are not implemented in crab's wrapped_interval:
/// wrapped_interval_domain implements only standard abstract
/// operations of a numerical domain so it is intended to be used as
/// a leaf domain in the hierarchy of domains.
BOOL_OPERATIONS_NOT_IMPLEMENTED(wrapped_interval_domain_t)
ARRAY_OPERATIONS_NOT_IMPLEMENTED(wrapped_interval_domain_t)
REGION_AND_REFERENCE_OPERATIONS_NOT_IMPLEMENTED(wrapped_interval_domain_t)
DEFAULT_SELECT(wrapped_interval_domain_t)
Can this implementation retain the ideas of the TOPLAS15 paper?
For example, to handle branch condition like s < t, the paper update s and t respectively. But, in crab, we may transform this condition to a linear constraint s - t < 0, and solve this? Does this handling method safe in machine integer operation semantics?
I'm not very familiar with crab.
The issue seem to come from array_expansion.hpp:1287
- missing if (!ignore_array_store)
in the condition.
Valgrind traceback:
ebpf-verifier (post-submission)$ valgrind ./check ebpf-samples/cilium/bpf_lxc.o 2/7 --domain=polyElina
==31540== Memcheck, a memory error detector
==31540== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==31540== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==31540== Command: ./check ebpf-samples/cilium/bpf_lxc.o 2/7 --domain=polyElina
==31540==
exception vector product
exception vector product
exception vector product
exception vector product
check: /usr/include/boost/optional/optional.hpp:1205: boost::optional<T>::reference_type boost::optional<T>::get() [with T = ikos::z_number; boost::optional<T>::reference_type = ikos::z_number&]: Assertion `this->is_initialized()' failed.
==31540==
==31540== Process terminating with default action of signal 6 (SIGABRT)
==31540== at 0x5967077: raise (raise.c:51)
==31540== by 0x5948534: abort (abort.c:79)
==31540== by 0x594840E: __assert_fail_base.cold.0 (assert.c:92)
==31540== by 0x5958141: __assert_fail (assert.c:101)
==31540== by 0x31666E: get (optional.hpp:1205)
==31540== by 0x31666E: operator* (optional.hpp:1222)
==31540== by 0x31666E: crab::domains::array_expansion_domain<crab::domains::elina_domain_<ikos::z_number, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string, (crab::domains::elina_domain_id_t)2> >::array_store_range(ikos::variable<ikos::z_number, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string>, ikos::linear_expression<ikos::z_number, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string>, ikos::linear_expression<ikos::z_number, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string>, ikos::linear_expression<ikos::z_number, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string>, ikos::linear_expression<ikos::z_number, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string>) (array_expansion.hpp:1287)
==31540== by 0x317107: crab::analyzer::intra_abs_transformer<crab::domains::array_expansion_domain<crab::domains::elina_domain_<ikos::z_number, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string, (crab::domains::elina_domain_id_t)2> > >::exec(crab::cfg::array_store_stmt<ikos::z_number, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string>&) (abs_transformer.hpp:518)
==31540== by 0x2ACA8E: crab::analyzer::fwd_analyzer<crab::cfg::cfg_ref<crab::cfg::cfg<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string, ikos::z_number> >, crab::analyzer::intra_abs_transformer<crab::domains::array_expansion_domain<crab::domains::elina_domain_<ikos::z_number, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string, (crab::domains::elina_domain_id_t)2> > > >::analyze(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, crab::domains::array_expansion_domain<crab::domains::elina_domain_<ikos::z_number, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string, (crab::domains::elina_domain_id_t)2> >&) (fwd_analyzer.hpp:80)
==31540== by 0x2B4E71: ikos::interleaved_fwd_fixpoint_iterator_impl::wto_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, crab::cfg::cfg_ref<crab::cfg::cfg<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string, ikos::z_number> >, crab::domains::array_expansion_domain<crab::domains::elina_domain_<ikos::z_number, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string, (crab::domains::elina_domain_id_t)2> > >::visit(ikos::wto_vertex<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, crab::cfg::cfg_ref<crab::cfg::cfg<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string, ikos::z_number> > >&) (fwd_fixpoint_iterators.hpp:419)
==31540== by 0x201409: ikos::wto<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, crab::cfg::cfg_ref<crab::cfg::cfg<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string, ikos::z_number> > >::accept(ikos::wto_component_visitor<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, crab::cfg::cfg_ref<crab::cfg::cfg<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string, ikos::z_number> > >*) (wto.hpp:743)
==31540== by 0x1D2C79: run (fwd_fixpoint_iterators.hpp:261)
==31540== by 0x1D2C79: Run (fwd_analyzer.hpp:138)
==31540== by 0x1D2C79: run (fwd_analyzer.hpp:285)
==31540== by 0x1D2C79: crab::checker::checks_db analyze<crab::domains::array_expansion_domain<crab::domains::elina_domain_<ikos::z_number, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string, (crab::domains::elina_domain_id_t)2> > >(crab::cfg::cfg<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string, ikos::z_number>&, boost::signals2::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), boost::signals2::optional_last_value<void>, int, std::less<int>, boost::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, boost::function<void (boost::signals2::connection const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, boost::signals2::mutex>&, boost::signals2::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), boost::signals2::optional_last_value<void>, int, std::less<int>, boost::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, boost::function<void (boost::signals2::connection const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, boost::signals2::mutex>&) (crab_verifier.cpp:156)
==31540== by 0x1DA725: std::_Function_handler<crab::checker::checks_db (crab::cfg::cfg<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string, ikos::z_number>&, boost::signals2::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), boost::signals2::optional_last_value<void>, int, std::less<int>, boost::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, boost::function<void (boost::signals2::connection const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, boost::signals2::mutex>&, boost::signals2::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), boost::signals2::optional_last_value<void>, int, std::less<int>, boost::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, boost::function<void (boost::signals2::connection const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, boost::signals2::mutex>&), crab::checker::checks_db (*)(crab::cfg::cfg<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string, ikos::z_number>&, boost::signals2::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), boost::signals2::optional_last_value<void>, int, std::less<int>, boost::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, boost::function<void (boost::signals2::connection const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, boost::signals2::mutex>&, boost::signals2::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), boost::signals2::optional_last_value<void>, int, std::less<int>, boost::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, boost::function<void (boost::signals2::connection const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, boost::signals2::mutex>&)>::_M_invoke(std::_Any_data const&, crab::cfg::cfg<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, crab::cfg::var_factory_impl::variable_factory<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::indexed_string, ikos::z_number>&, boost::signals2::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), boost::signals2::optional_last_value<void>, int, std::less<int>, boost::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, boost::function<void (boost::signals2::connection const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, boost::signals2::mutex>&, boost::signals2::signal<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&), boost::signals2::optional_last_value<void>, int, std::less<int>, boost::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, boost::function<void (boost::signals2::connection const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>, boost::signals2::mutex>&) (std_function.h:283)
==31540== by 0x1D14F5: operator() (std_function.h:687)
==31540== by 0x1D14F5: analyze (crab_verifier.cpp:232)
==31540== by 0x1D14F5: abs_validate(Cfg const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, program_info) (crab_verifier.cpp:72)
==31540==
==31540== HEAP SUMMARY:
==31540== in use at exit: 463,322,523 bytes in 4,653,262 blocks
==31540== total heap usage: 48,232,624 allocs, 43,579,362 frees, 4,789,812,024 bytes allocated
==31540==
==31540== LEAK SUMMARY:
==31540== definitely lost: 2,784,843 bytes in 142,118 blocks
==31540== indirectly lost: 326,439 bytes in 16,535 blocks
==31540== possibly lost: 155,348,967 bytes in 1,107,462 blocks
==31540== still reachable: 304,862,274 bytes in 3,387,147 blocks
==31540== suppressed: 0 bytes in 0 blocks
==31540== Rerun with --leak-check=full to see details of leaked memory
==31540==
==31540== For counts of detected and suppressed errors, rerun with: -v
==31540== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Aborted (core dumped)
It requires to implement make_thresholds
in apron_domains.hpp
.
There are at least two examples:
tests/domains/test2-rat.cc
tests/domains/test3-rat.cc
that would be benefit.
I noticed some cases with split_dbm and sparse_dbm where the analysis does not converge because one of the widening operands is wrong due to COW. For now, I decide to disable COW but with some time I should revisit it and fix it.
For future debugging (it requires to use crab-llvm)
crabllvm ./simple_array_index_value_true-unreach-call4_true-termination.pp.bc --crab-turn-undef-nondet --crab-lower-select --crab-dom=zones --crab-inter-sum-dom=zones --crab-widening-delay=2 --crab-widening-jump-set=0 --crab-narrowing-iterations=2 --crab-relational-threshold=10000 --crab-track=arr --crab-singleton-aliases --crab-add-invariants=none --crab-check=assert --crab-stats
Running valgrind when using the sdbm domain I get a warning about "use of uninitialized value of size 8" and "Conditional jump depends on uninitialized value" in this line.
I'm not sure which of the variables triggers this error; I would guess it's the dense
field since it is of size 8.
(I used the file samples/self/accept_DIV32_overflow_check_1.3
in the bpf verifier)
x & K
can at least be inferred to be <= K
. This is not the case currently.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.