Skip to the content.

sanitizer 实验代码

注意: nix 环境的 clang 缺 libclang_rt.tsan.a, 链接 TSan 会失败, 所以这里统一用 gcc。

结论 1: ASan 和 TSan 不能同时打开

make asan-tsan, 两个编译器都在编译期直接报错:

== gcc ==
cc1: error: ‘-fsanitize=thread’ is incompatible with ‘-fsanitize=address’
== clang ==
clang: error: invalid argument '-fsanitize=address' not allowed with '-fsanitize=thread'

原因: 两者的 shadow memory 布局互相冲突 (ASan 用地址高位缩放映射影子内存, TSan 需要保留若干段地址区间给影子状态), 内存模型不兼容, 只能分别编译两份二进制各跑各的。 同理 -fsanitize=memory 也和它们互斥, 只有 -fsanitize=undefined 可以和 ASan 叠加。

结论 2: TSan 能测到什么

make tsan (代码 race-counter.c, 从 ../code/tools/drd.c 拷贝):

WARNING: ThreadSanitizer: data race
  Write of size 4 ... by thread T2:
    #0 worker race-counter.c:29
  Previous write of size 4 ... by thread T1:
    #0 worker race-counter.c:29
  Location is global 'shared_counter' of size 4
SUMMARY: ThreadSanitizer: data race race-counter.c:29 in worker

结论 3: TSan 测不到什么

make missed:

此外 TSan 报告 race 时进程退出码非 0 (默认 66), Makefile 里用 - 前缀忽略。

结论 4: TSan 的死锁检测

make deadlock。两个前提:

能检测: 互斥锁获取顺序不一致造成的潜在死锁 (ABBA)。deadlock-abba.c 让两个线程按相反顺序拿锁, 但时间上错开、程序正常结束, TSan 依然报告:

WARNING: ThreadSanitizer: lock-order-inversion (potential deadlock)
  Cycle in lock order graph: M0 => M1 => M0

原理: TSan 在”持有一把锁时又成功拿到另一把锁”时向锁顺序图加边, 发现环就报告 —— 所以它报告的是运行中观察到的危险顺序, 不要求死锁真发生。

不能检测 (make deadlock 里后三个用例都是挂死且无报告, 退出码 124 是 timeout 杀掉的):

结论 5: 像 KASAN 一样, 自己实现 ASan 的 callback

make myasan (代码 myasan.c + myasan-demo.c)。

-fsanitize=kernel-address 下编译器只负责插桩, 不链接任何 runtime —— 这正是内核用 ASan 的方式: shadow memory、poison 编码、越界判定全由内核自己的 mm/kasan/ 提供。这个 demo 在用户态复刻了同样的结构:

一次运行抓出三类错误 (报告完继续跑, 对应 *_noabort 语义):

==myasan== ERROR: WRITE of size 4 ... shadow byte: 0xfe (heap-buffer-overflow)
==myasan== ERROR: WRITE of size 1 ... shadow byte: 0xfd (use-after-free)
==myasan== ERROR: WRITE of size 4 ... shadow byte: 0xfa (global redzone)

而 myasan-demo.c 里 p[12] = 'a' (13 字节对象的最后一个合法字节) 安静通过, 说明 partial granule (1~7) 的判定没有误报。

注意点: runtime (myasan.c) 必须不带 -fsanitize 单独编译, 否则自己插桩 自己, 无限递归; KASAN 内核也是靠 KASAN_SANITIZE_xxx.o := n 把自己摘出来的。

本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。