课程作业
英文 paper presentation session (10.23, 下次课)
静态分析
动态分析
这是对 “计算机” 的一个非常 fundamental 的理解。
以多线程程序 (多处理器系统) 为例
动态程序分析:通过执行程序、观测其行为从而得到程序各方面信息 (bugs、性能、需求实现情况等) 的程序分析技术。
简单说,就是检查状态机产生的状态序列
GDB, the GNU Project debugger, allows you to see what is going on “inside” another program while it executes -- or what another program was doing at the moment it crashed.
命令行交互
r
, c
, f
, s
, si
,...p
, x
, i
, bt
, ...b
, hb
, wa
, ...set
, ...rc
, rn
, rsi
, ...使用 GDB
最重要的功能是
实现指令级的断点:Program Instrumentation (插桩)
debug_trap()
,跳转后把原指令恢复0xcc
,仅一个字节,专门用于调试0xcd $trap
int main() {
asm volatile ("int $3");
}
$ ./a.out
Trace/breakpoint trap (core dumped)
ptrace
系统调用可以将被追踪进程的 trap 通知追踪进程 (gdb)
stepi
),将会直接 “越过” int $3
任何动态分析都是 “简化的” 调试器。
调试器实现了
info inferiors
; thread tid
set var = value
当你试图理解动态分析技术时
调试器是好,但性能太差、记录太多
核心问题:如何针对
特定软件工程问题 实现轻量级的记录 和高效的分析算法 ?
问题空间
设计空间
我们并不需要指令级的完整 log
profile 问题: 统计同一类代码的执行信息
trace 问题: 打印事件日志
我的程序的性能尚不能满足要求
Invariant Mining
在各种场合都很好用
我们已知一些 bug patterns,在运行时检测就好了
Mini UBSan
foo(i++, j++) + (bar() / 2)
例子:AST 改写
(E1) + (E2)
替换成 CallExpr ubsan::add_chk(E1, E2)
在动态分析时,我们不仅可以
甚至在程序出现问题以后,还可以恢复
本质上,调试器都可以搞定
实现方法
动态分析 (tracer/profiler) 虽然不改变程序的语义,但实际改变了程序的运行时间
printf
就没有了(这两次课信息量很大,但不必惊慌)