Tai-e 框架(教学版)配置指南

本节介绍如何配置实验作业所需的 Tai-e 框架(教学版)。

目前,Tai-e 利用 Soot 前端解析 Java 程序并帮助构建 Tai-e IR。Soot 有两个前端,分别处理 Java 源代码文件(.java)和字节码文件(.class)。其中,前者可以将源代码中的变量名保留至 IR 中,从而使得生成的 IR 更贴近源码,比后者的更易于理解。因此,在实验作业中,测试用例(即待分析的程序)都以 Java 源文件的格式提供。然而,Soot 的 Java 源文件前端已经过时(只对最高 Java 7 版本提供部分支持)且不够健壮。与之相比,尽管 Soot 的字节码文件前端不能保持原先的变量名,但它更加健壮(对最高 Java 17 版本编译生成的 .class 文件都提供支持)。因此,分析真实世界的程序时,Tai-e 往往分析字节码。

0 下载实验作业

只需将 Tai-e 实验作业的 GitHub 仓库 Tai-e-Assignmentsopen in new window 克隆到本地即可,该仓库包含所有作业所需的代码及其依赖。

1 实验作业内容

Tai-e 实验作业仓库下有多个子目录,包含各个作业对应的 Tai-e 项目(如 A1/tai-e/ 对应作业 1 的 Tai-e 项目)。Tai-e 利用 Gradle 构建,并符合一般 Gradle 项目的结构,所有实验作业项目都具有如下结构:

  • build.gradle.ktsgradlewgradlew.batgradle/:Gradle 脚本和 Tai-e 项目配置文件。
  • src/main/java:Tai-e 源代码文件夹。你需要修改该文件夹中的文件以完成作业。
  • src/test/java:运行测试用例所需的测试驱动程序(test drivers)所在文件夹。
  • src/test/resources:测试用例(待分析的程序)文件夹。
  • lib/:包含 Tai-e 类的文件夹。
  • plan.yml:Tai-e 配置文件,设定了作业中需要执行的分析。
  • COPYING, COPYING.LESSER:Tai-e 许可文件。

2 配置步骤

Tai-e 使用纯 Java 开发,因而可以在大部分主流操作系统上运行,如 Windows,Linux,MacOS。构建和运行 Tai-e 需要安装 Java 17。本节包含了 Java 17 安装指引。

你可以从此处open in new window下载到 Java 17,也可以使用包管理工具(如系统包管理或 Sdkman! 等)安装 Java 17,但是如果你选用我们推荐的方式,你不需要使用以上方式安装 Java 17。

我们极力推荐大家使用 IntelliJ IDEA 来完成本课程的实验作业。利用 Gradle 构建脚本,可以很容易地以如下方式将 Tai-e 导入至 IntelliJ IDEA。

步骤 1

JetBrains 官网open in new window下载 IntelliJ IDEA 并安装(其中 Windows 和 MacOS 版本提供了安装器,Linux 版本则提供了大部分发行版解压后即可运行的压缩包)。建议安装较新版本的 IntelliJ IDEA(2021.3 或更新版本)从而获得更佳的 Java 17 支持。

注:你可能疑惑:没有 Java 运行环境如何能运行 IntelliJ IDEA?实际上 IntelliJ IDEA 内置了一份 JRE,供其内部使用。

注意:我们接下来介绍导入作业 1(对应 Tai-e 实验作业仓库下的 A1/tai-e/)的步骤,导入其它作业的步骤与之完全一样。

步骤 2

打开项目。

Open Project

注:如果你已使用过 IntelliJ IDEA,并打开了一些项目,请使用 File > Open… 来打开与下一步相同的界面。

步骤 3

选择 A1/tai-e/ 文件夹,点击 “OK”。

Select Folder

步骤 4

IntelliJ IDEA 可能会弹出下图窗口询问你是否信任该 Gradle 项目。点击 “Trust Project” 信任该项目(别担心,Tai-e 是可信的😊)。

Trust Project

这样导入操作就完成了。你可能需要等待一段时间以导入 Tai-e。之后,tai-e/ 文件夹中会生成一些与 Gradle 相关的文件和文件夹,你可以忽略它们。

步骤 5

