Giter VIP home page Giter VIP logo

crab's Issues

Possibly stack overflow while computing WTO of a large CFG

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.

Restrict API of CFG array_assume method

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

Optimize/cleanup array graph domain

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:

  1. landmarks must be kept as local state as part of each abstract
    state.

  2. 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

Adapt numerical domains for supporting reals

From @caballa on October 15, 2016 23:18

For intervals and zones, we need at least:

  • make sure rounding is correct (e.g., if upper bounds towards +oo, etc)
  • make sure division is correct
  • etc.

Copied from original issue: caballa/crab#4

Reaching Definitions Analysis

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 Options

CMake top-level options should be prefixed with CRAB. For example,

USE_LDD --> CRAB_ENABLE_LDD
USE_APRON --> CRAB_ENABLE_APRON

etc.

Question regarding the CFG input encoding for the analysis

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:
image
As I can not express statements such as NOT(activate) AND b I converted my input to SSA and three-address code as follows:
image
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?

"compress" `powerset_domain` domain after projection

Current status

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}

Question

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]?

Python API

From @caballa on April 17, 2017 4:40

Copied from original issue: caballa/crab#16

zones with bignum seems to be imprecise for computing summaries

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

Question regarding "cyclic" encoding and propagation of analysis results

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?

Bug in flat_boolean_domain

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.

How to correctly represent "else" when manually working with `powerset_domain`

Current situation

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;
}

Current issue

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.

Question

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.

Should we add the bitwise complement (~) operation in Crab?

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 ?

Bug with apron-domains and rationals

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

General question on "backward_assign_operations"

Two questions:

  1. Is it possible to use crab's "backwards assignment"s to calculate inputs at the "beginning" of a program? For example:
void foo(int y)
{
    y++;
    if (y > 10); // <-- if this was SSA, it would be something like "y__0 > 9"
}
  1. Are there any domains which support wrapped bit vectors and "work backwards"?

Elina does not compile on mac: `'stdlib.h' file not found`

(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

Add a logico-numerical abstract domain

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

An instance of boxes domain can be in an inconsistent state due to global state

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

Compiler warning with `dev`

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.

Create tree expressions and adapt abstract domains to use them

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:

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.

Make generic weights of adaptative sparse graph

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!

Question: "range of intervals"

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!

What is the difference between the wrapped_interval implemented in crab and the one implemented in TOPLAS15 paper?

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.

none-optional dereference on array-expansion domain with elina-pk

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)

Copy-on-write optimization in apron_domains, split_dbm, and sparse_dbm seems flaky

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

cow_bug_program.zip

Valgrind warnings

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.