# PPT 补充数据 · D1–D5 汇总（含全部材料下载链接）

> 实验机 `ubuntu@cuda-ke`（AMD Threadripper PRO,192 线程）。AFL++ 4.40c,clang/LLVM 18。
> 目标:libxml2 = `gfts-xml_read_fuzzer`;覆盖率 = `afl-showmap -C` 边覆盖（PCGUARD,collision-free）。
>
> **下载站**:所有文件在 **http://down.kew.ac/**（开了目录浏览,可直接点开看)。
> 本文所有图片/CSV/文本证据均给了直链,见各节内嵌链接与文末**〔附一〕全部文件下载清单**。
> 全量打包:**[symcc-ppt-material.tar.gz](http://down.kew.ac/symcc-ppt-material.tar.gz)**（~1.9 MB,含本文所有材料)。

---

## 〇、一句话总览（TL;DR)

| 项 | 结论 | 给答辩的用法 |
|---|---|---|
| **D1** | np=64 是甜点:16,881 tc/s、6.75% 边覆盖,**吞吐+覆盖都超过 128/190** | 回答"32→64 还线性吗、会否超 128" |
| **D2** | PCGUARD = **块级 guard**,afl-showmap 报的是**边级命中**,分母是真实 guard 数(非 65536 hash 图) | 定论"数 BB 还是数边",附实拍图 |
| **D3** | 覆盖率 = 正则解析 afl-showmap 的 `(X%)`,含"测量失败 vs 真 0"区分 | 给代码框 |
| **D4** | freetype2「np32 覆盖腰斩」**不成立**——3 轮显示 np8≈np32,原 5.59% 是单轮离群 | **务必据此改 deck** |
| **D5** | 单进程 ~178 tc/s;MPI 协调开销 <0.5%;负载极不均随 np 恶化(np32 有⅓ worker 空转) | 坐实"过并行浪费"的机理 |

**贯穿主线**:*有效"重活"就那么几份*——所以并行度过了"几十个 worker"纯属浪费,这就是**自适应封顶 SymCC
worker(~12)+ 拉 AFL 进来做 hybrid** 的根据。D1/D4/D5 四路数据互证这条主线(串词见文末**〔附二〕**)。

> 除 D1–D5 外,本轮之前还交付了一批 PPT 支撑材料(插桩核实/真实截图/#10 冗余拆分/约束量级/IR·gdb/
> CONFETTI 等),汇总见 **第六节"其它补充材料"**,下载见**〔附一〕**。

---

## D1 · np=64 实测〔评委第一优先〕

**一行插表**:`mpi np=64 → 16,881 tc/s,edge_cov 6.75%(3432/50880)`
(另 hybrid np=64 → 1,450 tc/s,10.91% / 5553/50880)

补上 np=64 后的 MPI 扩展全貌(libxml2,120s,`afl-showmap -C` 量边):

| np | 2 | 8 | 32 | **64** | 128 | 190 |
|---:|---:|---:|---:|---:|---:|---:|
| tc/s | 128 | 1,604 | 7,683 | **16,881** | 15,022 | 13,906 |
| edge_cov | 5.67% | 5.88% | 6.13% | **6.75%** | 6.26% | 6.17% |

- **吞吐**:32→64 **超线性**(7,683→16,881 = **2.20×**);且 **64 是峰值**,64→128→190 反而**递减**。
- **边覆盖**:32→64 上升(6.13→6.75%),**np=64 同时超过 np=128(6.26%)与 np=190(6.17%)**。
- **结论**:**甜点 ≈ 64**;过 64 后吞吐与覆盖**双双回落**(worker 冗余/争用 + 调度压力,机理见 D5③)。
  正好补上评委说"图不清晰"那段——64 不是继续线性涨,而是**拐点**,且明确优于 128/190。

📎 原始数据:[03_benchmark_report_scaling_hybrid.txt](http://down.kew.ac/03_benchmark_report_scaling_hybrid.txt) ·
[03_benchmark_data_scaling_hybrid.csv](http://down.kew.ac/03_benchmark_data_scaling_hybrid.csv) ·
报告截图 [img_report.png](http://down.kew.ac/img_report.png)

---

## D2 · PCGUARD 插桩证据("数 BB 还是数边"定论)

**实拍图** → [img_d2_pcguard.png](http://down.kew.ac/img_d2_pcguard.png)

小程序 `bb_demo.c`(4 个 if):

1. **规范 PCGUARD**:`clang -fsanitize-coverage=trace-pc-guard -c` 后 `objdump -dr` →
   **`main` 里 10 个 `__sanitizer_cov_trace_pc_guard` 调用 = 10 个基本块**(每 BB 开头埋 1 个 guard)。
2. **AFL++ afl-clang-fast**:同为 trace-pc-guard,但把 guard 自增**内联**(更快);
   `__sancov_guards` 段 = 44 字节 = **11 个 4B guard ⇒ 每 BB 一个,无 hash 碰撞**。
3. **afl-showmap -C**:`A coverage of 9 edges were achieved out of 64 existing (14.06%) with 4 input files`。

**定论(已按 Q6 #4 反汇编核实更正)**:每个插桩位置一个**唯一 guard**;运行时 `__afl_area_ptr[*guard]++`
**直接用 guard 值索引**(反汇编:无 `prev_loc`、无 `(prev>>1)⊕cur` 异或),分母 = 本目标 guard 数(向上取整 64),
**无碰撞**。AFL++ `LLVM-PCGUARD` 拆分关键边 → 每 guard ≈ 一条 CFG 边 → **无碰撞的边覆盖**,分母是真实 guard 数
(xml=50880),**不是 65536 hash 图,也不是经典 AFL 的 `(prev>>1)⊕cur`**。〔勘误见 `Q6_补充.md` #4。〕

📎 佐证:afl-showmap 原始输出 [01_afl-showmap-C.txt](http://down.kew.ac/01_afl-showmap-C.txt)（截图 [img_showmap.png](http://down.kew.ac/img_showmap.png)) ·
三种二进制变体怎么编译的 [04_binary_variants_instrumentation.txt](http://down.kew.ac/04_binary_variants_instrumentation.txt)

---

## D3 · 覆盖率计算代码(评委要看代码)

`benchmark/run_benchmark.py:613–641`,`measure_coverage_afl()` 解析 afl-showmap 输出:

```python
# afl-showmap 输出到 stderr;解析 "A coverage of N edges were achieved out of M existing (X%)"
m = re.search(
    r"coverage of (\d+) edges were achieved out of (\d+) existing \(([0-9.]+)%\)",
    stderr)
if m:
    edges_found = int(m.group(1))          # N = 命中的边数
    edges_total = int(m.group(2))          # M = 该目标 guard 数(向上取整 64)
    edge_cov    = float(m.group(3))        # X% = afl-showmap 直接给的百分比
    measure_ok  = True
else:
    # 备用:从 "Captured N tuples (map size M)" 解析
    m2 = re.search(r"Captured (\d+) tuples \(map size (\d+)", stderr)
    if m2:
        edges_found = int(m2.group(1))
        edges_total = int(m2.group(2))
        edge_cov    = edges_found / edges_total * 100.0   # = N / M × 100
        measure_ok  = True
if not measure_ok:
    # 既无 coverage 行也无 Captured 行 → showmap 未正常完成(握手失败/启动崩溃/map 不匹配)
    # 关键:此时【不】把 0.0 当真实数据,而是告警 + 让调用方据 measure_ok 丢弃该点,
    #       避免污染均值/最佳配置选择("真 0 覆盖"与"测量失败"要区分)。
    print(f"[warn] afl-showmap 未产出覆盖率 ...", file=sys.stderr)
```

**要点**:①边覆盖率 = afl-showmap 直接给的 `X%`(命中边数 N / 目标 guard 数 M);
②有 **"测量失败 vs 真 0 覆盖" 区分**(`measure_ok`),失败点被丢弃而非当 0——保证均值/选优不被污染。

---

## D4 · freetype2 多轮 —— ⚠️ 重要:「腰斩」不成立,建议改 deck

freetype2-freetype2_fuzzer,120s,np=8 vs np=32,hybrid/mpi 各 3 轮:

| 模式 | np | r1 | r2 | r3 | 均值 |
|---|---|---|---|---|---|
| **hybrid** | 8 | 11.98% | 13.19% | 11.31% | **12.16%** |
| **hybrid** | 32 | 12.36% | 13.13% | 13.33% | **12.94%** |
| mpi | 8 | 2.26% | 2.26% | 2.26% | 2.26%(完全稳定) |
| mpi | 32 | 2.26% | 2.26% | 2.26% | 2.26%(完全稳定) |

- 原 deck 记 **hybrid np=8=11.24%、np=32=5.59%**,据此推断"np=32 上 30 个无效 SymCC worker 争 CPU → 覆盖腰斩"。
- **3 轮复现:np=32 均值 12.94% ≥ np=8 均值 12.16%,两者基本持平(np=32 甚至略高);
  np=32 三轮最低 12.36%,离 5.59% 差得很远。** → **原 5.59% 是单轮离群值,不是稳定机制。**
- freetype2 hybrid 本身有方差(±1pp),但**没有** np8→np32 的系统性下降。

**改 deck 建议(二选一,推荐前者):**
1. **删掉"np=32 拥塞腰斩"论断**,改成:*"freetype2 hybrid 在 np8/32 无显著差异(3 轮均值 12.2% vs 12.9%,
   方差 ±1pp),此前单轮 5.59% 为离群观测,已被多轮否定。"*
2. 若要保留"过并行有害",**换用 D1 的 gfts-xml**(np=64 > 128 > 190,多点、单调、可复现),别再用 freetype2 单轮数。

📎 详版:[12_D4_freetype2_multiround.md](http://down.kew.ac/12_D4_freetype2_multiround.md)

---

## D5 · 三个补充基线

### D5② · 单个 SymCC 进程吞吐(无 master/worker 干净基线)

直接跑 SymCC 二进制、逐种子喂入、`SYMCC_OUTPUT_DIR` 收集本次 concolic 生成、计时(无 MPI/去重/协调):

| 合计 | 4,729 outputs / 26.5s / 12 execs |
|---|---|
| **单进程原始生成率** | **≈ 178 tc/s** |
| 每次 concolic | ~350–400 用例(中位数) |
| **强烈右偏** | `seed_04_dtd` 一个吃 **22.3s / 941 输出**,多数种子 <0.5s |

对照 MPI np=2(1 master+1 worker)= 128 tc/s → 差值即**协调/去重开销**;且这 178 tc/s 里 **~80% 是冗余**
(见 #10,[07_redundancy_and_constraints.md](http://down.kew.ac/07_redundancy_and_constraints.md))——
**"纯 concolic 生成快、有效贡献低,须靠 hybrid"** 的根据。
📎 逐种子原始数据:[13_D5_single_process.dat](http://down.kew.ac/13_D5_single_process.dat)

### D5③ · worker 六阶段耗时 np=8 vs np=32(非自适应 hybrid,lava-base64,120s)

**np=8 实测 3 个 worker、np=32 实测 12 个 worker(各处理 1 个 item)。占 worker 总时间比例:**

| 阶段 | np=8 | np=32 | 变化 |
|---|---:|---:|---|
| **exec**(Z3 求解+生成) | **59.3%** | **46.3%** | ↓ |
| **showmap_dedup**(逐输出 afl-showmap 去重) | **40.4%** | **53.2%** | ↑ |
| wait + bmsync + import + send(协调/传输) | 0.3% | 0.5% | ≈0 |

**三个结论:**
1. **MPI 协调开销 ≈ 0.3–0.5%,可忽略——master 不是瓶颈**,worker 时间几乎全在真实工作(exec+showmap)。
2. **np 越大,showmap 去重越吃时间(exec 占比反降):59/40 → 46/53,showmap 反超 exec。**
   机制:showmap 对每个输出 fork 一个短进程,np=32 下 CPU 争用把大量短进程拖得比单个长 Z3 进程更狠。
   → **真正卡吞吐的是"去重后处理",不是 Z3 求解本身**(慢目标 05b 里 showmap 更是占 99.7%)。
3. **负载极不均、随 np 急剧恶化(机理根因):**
   - np=8:3 worker = 6.4 / 14.2 / **39.7**s → 最忙/最闲 **≈6×**;
   - np=32:12 worker 从 **0.27s 到 36.9s** → **≈137×**;其中 **4 个(⅓)≤1s 就干完空转**。
   → **加更多 worker,多数只领到琐碎 item 秒退空转,少数重 item worker 还被 showmap 争用拖慢**;
     这正是自适应模式给 SymCC worker 封顶(~12)的依据。

📎 数据:[05c_phase_timing_np8.csv](http://down.kew.ac/05c_phase_timing_np8.csv) ·
[05c_phase_timing_np32.csv](http://down.kew.ac/05c_phase_timing_np32.csv) ·
固定-np 版 [05a lava-快](http://down.kew.ac/05a_phase_timing_lava_fast.csv) /
[05b sqlite-慢(showmap 99.7%)](http://down.kew.ac/05b_phase_timing_sqlite_slow.csv)

### D5① · 长时对比(1h vs 300s)—— 未做,可按需补
1h 长跑成本高,且"短时窗覆盖"结论已由 D1(np 扫描)与 D4(多轮方差)覆盖。如需"覆盖-时间曲线"
(证 300s 是否饱和),可后台补一组 gfts-xml 的 {60,120,300,900,3600}s 曲线——需要就说一声。

---

## 六、其它补充材料(非 D1–D5,本轮之前已交付)

答辩若被追问以下点,对应材料都在下载站;每条给了直链。

| 主题 | 结论一句话 | 材料 |
|---|---|---|
| **插桩/覆盖/计时 三大核实** | 插桩真实、coverage-map 与 AFL 对齐、worker 计时可信的总结论 | [00_核实结论_verification.md](http://down.kew.ac/00_核实结论_verification.md) |
| **测试过程截图**(老师明确要) | 真实 fuzzing 运行/测试过程的终端截图 | [img_process.png](http://down.kew.ac/img_process.png) · [img_showmap.png](http://down.kew.ac/img_showmap.png) · [img_fuzzer_stats.png](http://down.kew.ac/img_fuzzer_stats.png) · [img_report.png](http://down.kew.ac/img_report.png) |
| **AFL 真在跑的证据** | pcre2 的 `fuzzer_stats`(execs/覆盖等真实计数) | [02_fuzzer_stats_pcre2.txt](http://down.kew.ac/02_fuzzer_stats_pcre2.txt) |
| **三种二进制变体怎么编译**(Q3) | `-afl`=PCGUARD / `-cov`=gcov / SymCC 各自的编译方式 | [04_binary_variants_instrumentation.txt](http://down.kew.ac/04_binary_variants_instrumentation.txt) |
| **完整基准报告** | scaling+hybrid 全量 + public v4 | [03 报告](http://down.kew.ac/03_benchmark_report_scaling_hybrid.txt)/[CSV](http://down.kew.ac/03_benchmark_data_scaling_hybrid.csv) · [03b 报告](http://down.kew.ac/03b_benchmark_report_public_v4.txt)/[CSV](http://down.kew.ac/03b_benchmark_data_public_v4.csv) |
| **#10 重复求解占比拆分** | 冗余 worker-内 ≈¾、worker-间(新鲜度间隙)≈¼;+关键难约束就"几十条"量级;ustar 是内联比较非 laf | [07_redundancy_and_constraints.md](http://down.kew.ac/07_redundancy_and_constraints.md) · 数据 [06_redundancy_split.csv](http://down.kew.ac/06_redundancy_split.csv) |
| **SymCC 插桩机制实证(IR+gdb)** | 编译期 IR 旁挂 `_sym_*`、运行时 gdb 断在 `_sym_push_path_constraint`;"+50%"= SQLite 单种子 `SYMCC_DICT` | [08_IR_gdb_and_dict50.md](http://down.kew.ac/08_IR_gdb_and_dict50.md) · [img_ir.png](http://down.kew.ac/img_ir.png) · [img_gdb.png](http://down.kew.ac/img_gdb.png) · A/B 原始 [09_dict_ab_sqlite.txt](http://down.kew.ac/09_dict_ab_sqlite.txt) |
| **CONFETTI 测试集设置** | ICSE'22 的 5 个 Java 程序/24h×20;**只借 global hinting 思想,不可与我们边覆盖并列比** | [10_CONFETTI_testset.md](http://down.kew.ac/10_CONFETTI_testset.md) |

---

## 〔附一〕全部文件下载清单

站点根 **http://down.kew.ac/**（目录浏览已开,可直接进站点点选)。

**📘 汇总与 D1–D5 正文**
| 文件 | 说明 |
|---|---|
| [D1-D5_汇总.md](http://down.kew.ac/D1-D5_汇总.md) | 本文 |
| [11_D1_D2_D3.md](http://down.kew.ac/11_D1_D2_D3.md) | D1 np=64 / D2 PCGUARD / D3 覆盖率代码 |
| [12_D4_freetype2_multiround.md](http://down.kew.ac/12_D4_freetype2_multiround.md) | D4 freetype2 多轮(腰斩证伪) |
| [13_D5_baselines.md](http://down.kew.ac/13_D5_baselines.md) | D5 ②单进程/③相位计时/①长跑说明 |

**🖼 图片**
| 文件 | 说明 |
|---|---|
| [img_d2_pcguard.png](http://down.kew.ac/img_d2_pcguard.png) | D2:objdump 显示 10 个 pc_guard 调用 = 10 BB |
| [img_showmap.png](http://down.kew.ac/img_showmap.png) | afl-showmap -C 覆盖率测量截图 |
| [img_fuzzer_stats.png](http://down.kew.ac/img_fuzzer_stats.png) | AFL fuzzer_stats 截图 |
| [img_report.png](http://down.kew.ac/img_report.png) | benchmark 报告截图 |
| [img_process.png](http://down.kew.ac/img_process.png) | 测试过程截图 |
| [img_ir.png](http://down.kew.ac/img_ir.png) | SymCC 编译期 LLVM IR 插桩截图 |
| [img_gdb.png](http://down.kew.ac/img_gdb.png) | 运行时 gdb concolic 断点截图 |

**📊 CSV / 数据**
| 文件 | 说明 |
|---|---|
| [03_benchmark_data_scaling_hybrid.csv](http://down.kew.ac/03_benchmark_data_scaling_hybrid.csv) | D1 np 扫描原始数据 |
| [03b_benchmark_data_public_v4.csv](http://down.kew.ac/03b_benchmark_data_public_v4.csv) | public v4 基准数据 |
| [05a_phase_timing_lava_fast.csv](http://down.kew.ac/05a_phase_timing_lava_fast.csv) | 相位计时(lava,快目标) |
| [05b_phase_timing_sqlite_slow.csv](http://down.kew.ac/05b_phase_timing_sqlite_slow.csv) | 相位计时(sqlite,慢目标) |
| [05c_phase_timing_np8.csv](http://down.kew.ac/05c_phase_timing_np8.csv) | D5③ np=8 相位计时 |
| [05c_phase_timing_np32.csv](http://down.kew.ac/05c_phase_timing_np32.csv) | D5③ np=32 相位计时 |
| [06_redundancy_split.csv](http://down.kew.ac/06_redundancy_split.csv) | #10 冗余占比拆分 |
| [13_D5_single_process.dat](http://down.kew.ac/13_D5_single_process.dat) | D5② 单进程逐种子数据 |

**📄 文本证据 / 说明**
| 文件 | 说明 |
|---|---|
| [00_核实结论_verification.md](http://down.kew.ac/00_核实结论_verification.md) | 插桩/覆盖/计时三大核实总结论 |
| [01_afl-showmap-C.txt](http://down.kew.ac/01_afl-showmap-C.txt) | afl-showmap -C 原始输出 |
| [02_fuzzer_stats_pcre2.txt](http://down.kew.ac/02_fuzzer_stats_pcre2.txt) | pcre2 AFL fuzzer_stats |
| [03_benchmark_report_scaling_hybrid.txt](http://down.kew.ac/03_benchmark_report_scaling_hybrid.txt) | scaling+hybrid 完整报告 |
| [03b_benchmark_report_public_v4.txt](http://down.kew.ac/03b_benchmark_report_public_v4.txt) | public v4 完整报告 |
| [04_binary_variants_instrumentation.txt](http://down.kew.ac/04_binary_variants_instrumentation.txt) | 三种二进制变体编译方式 |
| [07_redundancy_and_constraints.md](http://down.kew.ac/07_redundancy_and_constraints.md) | #10 冗余拆分 + 约束量级 + ustar 形态 |
| [08_IR_gdb_and_dict50.md](http://down.kew.ac/08_IR_gdb_and_dict50.md) | IR/gdb 现场 + "+50%"目标 |
| [09_dict_ab_sqlite.txt](http://down.kew.ac/09_dict_ab_sqlite.txt) | SQLite 字典 A/B 原始输出 |
| [10_CONFETTI_testset.md](http://down.kew.ac/10_CONFETTI_testset.md) | CONFETTI 测试集设置 |

**📦 打包**
| 文件 | 说明 |
|---|---|
| [symcc-ppt-material.tar.gz](http://down.kew.ac/symcc-ppt-material.tar.gz) | 本文全部 PPT 材料(~1.9 MB) |
| [symcc-offline-package.tar.gz](http://down.kew.ac/symcc-offline-package.tar.gz) | 项目离线/内网安装包(~350 MB) |

---

## 〔附二〕四路互证的"过并行浪费"链条(答辩串词)

> "有效重活就那么几份——**D5②** 单进程 22s 全耗在一个 DTD 难种子(其余种子 <0.5s);
> **D5③** np=32 有 ⅓ 的 worker 秒退空转,且 showmap 争用反超 Z3 求解;
> **D1** 吞吐与覆盖峰值都在 np≈64,过后回落;**D4** freetype2 np8≈np32,加 worker 不涨。
> 所以并行度超过'几十个 worker'纯属浪费——这就是我们做**自适应封顶 SymCC worker + 拉 AFL 做 hybrid**
> 的根据,也是 master/通信从来不是瓶颈(D5③ 协调开销 <0.5%)的佐证。"