打开 File > Project Structure…,展开 “SDK” 下拉菜单,选择 Add SDK > Download JDK… ,在弹出的窗口中选择 Version 为 17,Vendor 任意(通常选择 Oracle OpenJDK),Location 选择安装位置,一般保持默认即可,点击 Download 开始后台下载。

Download Java

然后展开 “Language level”,选择 “SDK default”(如果默认值是后者)或 “17 - Sealed types, always-strict floating-point semantics”。

Select Language Level

注:如果你已安装 JDK 17,在展开 SDK 下拉菜单后,直接选择你安装的 JDK 并选择 Language level 即可。如果你的 IntelliJ IDEA 已经选择 JDK 17 和 Java 17 作为默认 SDK 及 "Language level",则配置后续作业时可跳过此步。

步骤 6 (可选)

由于 Tai-e 是一个 Gradle 项目,IntelliJ IDEA 默认使用 Gradle 构建并运行它,这使得构建较慢且总会输出一些烦人的 Gradle 信息:

Gradle Information

为解决这些问题,可以使用 IntelliJ IDEA 而非 Gradle 来构建和运行 Tai-e。打开 File > Settings,将 Build and run 设置中的构建和运行工具从 Gradle 改为 IntelliJ IDEA,如下图:

Switch Gradle Integration

或者,如果你(真的)想用命令行构建 Tai-e,你可以 cdtai-e/ 文件夹下,并使用 Gradle 构建:

$ gradlew compileJava

完成以上步骤后,一个 Tai-e 框架(教学版)的环境配置就完成了。 ヽ(。◕‿◕。)ノ゚

3 以应用软件的形式运行 Tai-e

我们在 Tai-e 中为实验作业提供了一个特殊的类:

pascal.taie.Assignment

它提供了一种简单的使用方式来分析Java程序:

-cp <CLASS_PATH> -m <CLASS_NAME>

其中,<CLASS_PATH> 是 .class 文件所在文件夹的路径,<CLASS_NAME> 是待分析类的类名。Tai-e 会在路径给定的文件夹中寻找该类。比如,要分析 src/test/resources/dataflow/livevar 中的 Assign.java,首先在 IntelliJ IDEA 中打开 Assignment 的 “Run Configuration”:

Open Run Configuration

然后按下图配置 Program arguments:

Set Program Arguments

Tai-e 分析输入的程序并输出分析结果。不同作业中执行的分析和输出各不相同,我们会在各项目的文档中详细说明。

当然你也可以用 Gradle 运行分析:

$ gradlew run --args="-cp <CLASS_PATH> -m <CLASS_NAME>"

我们鼓励你用这一小节介绍的方法来分析你自己编写的 Java 程序,这样有助于你测试自己分析算法的实现、探索分析算法的效用、从而加深对算法的理解。在这个过程中你可能会遇到一些问题。为此,我们把常见的问题和解决方案集中到了 用 Tai-e 框架(教学版)分析自制用例 这一节中以供读者方便查阅。

4 使用 JUnit 测试你的实验作业

为了方便大家测试,我们在 src/test/resources/ 文件夹中准备了一些 Java 类和测试输入。每个类都对应于一个名为 *-expected.txt 的期望测试结果文件。可以(用 JUnit)运行测试类来分析 src/test/java/ 中的测试输入。不同实验作业有不同测试用例和测试驱动程序,在各实验作业的文档中会详细说明。

测试驱动程序会对 src/test/resources/ 下所有测试用例执行分析,并将其输出与期望结果进行比较。如果实现正确,你会通过测试,否则测试驱动程序会失败并输出期望结果和执行结果的不同之处。

同样,你也可以使用 Gradle 运行测试:

$ gradlew clean test

该命令会清空构建目录,重新构建 Tai-e 并执行测试。

需要注意的是,框架自带的测试输入并不全面,这对于测试分析算法实现的正确性是远远不够的。为此,我们准备了一个在线评测系统open in new window,里面包含了更多覆盖边界情况的测试用例来评测你的实现。但是这里面有一部分测试用例是不公开的——我们希望你能自己思考边界条件并编写相应的测试用例。关于在线评测系统的使用,你可以参考实验作业评测系统使用指南

Last Updated: