1 介绍
-
Daikon是一个动态检测不变量的工具
-
不变量是程序中某个特定点上保持为真的属性,这些通常出现在断言语句,文档和形式化规范中。
-
不变量在程序理解和其它许多应用中都非常有用,例如,不变量可以是
- x.field > abs(y)
- y = 2 * x + 3
- 数组a是有序的
- 对于所有的列表对象lst,kst.next.prev = lst
- 等等,用户可以扩展Daikon以添加新的属性
-
动态不变量检测通过运行程序,观察程序计算的值,然后报告在观察到的执行过程中始终为真的属性。
- Daikon可以在C、C++、C#、Eiffel、F#、Java、Perl和Visual Basic程序中检测属性
- 在spreedsheet文件中
- 以及其它数据源中(动态不变量监测是一种可以应用于任意数据的机器学习技术)
-
Daikon完全开源
-
Daikon详情参考daion用户手册
-
本文记录本人使用daikon过程
2 下载Daikon
- 照着用户手册下载即可
- 注意daikon需要的shell环境变量
export DAIKONDIR=daikonparent/daikon-5.8.18 # daikon的安装目录
source $DAIKONDIR/scripts/daikon.bashrc
3 使用案例
C/C++
- 需要使用
gcc
和 编译选项-gdwarf-2 -no-pie
产生可执行文件- 对于通过
./configure
生成的Makefile,在./configure
前加入CC=gcc CFLAGS="-gdwarf-2 -no-pie"
即可
- 对于通过
- 使用 kvasir 前端产生daikon需要的文件,对于单次运行,只需要在正常运行指令前加上
kvasir-dtrace
即可,示例kvasir-dtrace ./wordplay -f words.txt 'Daikon Dynamic Invariant Detector'
- 随后使用daikon进行分析
java -cp $DAIKONDIR/daikon.jar daikon.Daikon \
daikon-output/wordplay.decls daikon-output/wordplay.dtrace
程序多次运行轨迹
- 对于多次运行的程序,需要将多次运行的轨迹合并,此时可以将各个轨迹分开,或者合成一个轨迹文件
- 分开轨迹文件(此种写法更好一些)
kvasir-dtrace --dtrace-file=daikon-output/wordplay1.dtrace \
./wordplay -f words.txt 'daikon dynamic invariant detector'
kvasir-dtrace --no-dyncomp --dtrace-file=daikon-output/wordplay2.dtrace \
./wordplay -f words.txt 'better results from multiple runs'
kvasir-dtrace --no-dyncomp --dtrace-file=daikon-output/wordplay3.dtrace \
./wordplay -f words.txt 'more testing equals better testing'
java -Xmx3600m -cp $DAIKONDIR/daikon.jar daikon.Daikon \ # 这里-Xmx3600m是为了增加java的堆栈大小,在大数据量的情况下需要
daikon-output/wordplay*.dtrace daikon-output/wordplay.decls # 这里的*是通配符
- 合并轨迹文件
kvasir-dtrace --dtrace-file=daikon-output/wordplay-all.dtrace \
./wordplay -f words.txt 'daikon dynamic invariant detector'
kvasir-dtrace --no-dyncomp --dtrace-append \
--dtrace-file=daikon-output/wordplay-all.dtrace \
./wordplay -f words.txt 'better results from multiple runs'
kvasir-dtrace --no-dyncomp --dtrace-append \
--dtrace-file=daikon-output/wordplay-all.dtrace \
./wordplay -f words.txt 'more testing equals better testing'
java -Xmx3600m -cp $DAIKONDIR/daikon.jar daikon.Daikon \
daikon-output/wordplay-all.dtrace daikon-output/wordplay.decls
注意事项
- 在示例中,很重要的一个示范是
java -cp $DAIKONDIR/daikon.jar daikon.Daikon \
--config_option daikon.derive.Derivation.disable_derived_variables=true \
daikon-output/wordplay.decls daikon-output/wordplay.dtrace
- 这里通过配置选项禁止派生变量的生成,大大减少了运算时间,而这派生变量许多都是无用的,这在第五部分Daikon输出中会有所说明
4 运行Daikon
- 运行Daikon使用以下命令:
java -jar daikon.jar --input=<dtrace文件路径> <其他选项>
- 其中<dtrace文件路径>是你要分析的.dtrace文件的路径
- <其他选项>是可选的命令行参数,用于配置Daikon的行为。例如,你可以使用–output=<输出文件路径>选项来指定输出文件的路径,或者使用–help选项来查看所有可用的命令行选项。
- 各Daikon的前端使用各不相同,详见手册
- spinfo文件是用于检测条件不变量(Conditional invariants)的分割信息文件。这些文件是可选的,可以自动创建或手动创建。
4.1 控制Daikon输出的选项
- –help
- -o inv_file:将序列化的不变量输出到指定文件,默认生成与dtrace文件同名的.inv.gz文件
- –no_text_output:不将不变量作为文本输出
- –format name:以给定格式生成输出,有关Daikon支持的输出列表参阅invariant语法
- –show_progress/–no_show_progress:打印或不打印执行Daikon主要部分的时间信息
- –show_detail_progress:同上,还包括不变量的详细信息
- –noversion:禁止打印版本信息
- –output_num_samples:输出不变量和程序点的数值和样本数量,这是一个调试选项,帮助理解Daikon产生了怎样的输出
- –files_from filename:从给定的文本文件中读取一系列.decls、.dtrace或.spinfo文件名,作为在命令行上提供文件名的替代方法
- –server dirname:Daikon的服务器模式,在该模式下,它会读取dirname中的文件(按字典顺序排序),直到找到一个以“.end”结尾的文件,然后计算并输出不变量
4.2 控制不变量探测的选项
- –conf_limit val:是一个命令行选项,用于设置Daikon在证明不变量的置信度限制。只有当给定的不变量置信度大于这个值Daikon才会输出
- val在0到1之间,.99为默认值,越大的值过滤越强
- 每种类型的不变量都有自己确定置信度的方法,参见Java 源代码中的 invariant 的 computeConfidence 方法。
- 考虑不变量a,有两种打印不变量置信度的方法
- 使用Diff(参见invariant Diff)
java -cp $DAIKONDIR/daikon.jar daikon.diff.Diff MyFile.inv.gz
- 使用PrintInvariants (参见 Printing invariants)
java -cp $DAIKONDIR/daikon.jar daikon.PrintInvariants --dbg daikon.PrintInvariants.repr \ MyFile.inv.gz
- 使用Diff(参见invariant Diff)
- 要打印被丢弃的每个不变量的置信度,请使用 --disc_reason all 命令行选项运行 Daikon(参见 Daikon Daikon debugging options)
- –list_type classname:表示给定的类实现了java.util.List接口。See ListImplementors declaration
- –user-defined-invariant classname:使用在给定类中定义的用户定义的不变量,而不是内置在Daikon中的不变量。
- –disable-all-invariants:禁用所有已知的不变量:那些内置在Daikon中的不变量,以及到目前为止通过–user-defined-invariant指定的所有不变量。在此选项指定后,可以重新启用某个不变量,参见启用/禁用特定不变量的选项。
- –nohierarchy:避免在数据流层次结构中连接程序点。
- –suppress_redundant:使用Simplify自动定理证明器抑制逻辑上多余的不变量的显示。
4.3 操作部分trace文件
- –ppt-select-pattern=ppt_regexp:仅处理名称与正则表达式匹配的程序点。–ppt-omit-pattern参数优先于此参数
- –ppt-omit-pattern=ppt_regexp:不处理名称与正则表达式匹配的程序点。此参数优先于–ppt-select-pattern参数
- –var-select-pattern=var_regexp:仅处理名称与正则表达式匹配的变量(无论是在跟踪文件还是在派生中)。–var-omit-pattern参数优先于此参数。
- –var-omit-pattern=var_regexp:忽略名称与正则表达式匹配的变量(无论是在跟踪文件还是在派生中)。此参数优先于–var-select-pattern参数。
- 将以上命令传给前端工具,可以让目标程序运行得更快,跟踪文件更小
4.4 Daikon配置选项
- –config filename: 从指定的文件中读取配置选项。更多信息参见 Configuration options
- –config_option name=value:指定一个配置选项
4.5 Daikon调试选项
- 更多参见后续 Debugging options
- –dbg category 和 --debug:这两个选项用于启用特定部分的Daikon的调试输出(日志输出)。可以通过多次指定–dbg category来实现对调试输出的细粒度控制。–debug选项会打开所有调试标志,这会产生很多输出!
- –track class<var1,var2,var3>@ppt:此选项用于在指定的类、变量和程序点上启用调试信息。
- –disc_reason inv_class<var1,var2,…>@ppt:此选项打印指定程序点处被丢弃的inv_class类的不变量,以及简短的原因和解释为什么它们不值得打印。
- –mem_stat:此选项将内存使用情况统计信息打印到当前目录中名为stat.out的文件中