[klee-dev] A question on using gcov for coverage testing

刘梓涵 zihanliu at zju.edu.cn
Tue Apr 2 07:53:09 BST 2024


Dear klee developers,

I am recently using klee for test case generation and it has been proved to be an efficient tool in the field of symbolic execution. But when it comes to coverage, a question occurs.




Currently the coverage type i want is modified condition/decision coverage, but klee only give icov and bcov by running klee-istats command; luckily, these are open-source tools for mc/dc coverage from gcov's coverage, so i have to figure out a way to use gcov at least to find line coverage. 




The guide to test coreutils is so old that it cannot accually run at least in my linux system, so my sample code originated from another non-official tutorial for automatic testing is as follows and we can discuss based on this. 



# main.c


#include <klee/klee.h>
#include "match.h"
#define SIZE 7


int main() {
  // The input regular expression.
  char re[SIZE];
 
  // Make the input symbolic.
  klee_make_symbolic(re, sizeof re, "re");


  // // Try to match against a constant string "hello".
  // match(re, "hello");


  return 0;
}


# match.c


#include <klee/klee.h>


static int matchhere(char*,char*);


static int matchstar(int c, char *re, char *text) {
  do {
    if (matchhere(re, text))
      return 1;
  } while (*text != '\0' && (*text++ == c || c== '.'));
  return 0;
}


static int matchhere(char *re, char *text) {
  if (re[0] == '\0')
     return 0;
  if (re[1] == '*')
    return matchstar(re[0], re+2, text);
  if (re[0] == '$' && re[1]=='\0')
    return *text == '\0';
  if (*text!='\0' && (re[0]=='.' || re[0]==*text))
    return matchhere(re+1, text+1);
  return 0;
}


int match(char *re, char *text) {
  if (re[0] == '^')
    return matchhere(re+1, text);
  do {
    if (matchhere(re, text))
      return 1;
  } while (*text++ != '\0');
  return 0;
}


# match.h


#include <klee/klee.h>


#ifndef _MATCH_H_
#define _MATCH_H_


int match(char *re, char *text);


#endif




And code to execute klee SE process as follows:


clang -I ../../../include -emit-llvm -c -g -O0 -Xclang -disable-O0-optnone *.c -c
llvm-link *.bc -o linked.bc
rm $(ls *.bc | grep -v linked.bc)
klee linked.bc




Currently i have know about how to separately use gcov for coverage testing, just a modification from klee_make_symbolic to accepted c arguments. For example a modify on main.c:



#include"match.h"
#defineSIZE7


intmain(intargc, char**argv) {
  charre[SIZE];


  // Assuming the input is passed as a command-line argument.
  if(argc >1) {
    strncpy(re, argv[1], SIZE);
    re[SIZE -1] ='\0'; // Ensure null-termination.
  } else {
    printf("Usage: %s <regular_expression>\n", argv[0]);
    return1;
  }
 
  // Try to match against a constant string "hello".
  match(re, "hello");


  return0;
}



Then separatly using gcov:


gcc -Wall-fprofile-arcs-ftest-coverage*.c


# This is just a sample, actually we need to :
# 1. ktest-tool to get all test cases in plain text form;
# 2. loop through the plain text and execute on out program
./a.out 3


gcov a-cov.c


However this intrusive way may break the code itself and i need a way to integrate klee testing and gcov coverage. As coreutils tutorial mentioned, "At its core, KLEE is just an interpreter for LLVM bitcode. " However actually i have not figured out how to use .bc code at the execution and gcov process.I even trys 


clang -fprofile-arcs -ftest-coverage -I ../../../include -emit-llvm -c -g -O0 -Xclang -disable-O0-optnone *.c -c




but it seems donnot work. As a newbee for klee, i want to ask about:
1. How to combine klee test case gen and gcov coverage process? 
2. Potentially, is there other ways klee support for generate mc/dc coverage?

Thank you!

Yours sincerely,
Zihan Liu
-------------- next part --------------
HTML attachment scrubbed and removed


More information about the klee-dev mailing list