klee / klee

KLEE Symbolic Execution Engine

Home Page:https://klee-se.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question about --make-concrete-symbolic

qichang3 opened this issue · comments

To ask a question about KLEE:

  1. Please first check the documentation at http://klee.github.io/docs/
  2. Then check the searchable mailing list archive
  3. If this still doesn’t answer your questions then please send an email to the klee-dev mailing list

We will normally not answer questions asked on GitHub.
I am trying to explore program:

// int.c
#include "klee/klee.h"
#include <stdio.h>
#include <stdlib.h>
// CHECK-DAG: abs
int main() {
  int x;
  int y = abs(x);
  if (y == 1) {
    printf("y is 1\n");
  } else {
    printf("y is not 1\n");
    if(x == 7) {
      printf("x is 7\n");
    } else {
      printf("x is not 7\n");
    }
  }
  return 0;
}

with

klee --max-solver-time=30 --search=bfs --external-calls=all -make-concrete-symbolic=1 int.bc

Then I found the parameter -make-concrete-symbolic cannot make KLEE explore more paths:

KLEE: Using Z3 solver backend
KLEE: WARNING: undefined reference to function: abs
KLEE: WARNING: undefined reference to function: printf
Making symbolic: (NotOptimized (Eq 2880154539
                   (ReadLSB w32 0 rrws_arr1)))
KLEE: WARNING ONCE: calling external: abs((ReadLSB w32 0 rrws_arr1)) at [no debug info]
Making symbolic: (NotOptimized (Eq 1414812757
                   (ReadLSB w32 0 rrws_arr2)))
KLEE: WARNING ONCE: calling external: printf(47472944) at [no debug info]
y is not 1
Making symbolic: (NotOptimized (Eq 2880154539
                   (ReadLSB w32 0 rrws_arr3)))
x is not 7

KLEE: done: total instructions = 18
KLEE: done: completed paths = 1
KLEE: done: partially completed paths = 0
KLEE: done: generated tests = 1

I found the function ref<Expr> Executor::replaceReadWithSymbolic(ExecutionState &state, ref<Expr> e) will add an Eq(concrete, symbolic) (such as (Eq 2880154539 (ReadLSB w32 0 rrws_arr1)) ) to path condition every time replace concrete with symbolic, which restricts the symbolic value and makes KLEE unable to explore more paths related to symbolic value.

I commented the related code:
image

Then KLEE can explore more paths:

KLEE: Using Z3 solver backend
KLEE: WARNING: undefined reference to function: abs
KLEE: WARNING: undefined reference to function: printf
Making symbolic: (NotOptimized (Eq 2880154539
                   (ReadLSB w32 0 rrws_arr1)))
KLEE: WARNING ONCE: calling external: abs((ReadLSB w32 0 rrws_arr1)) at [no debug info]
Making symbolic: (NotOptimized (Eq 0
                   (ReadLSB w32 0 rrws_arr2)))
KLEE: WARNING ONCE: calling external: printf(45212032) at [no debug info]
y is 1
y is not 1
Making symbolic: (NotOptimized (Eq 2880154539
                   (ReadLSB w32 0 rrws_arr3)))
x is 7
x is not 7

KLEE: done: total instructions = 25
KLEE: done: completed paths = 3
KLEE: done: partially completed paths = 0
KLEE: done: generated tests = 3

It seems that restrict the symbolic value to a specific constant value will make symbolic useless for exploring more paths. Is that a bug or the parameter -make-concrete-symbolic is supposed to act like this?

@qichang3 This functionality naming is unfortunately misleading. It generates internal expression that should have been folded to concrete expressions and is meant for testing mostly.

In case you want to test with symbolic values, please use klee_make_symbolic to explicitly mark objects as symbolic (https://klee.github.io/tutorials/testing-function/).

Your example would be:

// int.c
#include "klee/klee.h"
#include <stdio.h>
#include <stdlib.h>
// CHECK-DAG: abs
int main() {
  int x;
  klee_make_symbolic(&x, sizeof(x), "my x");
  int y = abs(x);
  if (y == 1) {
    printf("y is 1\n");
  } else {
    printf("y is not 1\n");
    if(x == 7) {
      printf("x is 7\n");
    } else {
      printf("x is not 7\n");
    }
  }
  return 0;
}

Please re-open this issue if it doesn't solve your problem.

Thanks for your kind reply, it helps me better understand KLEE.