# PPT 补充 · IR/gdb 现场 + "+50%"用哪个目标

> 实验机 `ubuntu@cuda-ke`。图见本目录 `img_ir.png` / `img_gdb.png`。

---

## A. IR / gdb 现场（SymCC 插桩机制的实证）

演示程序 `ir_demo.c`：`int x; read(0,&x,4); if (x == 0xCAFE) puts("hit");`（0xCAFE=51966）。

### ① 编译期插桩 — LLVM IR（`img_ir.png`）
`build/symcc -S -emit-llvm ir_demo.c` 后，IR 里在【具体】指令旁**旁路注入** `_sym_*` 调用：

```
%21 = call ptr @_sym_read_memory(...)         ; x 源自输入 → 标记为符号量
%22 = load i32, ptr %2                         ; 取 x 具体值(照常执行)
%26 = call ptr @_sym_build_integer(51966,32)   ; 构造符号常量 0xCAFE
%27 = call ptr @_sym_build_equal(%21, %26)     ; 构造符号表达式  x == 0xCAFE
%30 = icmp eq i32 %22, 51966                   ; 原始【具体】比较(concrete)
call void @_sym_push_path_constraint(%29,%30,…); 记录路径约束 → 交 Z3 求反解
br i1 %30, label %34, label %36                ; 仍按具体结果跳转
```
**要点**：具体执行(icmp/br)原封不动，符号追踪是"旁挂"的——这就是 SymCC "编译进去、
不解释执行"的核心，比 SymQEMU/KLEE 快的根因。

### ② 运行时 concolic 追踪 — gdb（`img_gdb.png`）
`gdb` 断在两个运行时函数，喂 4 字节输入(x=0x61616161≠0xCAFE)：
```
Breakpoint 1, _sym_build_equal (...) at runtime/.../Runtime.cpp:267
  #1  main () at ir_demo.c:3            ← SymCC 构造 x==0xCAFE 的符号表达式
Breakpoint 2, _sym_push_path_constraint (constraint=…, taken=0, site_id=…) at Runtime.cpp:320
  #1  main () at ir_demo.c:3            ← 记录该分支(taken=0 未走), 待 Z3 求反解出 x==0xCAFE
```
真实回溯 `main → _sym_push_path_constraint`、真实参数 `taken=0 / site_id`，坐实"运行时把每个
输入相关分支的条件交给 QSYM/Z3 求解"。

---

## B. "+50%" 用哪个目标 —— SQLite（字典引导求解 `SYMCC_DICT`）

**答案：SQLite，单种子（只有 `SELECT`）场景下，开启字典引导求解（`SYMCC_DICT`=SQL 关键字字典）
带来 +50% 边覆盖。多样种子时 +0%（种子已覆盖字典关键字）。**

- 文献/原始实测（`docs/Work_Progress_Report.md:149`）：单种子 **1,802 → 2,710 edges = +50%**；
  25 个多样种子 **4,832 → 4,835 = +0%**。
- 机制（`solver.cpp:545` 读 `SYMCC_DICT`）：Z3 求解后，用 AFL 字典 token 替换被修改的字节位置，
  额外生成最多 20 个变体——单种子缺关键字时补上 SQL 关键字，故涨得多。
- 字典：`benchmark/public/fuzzer-test-suite/sqlite-2016-11-14/sql.dict`（284 tokens）。

### 本轮新做的 A/B 复现（实验机，单 `SELECT` 种子，8 进程 concolic，120s，afl-showmap -C 量边）
| 配置 | 语料 | 边覆盖 |
|---|---|---|
| 无字典 | 14,577 | **1,470 / 31552 (4.66%)** |
| `SYMCC_DICT=sql.dict` | 127,489 | **3,091 / 31552 (9.80%)** |
| **提升** | | **+110%** |

> 复现幅度（+110%）比原始（+50%）更大，是因为本轮设置（8 进程/120s/单 `SELECT 1;` 种子）与原始
> 不同——但**方向强一致：SQLite 单种子下字典引导带来数量级的覆盖提升**。deck 里引用 **+50%（SQLite
> 单种子，1802→2710）** 这个原始口径即可；本轮 A/B 作为独立复现佐证（数据文件 `09_dict_ab_sqlite.txt`）。

**一句话给答辩**：+50% 是 **SQLite 单种子 + SYMCC_DICT** 的数；它恰恰说明字典引导只在"种子贫瘠"时
有效，种子充分（或用 CmpLog 动态字典）时收益归零——这也是我们最终没把静态字典作为主力的原因。
