KLEE 使用(二)------ 怎么自动地生成测试用例?

在这篇博客中,我们将展示如何使用 KLEE 自动地为一些整数相关的小实例(用 C 语言编写)生成测试用例,在下篇博客中,我们将用 KLEE 来测试一段二分查找算法的代码,生成测试用例。

符号执行是不同于实际运行程序的,在符号执行中,我们跟踪的不是变量的实际值,而是其“符号值”和对这些值的操作。所以,对于如下这段函数代码:

int many_math_operations(int x) {
    int result = x * 2;
    result += 5;
    result /= -3;
    result *= (result+1);
    return result;
}

如果我们将变量 x 的值看成是一个未知的 X,则这个函数的结果是:
在这里插入图片描述
符号执行也处理一些条件语句(if,while,do-while,for)等。例如:

int function_with_if(int x) {
    if (x > 0) {
        return 10 / x;
    } else {
        return 10 / (x + 1);
    }
}

在上面的函数中,符号执行尝试去覆盖到所有可能的路径。对于每条路径,它都会找到满足路径条件的输入并且根据符号表达式产生输出。

对于 X > 0 的情况,输出将是 10/X(接下来都使用大写字母来表示符号值)。
对于 !X > 0)的情况,输出将会是 10/(X+1)。

你能找到上述函数可能的错误码??KLEE 呢??


1、首先我们创建一个包含上述函数的本地文件(source_to_klee/examples/function_with_if/function_with_if.c)

#include <klee/klee.h>
#include <stdio.h>

int function_with_if(int x) {
    printf("input: %d\n", x);
    if (x > 0) {
        return 10 / x;
    } else {
        return 10 / (x + 1);
    }
}

int main() {
  int x;
  klee_make_symbolic(&x, sizeof(x), "x");
  int result = function_with_if(x);
  printf("result = %d\n", result);
  return 1;
}

main 函数中表示变量 x 应该视为符号值。

2、编译成 LLVM 字节码
clang -I source_to_klee/include/ -emit-llvm -c -g -O0 -Xclang -disable-O0-optnone function_with_if.c

3、运行 KLEE
klee -external-calls=all source_to_klee/examples/function_with_if/function_with_if.bc
通过命令行选项 -external-calls=all 可以让 KLEE 在遇到 printf 函数调用的时候状态不会终结。
在这里插入图片描述
KLEE 找到了一个除零错误!!!

4、让我们看看生成的测试用例:
ktest-tool klee-out-0/test000001.ktest
在这里插入图片描述
可以看到在这个测试用例中,变量 x 的值是 int 型的 -1。同样你也可以查看第二个和第三个测试用例,你将看到被选择的输入分别是 0 和 16777216。KLEE 选择这些值是非常有用的,因为他们可以有效的检查边界情况。

5、让我们用不同的输入运行程序,观察程序的行为:
根据第一篇博文中类似的方式复现这个测试用例,如下:
在这里插入图片描述
可以看到产生了异常,程序被非正常终止。
在这里插入图片描述
同时复现第二个和第三个测试用例,结果如上。

在这篇博文中,我们使用 KLEE 分析了一个非常简单的示例。在下篇博客中,我们将使用 KLEE 自动地分析二分查找的小示例,生成测试用例。


[注]:在 KLEE 输出的文件夹中,发现对于第一个除零错误的测试用例,还生成了一个 .kquery 后缀文件和一个 .div.err 后缀文件,让我们看看里面都有啥。
.div.err 后缀文件(提供了缺陷类型,所在文件名和行数,调用栈信息):
在这里插入图片描述
.kquery 后缀文件(Kquery 格式的查询表达式):
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值