16. Static Analysis
Learning Goals
- ํ ๋ฌธ์ฅ์ผ๋ก ์ ์ ๋ถ์ ์ ์ ๋ฐ ์ ์ ๋ถ์์ด ๋ชฉํ๋ก ํ๋ Bug ์ ํ ์ค๋ช
- Syntactic ๋๋ Structural ์ ์ ๋ถ์์ ์์ ์ ์
- ๊ฐ๋จํ ์์ ์ ๋ํด ๊ธฐ๋ณธ์ ์ธ Control Flow Graph๋ฅผ ์์์ ์ผ๋ก ์์ฑ
- Control-flow ๋ถ์๊ณผ Dataflow ๋ถ์์ ๊ตฌ๋ณ, ์ฝ๋ ์์ ์์์ ์ ์ ๋ฐ ๋จ๊ณ๋ณ ์ํ
- Dataflow Analysis ๊ตฌํ
- ์ ์ ๋ถ์์ด ์ Sound, Complete, Terminatingํ ์ ์๋์ง์ ๋ํ ๊ณ ์ฐจ์์ ์ค๋ช ๋ฐ ๋ถ์ ์ค๊ณ์ trade-off ํ๊ฐ
- ์ ์ ๋ถ์์ ์ํํ๋ ๋๊ตฌ์ ํน์ฑ ํ์ ๋ฐ ์ ํ
goto fail;
static OSStatus
SSLVerifySignedServerKeyExchange(SSLContext *ctx, bool isRsa, SSLBuffer signedParams, uint8_t *signature, UInt16 signatureLen) {
OSStatus err;
โฆ
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
goto fail;
โฆ
fail
SSLFreeBuffer(&signedHashes);
SSLFreeBuffer(&hashCtx);
return err;
}
A Bug in the Old Linux Kernel
/* from Linux 2.3.99 drivers/block/raid5.c */
static struct buffer_head *
get_free_buffer(struct stripe_head * sh, int b_size) {
struct buffer_head *bh;
unsigned long flags;
save_flags(flags);
cli(); // disables interrupts
if ((bh = sh->buffer_pool) == NULL)
return NULL;
sh->buffer_pool = bh -> b_next;
bh->b_size = b_size;
restore_flags(flags); // re-enables interrupts
return bh;
}
Could You Have Found Them?
- ์ด๋ฌํ Bug๋ค์ด ์ผ๋ง๋ ์์ฃผ ๋ฐ์ํ ๊ฒ์ธ๊ฐ
- Driver Bug
- Interrupt๊ฐ ๋นํ์ฑํ๋ ์ํ์์ Driver๋ก๋ถํฐ ๋ฐํ๋ ๊ฒฝ์ฐ ๋ฐ์ํ๋ ์ผ
- ๊ณ ๋ ค์ฌํญ: ๋จ์ผ ํจ์
- 2000์ค(LOC) ํ์ผ ๋ด์ ๊ฒฝ์ฐ
- 60,000์ค(LOC) ๋ชจ๋ ๋ด์ ๊ฒฝ์ฐ
- ๋ฆฌ๋ ์ค ์ปค๋(LINUX KERNEL) ๋ด๋ถ์ ๊ฒฝ์ฐ
- ๊ตํ: ์ผ๋ถ ๊ฒฐํจ์ ํ ์คํธ๋ ๊ฒ์ฌ๋ฅผ ํตํด ๋ฐ๊ฒฌํ๊ธฐ ๋งค์ฐ ์ด๋ ค์
https://www.cnet.com/news/privacy/klocwork-our-source-code-analyzer-caught-apples-gotofail-bug/
Defects of Interest
- ํ ์คํธ์ ๋์กฐ์ ์ผ๋ก ์ผ๋ฐ์ ์ด์ง ์๊ฑฐ๋ ๊ฐ์ ํ๊ธฐ ์ด๋ ค์ด ์คํ ๊ฒฝ๋ก์์ ์กด์ฌ
- ์ด๋ฌํ ๊ฒฐํจ์ ์ฐพ๊ธฐ ์ํด ๋ชจ๋ ๊ฒฝ๋ก๋ฅผ ๊ตฌ์ฒด์ ์ผ๋ก ์คํ(๋๋ ํด์/๋ถ์)ํ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅ
- ์ค์ ๋ก ์ํ๋ ๊ฒ์ ํ๋ก๊ทธ๋จ์ ์ ์ฒด ๊ฐ๋ฅํ ์ํ ๊ณต๊ฐ(State Space)์ ํ์ธํ์ฌ ํน์ ์์ฑ์ ๊ฒ์ฌํ๋ ๊ฒ
Defects Static Analysis Can Catch
- ๋จ์ํ๊ณ ๊ธฐ๊ณ์ ์ธ ์ค๊ณ ๊ท์น์ ์ผ๊ด๋๊ฒ ๋ฐ๋ฅด์ง ์์์ผ๋ก ์ธํด ๋ฐ์ํ๋ ๊ฒฐํจ.
- Security: Buffer ์ค๋ฒ๋ฐ, ๋ถ์ ์ ํ๊ฒ ๊ฒ์ฆ๋ ์ ๋ ฅ
- Memory safety: Null ์ญ์ฐธ์กฐ, ์ด๊ธฐํ๋์ง ์์ ๋ฐ์ดํฐ
- Resource leaks: Memory, OS ๋ฆฌ์์ค
- API Protocols: Device drivers, ์ค์๊ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ, GUI ํ๋ ์์ํฌ
- Exceptions: ์ฐ์ /๋ผ์ด๋ธ๋ฌ๋ฆฌ/์ฌ์ฉ์ ์ ์
- Encapsulation: ๋ด๋ถ ๋ฐ์ดํฐ ์ ๊ทผ, ๋น๊ณต๊ฐ ํจ์ ํธ์ถ
- Data races: ๋๊ธฐํ ์์ด ๋ ์ค๋ ๋๊ฐ ๋์ผํ ๋ฐ์ดํฐ์ ์ ๊ทผ
- Key: ๋จ์ํ๊ณ ๊ธฐ๊ณ์ ์ธ ์ค๊ณ ๊ท์น ์ค์ ์ฌ๋ถ ํ์ธ
Defining Static Analysis
What is Static Analysis?
- ํ๋ก๊ทธ๋จ ์ํ ๊ณต๊ฐ์ ์ถ์ํ์ ๋ํ ์ฒด๊ณ์ ์ธ ๊ฒ์ฌ
- ์ฝ๋๋ฅผ ์คํํ์ง ์์(์ฝ๋ ๋ฆฌ๋ทฐ์ ์ ์ฌ)
- Abstraction: ๋ถ์ํ๊ธฐ ๋ ๊ฐ๋จํ ํ๋ก๊ทธ๋จ์ ํํ ์์ฑ
- ํ์ํ ์ํ ์๊ฐ ์ ์ด์ง, ์ด๋ ค์ด ๋ฌธ์ ๋ฅผ ๋ค๋ฃจ๊ธฐ ์ฝ๊ฒ ๋ง๋ฌ
- ์ ์ฒด ์ํ ๊ณต๊ฐ์ ๋ํด ํน์ ์์ฑ์ด ์ ์ง๋๋์ง ํ์ธ
- Liveness: "์ข์ ์ผ์ด ๊ฒฐ๊ตญ ๋ฐ์ํจ"
- Safety: "๋์ ์ผ์ด ์ ๋ ๋ฐ์ํ์ง ์์"
The Bad News: Riceโs Theorem
"ํ๋ง ๋จธ์ ์ ์ํด ์ธ์๋๋ ์ธ์ด์ ๋ํ ๋น์๋ช ํ ์์ฑ์ ๊ฒฐ์ ๋ถ๊ฐ๋ฅํ๋ค" (Henry Gordon Rice, 1953)
- ๋ชจ๋ ์ ์ ๋ถ์์ ํ์ฐ์ ์ผ๋ก Incompleteํ๊ฑฐ๋ Unsoundํ๊ฑฐ๋ Undecidableํจ (ํน์ ์ด๊ฒ๋ค์ ๋ณตํฉ)
Soundness and Completeness
| ์๋ฌ ์กด์ฌ | ์๋ฌ ์กด์ฌํ์ง ์์ | |
|---|---|---|
| ์๋ฌ ๋ณด๊ณ ๋จ | True positive (correct analysis result) | False positive |
| ์๋ฌ ๋ณด๊ณ ๋์ง ์์ | False negative | True negative (correct analysis result) |
- Sound Analysis
- ๋ชจ๋ ๊ฒฐํจ์ ๋ณด๊ณ
- False negative๊ฐ ์์
- ์ผ๋ฐ์ ์ผ๋ก ๊ณผ๋ ๊ทผ์ฌ(Overapproximated)
- Complete Analysis
- ๋ณด๊ณ ๋ ๋ชจ๋ ๊ฒฐํจ์ด ์ค์ ๊ฒฐํจ์
- False positive ์์
- ์ผ๋ฐ์ ์ผ๋ก ๊ณผ์ ๊ทผ์ฌ(Underapproximated)

Simple Syntactic and Structural Analyses
Syntactic Analysis
- ํน์ ํจํด์ ๋ชจ๋ ๋ฐ์ ์ฐพ๊ธฐ
public foo() {
โฆ
logger.debug(โWe have โ + conn + โconnections.โ);
}
public foo() {
โฆ
if (logger.inDebug()) {
logger.debug(โWe have โ + conn + โconnections.โ);
}
}
- Grep ๋ช
๋ น์ด ์์:
grep "if \(logger\.Debug\(" . -r
Type Analysis
public void foo() {
int a = computeSomething();
if (a == "5")
doMoreStuff();
}
Abstraction: Abstract Syntax Tree
- ์์ค ์ฝ๋์ ๊ตฌ๋ฌธ ๊ตฌ์กฐ๋ฅผ ํธ๋ฆฌ๋ก ํํ
- Parser๊ฐ ๊ตฌ์ฒด์ ์ธ ๊ตฌ๋ฌธ์ ์ถ์ ๊ตฌ๋ฌธ์ผ๋ก ๋ณํํ๊ณ ๊ฒฐ๊ณผ์ ์ธ ๋ชจํธ์ฑ ์ฒ๋ฆฌ
- ์๋ฏธ์ ์ผ๋ก ๊ด๋ จ๋ ์ ๋ณด๋ง ๊ธฐ๋ก
- Abstract: ๋ชจ๋ ์ธ๋ถ ์ฌํญ(๊ดํธ ๋ฑ)์ ํํํ์ง ์์ผ๋ฉฐ, ์ด๋ฌํ ๊ฒ๋ค์ ๊ตฌ์กฐ์์ ์ ์ถ ๊ฐ๋ฅ
- ์ปดํ์ผ๋ฌ๋ฅผ ํตํด ์์ฑ ๊ฐ๋ฅ
- ์์:
Type Checking
- Class X, Logger ๋ฑ์ ๊ตฌ์กฐ ๋ฐ ๋ฉ์๋ ํธ์ถ ๊ด๊ณ๋ฅผ ๋ณด์ฌ์ฃผ๋ ๋ค์ด์ด๊ทธ๋จ ๋ฐ ์ฝ๋
- Class X
- Field: logger
- Method: foo
- If stmt
- Method Invoc.: logger inDebug
- Block
- Method Invoc.: logger debug
- Param.: String ์ฐ๊ฒฐ
- If stmt
- Logger ํด๋์ค ๊ตฌ์กฐ
boolean inDebug() {โฆ}void debug(String msg) {โฆ}
Abstract Syntax Tree Walker
Logger.inDebug์ฒดํฌ ์ธ๋ถ์์ ๋๋ฒ๊น ๋ก๊ทธ๋ฅผ ํ์ํ์ง ์๋์ง ํ์ธ- Abstraction
Logger.debug()ํธ์ถ๋ง ํ์ธ- ๋ชจ๋
if (Logger.inDebug())๋ก ๊ฐ์ธ์ ธ ์๋์ง ํ์ธ
- Systematic: ๋ชจ๋ ์ฝ๋ ๊ฒ์ฌ
- Abstract Syntax Tree (AST) Walker๋ก ์๋ ค์ง
- ์ฝ๋๋ฅผ ๊ตฌ์กฐํ๋ ํธ๋ฆฌ๋ก ์ทจ๊ธ
- Control Flow, ๋ณ์ ๊ฐ, Heap ๋ฌด์
- Code style checker๊ฐ ์ด์ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์๋
Structural Analysis

Bug Finding
Structural Analysis to Detect goto fail;?
goto fail;์ค๋ณต ์ฝ๋๊ฐ ํฌํจ๋SSLVerifySignedServerKeyExchangeํจ์ ์ฝ๋ ์ฌ์ ์
Summary of Syntactic/Structural Analyses
- Token ์คํธ๋ฆผ ๋๋ ์ฝ๋ ๊ตฌ์กฐ(AST) ๋ถ์
- ํจํด์ ์ฐพ๋ ๋ฐ ์ ์ฉ
- ์คํ ๊ฒฝ๋ก์ ๋ฌด๊ดํ ๊ตญ์์ /๊ตฌ์กฐ์ ์์ฑ
Tools
- Checkstyle
- ๋ค์์ Linter (C, JS, Python ๋ฑ)
- Find bugs (์ผ๋ถ ๋ถ์)
Tools: Compilers
Type checking, ์ ์ ํ ์ด๊ธฐํ API, ์ฌ๋ฐ๋ฅธ API ์ฌ์ฉ
ํ๋ก๊ทธ๋จ
int add(int x, int y) { return x + y; } void main() { add(2); }์ปดํ์ผ๋ฌ ์ถ๋ ฅ
$> error: too few arguments to function 'int add(int, int)'๋์ ๊ฒฝ๊ณ ๋ ๋ฒจ๋ก ์ปดํ์ผ
- ์:
$ gcc -Wall
- ์:
Control-Flow Analysis
Control/Dataflow Analysis
- Control Flow Graph๋ฅผ ํตํ ๊ฒฝ๋ก๋ก ๋ชจ๋ ๊ฐ๋ฅํ ์คํ์ ๋ํด ์ถ๋ก
- ๋ชจ๋ ํ๋ก๊ทธ๋จ ์ง์ ์์ ๊ด์ฌ ์๋ ์์ฑ๊ณผ ๊ด๋ จ๋ ์ ๋ณด ์ถ์
- Exception ์ฒ๋ฆฌ, ํจ์ ํธ์ถ ๋ฑ ํฌํจ.
- ๊ด์ฌ ์๋ ์์ฑ๊ณผ ๊ด๋ จ๋ ๊ฐ/์ํ๋ง ํฌ์ฐฉํ๋ Abstract domain ์ ์
- ๊ทธ๋ํ๋ฅผ ํตํ ๋ชจ๋ ๊ฐ๋ฅํ ์คํ(๊ฒฝ๋ก)์ ๋ํด ๊ฐ๋ฅํ ๋ชจ๋ ๊ตฌ์ฒด์ ์ธ ๊ฐ ๋์ Abstract state ์ถ์
Control Flow Graphs
- ํ๋ก๊ทธ๋จ์ ํตํ ์ ์ด ํ๋ฆ์ ํธ๋ฆฌ/๊ทธ๋ํ ๊ธฐ๋ฐ ํํ
- ๋ชจ๋ ๊ฐ๋ฅํ ์คํ ๊ฒฝ๋ก ํฌ์ฐฉ
- ๊ฐ ๋ ธ๋๋ Basic block: ๋ด๋ถ๋ก ๋ค์ด์ค๊ฑฐ๋ ๋๊ฐ๋ ์ ํ ์์
- ์ฃ์ง(Edges)๋ ๋ ธ๋ ๊ฐ์ ์ ์ด ํ๋ฆ ์ต์ ํํ
- Intra-procedural: ๋จ์ผ ํจ์ ๋ด (cf. Inter-procedural)
a = 5 + (2 + 3)
if (b > 10)
a = 0;
return a;

- ๋ ธ๋ 0~6์ผ๋ก ๊ตฌ์ฑ๋ ๊ทธ๋ํ ๊ตฌ์กฐ
Control Flow Graphs (CFG)
public int foo() {
doStuff();
return 3;
doMoreStuff();
return 4;
}

A Bug in the Old Linux Kernel
- ๋ฆฌ๋
์ค RAID ๋๋ผ์ด๋ฒ(
raid5.c)์get_free_bufferํจ์ ์ฝ๋ - ํด๋น ํจ์์ ๋ํ Control Flow Graph ๊ทธ๋ฆฌ๊ธฐ (๋จ์ํ ํฌํจ)
Example of a CFG
int foo()ํจ์ ์์ ์ฝ๋save_flags,cli,dont_interruptํธ์ถif (rv > 0)๋ถ๊ธฐ ๋ฐ ๋ณต๊ตฌ ๋ก์ง
- Entry๋ถํฐ Exit๊น์ง์ ํ๋ฆ๋ ํํ
- ๋์ผํ
foo()ํจ์์ ํ๋ฆ๋ ํํ ๋ฐ๋ณต

Control/Dataflow Analysis
- Control Flow Graph๋ฅผ ํตํ ๊ฒฝ๋ก๋ก ๋ชจ๋ ๊ฐ๋ฅํ ์คํ์ ๋ํด ์ถ๋ก
- ๋ชจ๋ ํ๋ก๊ทธ๋จ ์ง์ ์์ ๊ด์ฌ ์๋ ์์ฑ๊ณผ ๊ด๋ จ๋ ์ ๋ณด ์ถ์
- Exception ์ฒ๋ฆฌ, ํจ์ ํธ์ถ ๋ฑ ํฌํจ.
- ๊ด์ฌ ์๋ ์์ฑ๊ณผ ๊ด๋ จ๋ ๊ฐ/์ํ๋ง ํฌ์ฐฉํ๋ Abstract domain ์ ์
- ๊ทธ๋ํ๋ฅผ ํตํ ๋ชจ๋ ๊ฐ๋ฅํ ์คํ(๊ฒฝ๋ก)์ ๋ํด ๊ฐ๋ฅํ ๋ชจ๋ ๊ตฌ์ฒด์ ์ธ ๊ฐ ๋์ Abstract state ์ถ์
Abstract Domain: Lattices
- Lattice
- ๋ ํ๋ก๊ทธ๋จ ์์ฑ์ Domain
- ๋ ์์๋ค์ ์งํฉ(๋ฌดํํ ์ ์์)
- ๋ ์ ์ผํ ์ต๋ ์์(Top)์ ์ต์ ์์(Bottom)๋ฅผ ๋ฐ๋์ ํฌํจํด์ผ ํจ.
- ์ ์ ์์๋ค์ ๋ํ ์ดํญ ๊ด๊ณ
- ์ ํ์ ์์ฑ
- ๋ถ๋ถ ์์(Partial order): ๋ฐ์ฌ์ , ์ถ์ด์ , ๋ฐ๋์นญ์
- ๋ชจ๋ ์์ ์์ ์ ์ผํ ์ต๋ ํํ(Meet)๊ณผ ์ ์ผํ ์ต์ ์ํ(Join)์ ๊ฐ์ง
Example of a Lattice
Say What? Why We Need It?
- ๋ชจ๋ ํ๋ก๊ทธ๋จ ์ง์ ์์ ๊ด์ฌ ์์ฑ๊ณผ ๊ด๋ จ๋ ๋ชจ๋ ๊ฐ๋ฅํ ๊ฐ ์ถ์
- ๊ฐ๋ฅํ ๊ฐ(์ถ์ ์ค์ธ ์ ๋ณด)์ Domain์ ์ ์ํ๋ Lattice์ ์์๋ก ๋ชจ๋ธ๋ง
- ํ๋ก๊ทธ๋จ ์ ์ฒด์์ ์ ๋ณด๊ฐ ์ด๋ป๊ฒ ๋ณํ๋์ง ์ค๋ช
ํ๋ ์ ์ฝ ์กฐ๊ฑด์ ๊ตฌ์ถํ์ฌ ์ ๋ณด๋ฅผ ๊ณ์ฐํ๋ ๋ฐ Lattice ์ฌ์ฉ
- Transfer function: ๋ช ๋ น์ด๊ฐ ์ํ์ ๋ฏธ์น๋ ์ํฅ
- Meet/Join: Control Flow์ ์ํฅ
Abstract Domain: Interrupt Checker
maybe-enabled
/ \
enabled disabled
\ /
?
Reasoning about a CFG
- ๋ถ์์ ํ๋ก๊ทธ๋จ ์ง์ (๋ ธ๋ ์ฌ์ด์ ์ง์ )์์ ์ํ๋ฅผ ์ ๋ฐ์ดํธํจ.
- ๊ฐ ๋
ธ๋์ ๋ํด
- ์ ํ ๋ ธ๋(Predecessors)์ ์ํ๋ฅผ ๊ฒ์ฌ/๊ฒฐํฉํ์ฌ ์ง์ ์ ์ํ ๊ฒฐ์
- ์ฐ์ฐ(Transfer)์ ํจ๊ณผ์ ๊ธฐ๋ฐํ์ฌ ๋ ธ๋ ์ข ๋ฃ ์ ์ํ ํ๊ฐ
- ๊ฐ ํ๋ก๊ทธ๋จ ์ง์ ์ ์ํ๊ฐ ๋ณํ์ง ์์ ๋๊น์ง ํํ ๋ ธ๋(Successors)์ ์ ์ฒด ๊ทธ๋ํ๋ฅผ ํตํด ๋ฐ๋ณต
- Output: ๊ฐ ํ๋ก๊ทธ๋จ ์ง์ ์์์ ์ํ
An Interrupt Checker
- Abstraction
- 3๊ฐ์ง Abstract states: Enabled, Disabled, Maybe-enabled
- Interrupt๊ฐ disable๋ ์ํ๋ก ํจ์ ๋์ ๋๋ฌํ ์ ์๋์ง alarm์ ์ค.
- Transfer function
- Basic block์
cli()ํธ์ถ์ด ํฌํจ๋ ๊ฒฝ์ฐ, ๋ถ์ ์ํ๋ฅผ Enabled์์ Disabled๋ก ๋ณ๊ฒฝ - Basic block์
restore_flags()ํธ์ถ์ด ํฌํจ๋ ๊ฒฝ์ฐ, ๋ถ์ ์ํ๋ฅผ Disabled์์ Enabled๋ก ๋ณ๊ฒฝ
- Basic block์
Transfer Function
- ๊ฐ์ : ๋ธ๋ก ์ ํ๋ก๊ทธ๋จ ์ง์ ์ Interrupt enabled
โ โโโโโโโโโโโโโโโโโโโโโ โ // do_stuff โ โ restore_flags(); โ โโโโโโโโโโโโโโโโโโโโโ โ - ๋ธ๋ก ํ ํ๋ก๊ทธ๋จ ์ง์ : Interrupt disabled
Join
- ๊ฐ์ : ๋ธ๋ก ์ ํ๋ก๊ทธ๋จ ์ง์ ์ Interrupt disabled
โโโโโโโโโโโโโโ
โ if(rv > 0) โ
โโโโโโโโณโโโโโโ
โโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโ
โ โ
โผ โผ
True branch: False branch:
interrupts disabled interrupts disabled
โโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโ
โ // do_stuff โ โ Handle_error_case(); โ
โ Restore_flags(); โ โโโโโโโโโโโโณโโโโโโโโโโโโ
โโโโโโโโโโโณโโโโโโโโโโ โ
โ โ
interrupts enabled interrupts disabled
โ โ
โโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโ
โผ
โโโโโโโโโโโโโโ
โ return rv; โ
โโโโโโโโโโโโโโ
interrupts...???
Join/Branching
- ๋ค์์ ์ด์ ์ํ๋ก๋ถํฐ ์ค๋/๊ฐ๋ ์ ๋ณด๋ฅผ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ๊ฒ์ธ๊ฐ
- ๋ถ๊ธฐ(Branch)์ ๋๋ฌํ์ ๋ ์ํํ ์์
- ๊ฐ ๊ฒฝ๋ก๋ฅผ ๊ฐ๋ณ์ ์ผ๋ก ํ์
- ๊ฐ ๊ฒฝ๋ก์ ๋ํ ๊ฐ์ฅ ์ ํํ ์ ๋ณด
- ๊ทธ๋ฌ๋ ๊ฒฝ๋ก์ ์๊ฐ ๋ฌด์ํ ๋ง์ ์ ์์
- ์ํ ํญ๋ฐ(State explosion) ๋ฐ์, ๋ฃจํ๋ ๋ฌดํ์ฑ ๋ฌธ์ ์ถ๊ฐ
- Join!
- ๊ฒฝ๋ก๋ฅผ ๋ค์ ํ๋๋ก ๊ฒฐํฉ
- ๋ ์ ํํ๋ฉฐ ์ ๋ณด ์์ค ๋ฐ์ (Rice's theorem)
- ๊ทธ๋ฌ๋ ์ํ ํญ๋ฐ์ด ์์ผ๋ฉฐ ์ข ๋ฃ๋จ (Terminate)
- ๊ฐ ๊ฒฝ๋ก๋ฅผ ๊ฐ๋ณ์ ์ผ๋ก ํ์
- ์กฐ๊ฑด๋ฌธ๋ฟ๋ง ์๋๋ผ ๋ฃจํ, Switch, Exception๋ ํด๋น๋จ
Interrupt Analysis: Join Function
- Abstraction
- 3๊ฐ์ง ์ํ: Enabled, Disabled, Maybe-enabled
- Program counter
- Join: Basic block์ ์ ํ ๋
ธ๋ ์ค ์ ์ด๋ ํ๋๊ฐ Interrupt enabled์ด๊ณ ์ ์ด๋ ํ๋๊ฐ Disabled์ธ ๊ฒฝ์ฐ
- Join(Enabled, Enabled) โ Enabled
- Join(Disabled, Disabled) โ Disabled
- Join(Disabled, Enabled) โ Maybe-enabled
- Join(Maybe-enabled, *) โ Maybe-enabled
Example of the Interrupt Analysis
foo()ํจ์ ์์ ์ ๋ํ ๋ถ์ ์ถ์ - ๊ฐ ๋จ๊ณ๋ณ ์ํ ๋ณํ ( Enabled/Disabled)
- ๋ฌธ์ ๋ฐ์ ์ง์ : Maybe-enabled

Abstraction
- ๊ฐ๋จํ ์ฝ๋ ์์
cli();if (*)๋ถ๊ธฐ ๋ดrestore_flags();- ์ข ๋ฃ ์์ ์ํ ํ์ธ
Too Simple?
- ํจ์๋น ์ ์ญ ์ํ(Control flow analysis)๋ง ์ถ์ ํ๋ ๊ฒ๋ ์ ์ฉํจ.
- ์: ๋ค์ ์ปดํ์ผ๋ฌ(์: Java)์ Dead-code ๊ฐ์ง
- ๊ฒฐ์ ์ง์ ์ ํ์ ๋์ ๋ถ์์ ์ํ Instrumentation, ๋ฃจํ ๊ฐ์ง
- ๋ฆฌ๋ ์ค ์ปค๋์ ์ค์ Interrupt ๋ถ์
- ๋ณต์ก์ฑ์ ํ ๋จ๊ณ ๋์ด๋ ๊ฒ์ ๋ณ์๋น ์ํ๋ฅผ ์ถ์ ํ๋ ๊ฒ (Dataflow analysis)
- ์: ๋ณ์ x๊ฐ 0์ด ๋ ์ ์๋๊ฐ
- ์๋ณธ Domain: ์ ๋ชจ๋ ๋ณ์๋ฅผ ์ ์๋ก ๋งคํ. ๊ฐ๋ฅํ ๊ตฌ์ฒด์ ์ํ ์๋ ๊ฑฐ๋ํจ.
- ๊ฐ์ 32๋นํธ ๋ณ์๋ ๊ฐ์ ์ํ ์ด๋
- ๋ฃจํ๊ฐ ์์ผ๋ฉด ์ํ๊ฐ ๋ฌดํํ ๋ณํ ์ ์์
- Abstract state space๋ ํจ์ฌ ์์: ๋ณ์๊ฐ Zero, Not-zero, ๋๋ Maybe-zero ()
- ์๋ณธ Domain: ์ ๋ชจ๋ ๋ณ์๋ฅผ ์ ์๋ก ๋งคํ. ๊ฐ๋ฅํ ๊ตฌ์ฒด์ ์ํ ์๋ ๊ฑฐ๋ํจ.
Data-Flow Analysis
Data- VS. Control-Flow
- Dataflow: ํ๋ก๊ทธ๋จ ๋ด ๋ณ์(์ผ๋ถ ๋ถ๋ถ ์งํฉ) ๊ฐ๊ฐ์ ๋ํ Abstract value ์ถ์
- Control flow: ํด๋น ํจ์์ ๋ํ ์ ์ญ(Global) ์ํ ์ถ์
Example: Zero/Null-pointer Analysis
- ๋ณ์ x๊ฐ 0์ด ๋ ์ ์๋๊ฐ?
- (์ด๋ค ์ข ๋ฅ์ ์ค๋ฅ๋ฅผ ํ์ธํ ์ ์๋๊ฐ?)
- ์๋ณธ Domain: ์ ๋ชจ๋ ๋ณ์๋ฅผ ์ ์๋ก ๋งคํ
- Abstraction: ๋ชจ๋ ๋ณ์๋ Non zero(NZ), Zero(Z), ๋๋ Maybe zero(MZ)์
Zero Analysis Transfer
- ์ด๋ค ์ฐ์ฐ์ด ๊ด๋ จ๋์ด ์๋๊ฐ?
- ๋ณ์๋ฅผ ์ ๋ฐ์ดํธํ ์ ์๋ ๋ชจ๋ ์ฐ์ฐ!
Zero Analysis Join (per Variable)
- Join(Zero, Zero) โ Zero
- Join(Not-zero, Not-zero) โ Not-zero
- Join(Zero, Not-zero) โ Maybe-zero
- Join(Maybe-zero, *) โ Maybe-zero
Example
x = 10;
y = x;
z = 0;
while (y > -1) {
x = x / y;
y = y - 1;
z = 5;
}
- ๋๋์ ์์ y๊ฐ 0์ด ๋ ์ ์๋์ง ํ์ธํ๊ธฐ ์ํด Zero analysis ์ฌ์ฉ
- 1์ฐจ ๋ฐ๋ณต
- ๊ฐ ๋ผ์ธ๋ณ ์ํ(NZ, Z, MZ) ๋ณํ ์ถ์
- Join ์ ์ฉ ๊ฒฐ๊ณผ
- 2์ฐจ ๋ฐ๋ณต
- ์ํ ๋ณํ ๋ฐ Join ์ ์ฉ ๊ฒฐ๊ณผ
- ๋ฑ ์ํ ์ ๋ฐ์ดํธ
- 3์ฐจ ๋ฐ๋ณต
- ์ด์ ์ํ์ ๋น๊ตํ์ฌ ๋ณ๊ฒฝ ์ฌํญ ์์ (Stable, Fixed point ๋๋ฌ)
- ๊ฒฝ๊ณ : Div-by-zero ์ค๋ฅ ๋ฐ์ ๊ฐ๋ฅ
Abstraction at Work
- ๊ฐ๋ฅํ ์ํ์ ์๋ ๊ฑฐ๋ํจ.
- ๊ฐ์ 32๋นํธ ๋ณ์๋ ๊ฐ์ ๊ฐ๋ฅํ ์ํ
- Loop๊ฐ ์์ผ๋ฉด ์ํ๊ฐ ๋ฌดํํ ๋ณํ ์ ์์
- Zero Analysis๋ ์ํ ๊ณต๊ฐ์ ์ขํ
- 4๊ฐ์ Abstract values (Z, NZ, MZ, )
- ์ด ์ ํ๋ ๊ณต๊ฐ์ด ํ์๋๋ฉด ์๋ฃ๋จ
- ๋ชจ๋ ๋ฃจํ ๋ฐ๋ณต์ ๋ํด ์ธ์ฝ(Extrapolate)
Termination Intuition
- Termination์ ํญ์ ๋ณด์ฅํ์ง๋ ์์. ์๋ ด(fixed point)ํ์ง ์์ ์ ์์.
- ์ ์ฒด ํ๋ก๊ทธ๋จ์ ๋ํด ์ ๋ณด๊ฐ ๋ณํ์ง ์์ ๋๊น์ง ์ํ๋ ์์๋๋ก ๋ช
๋ น์ด๋ฅผ ์ฒ๋ฆฌํ ์ ์์
- ๊ณ์ฐ๋์ง ์์ ๋ชจ๋ ์ํ์ ์ด๊ธฐ ์ํ๋ก ํน๋ณํ ๊ฐ ์ฌ์ฉ
- ํจ์์ ๊ณ ์ ์ (Fixed point)์ ํจ์๊ฐ ์์ ์๊ฒ ๋งคํํ๋ ๋ฐ์ดํฐ ๊ฐ ์
- Flow function์ ์ํ์ ํจ์์
- ๊ฐ ๊ณ ์ ์ ์์์ Dataflow analysis ์ํ๋ ๋ฐ์ดํฐ ๊ฐ์
The Bad News: Riceโs Theorem
"ํ๋ง ๋จธ์ ์ ์ํด ์ธ์๋๋ ์ธ์ด์ ๋ํ ๋น์๋ช ํ ์์ฑ์ ๊ฒฐ์ ๋ถ๊ฐ๋ฅํ๋ค" (Henry Gordon Rice, 1953)
- ๋ชจ๋ ์ ์ ๋ถ์์ ํ์ฐ์ ์ผ๋ก Incompleteํ๊ฑฐ๋ Unsoundํ๊ฑฐ๋ Undecidableํจ (ํน์ ์ด๊ฒ๋ค์ ๋ณตํฉ)
Computability Theory saysโฆ
- ์ ์ง ๋ฌธ์ (Halting problem): ์ฃผ์ด์ง ํ๋ก๊ทธ๋จ์ด ์ฃผ์ด์ง ์ ๋ ฅ์ ๋ํด ์ ์ง/์ข ๋ฃํ ์ง ๊ฒฐ์ ํ๋ ๋ฌธ์
- ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ์ผ๋ฐ์ ์ธ ์๊ณ ๋ฆฌ์ฆ์ ๋ถ๊ฐ๋ฅ
- ๋ ๊ตฌ์ฒด์ ์ผ๋ก, ๊ฒฐ์ ๋ถ๊ฐ๋ฅํจ (Yes ๋ต์ ์ป์ ์ ์์ง๋ง, No ๋ต์ ์ป์ ์ ์์)
- ๋๋๋ก ํด๋ฆฌ์คํฑ์ ์ฌ์ฉํ ์ ์์ง๋ง, ๋ชจ๋ ํ๋ก๊ทธ๋จ์ ๋ํด ์ผ๋ฐ์ ์ผ๋ก ํด๊ฒฐํ๋ ๊ฒ์ ์ฌ์ ํ ๋ถ๊ฐ๋ฅ
def g():
if halts(g):
loop_forever()
OK, So?
- ์ด๋ค ํ๋ก๊ทธ๋จ์ด ๋น์๋ช ํ ์์ฑ(์ ๋ Null ์ญ์ฐธ์กฐ ์ ํจ, ํญ์ ๋ชจ๋ ํ์ผ ํธ๋ค ํด์ ๋ฑ)์ ๊ฐ๋์ง ์ ์ ์ผ๋ก ํญ์ ์ ์ ์๋ค๋ฉด, ์ ์ง ๋ฌธ์ ๋ ์ผ๋ฐ์ ์ผ๋ก ํด๊ฒฐํ ์ ์์
- ...๊ทธ๋ฌ๋ ์ ์ง ๋ฌธ์ ๋ ๋ช ๋ฐฑํ ๋ถ๊ฐ๋ฅํจ.
- ๋ฐ๋ผ์, ์๋ฒฝํ ์ ์ ๋ถ์์ ์์. ํญ์ False positive๋ False negative(๋๋ ๋ ๋ค)๋ฅผ ๊ฐ์ง
- ๋ชจ๋ ๋๊ตฌ๋ trade-off๋ฅผ ๊ฐ์ง
Sound vs. Heuristic Analysis vs. Reality
- Heuristic Analysis
- FindBugs, Coverity, Checkstyle ๋ฑ
- ๊ท์น ๋ฐ๋ฆ, ๊ทผ์ฌ์น ์ฌ์ฉ, False positive๋ฅผ ์ค์ด๊ธฐ ์ํด ์ผ๋ถ ๊ฒ์ฌ ํํผ
- False positive์ False negative ๋ชจ๋ ๋ณด๊ณ ํ ์ ์์
- Sound Static Analysis
- Type checking, Not-Null ๋ฑ (ํน์ ๊ฒฐํจ ํด๋์ค)
- Sound Abstraction, False positive๋ฅผ ์ค์ด๊ธฐ ์ํ ์ ๋ฐํ ๋ถ์
- ๊ทธ๋ฌ๋ ์ค์ ๋ก๋, ์ธ์ด๊ฐ ๋ณต์กํ๋ฉฐ, ๋ชจ๋ ๋๊ตฌ๋ ๋ด๋ถ์ ์ผ๋ก ๋ฌด์์ ๋ชจ๋ธ๋งํ ์ง/์ค์ abstraction์ ์ด๋ป๊ฒ ํ ์ง์ ๋ํ ๊ฒฐ์ ์ด ํ์ํจ.
Example: Null Pointers
int foo() {
Integer x = new Integer(6);
}

What About that Function Call?
- ๋ช ๊ฐ์ง ๊ฐ๋จํ ์ต์
- ์์ ํ ์๋ฑํ Control Flow(Exception, Longjumps)๊ฐ ์ฐ๋ ค๋๋ค๋ฉด, ๋ ๋ณต์กํ Control Flow Graph๋ก ๋ชจ๋ธ๋ง ๊ฐ๋ฅ
- ๋ชจ๋ ํจ์๊ฐ ๋ฐํ๋๋ค๊ณ ๊ฐ์ ํ๊ณ "ํ๋ก๊ทธ๋จ์ด ์ข
๋ฃ๋๋ค๊ณ ๊ฐ์ ํ ๋, ๋ถ์์ด Soundํ๊ฒ ๊ณ์ฐ๋จ..."์ด๋ผ๊ณ ์ฃผ์ฅํ๋ฉฐ ๋ฌด์
- ๋๋ถ๋ถ์ ์ฌ๋๋ค์ ์ ๊ฒฝ ์ฐ์ง ์์ผ๋ฉฐ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฐ์ ํจ.
- Interprocedural ๋ถ์์ด ์กด์ฌํ์ง๋ง ํ์ฅํ๊ธฐ ์ด๋ ต๊ณ ๋ณธ ๊ฐ์ ๋ฒ์๋ฅผ ๋ฒ์ด๋จ.
- ์: ๋จ์ผ์ ํฐ ๊ทธ๋ํ ๊ตฌ์ถ ๋๋ ๋ฉ์๋ ๋ ๋ฒจ์์์ ์ถ์ํ; ์ข ์ข ๋์์ ์ฃผ๊ธฐ ์ํ ์๋ ์ฃผ์(Annotation) ์ฌ์ฉ
Try-Catch?

Design Choices: Representation and Abstract Domain
- Try/catch๋ฅผ ๋ชจ๋ธ๋งํ์ง ์๋๋ค๋ฉด ์ด๋ ํ๊ฐ
- ํ๋ค๋ฉด... ์ด๋ป๊ฒ ํฌํจํด์ผ ํ๋๊ฐ
IOException์ด ์๋ ๊ฒฝ์ฐ๋ ์ด๋ ํ๊ฐ- ๋ ๋์ ์ง๋ฌธ: Semantics๋ฅผ ์ผ๋ง๋ ์ ๋ฐํ๊ฒ ๋ชจ๋ธ๋งํด์ผ ํ๋๊ฐ
- ์: ๋ช ๋ น์ด, ์กฐ๊ฑด ํ์ธ ๋ฑ์ Semantics
Upshot: Analysis as Approximation
- ๋ถ์์ ์ค์ ์ ์ผ๋ก ๊ทผ์ฌ(Approximate)ํด์ผ ํจ.
- False positives: ์ค์ ๋ก๋ ์ค๋ฅ๊ฐ ์๋ ๊ณณ์ ์ค๋ฅ ๋ณด๊ณ ๊ฐ๋ฅ
- False negatives: ์ค์ ๋ก ์กด์ฌํ๋ ์ค๋ฅ๋ฅผ ๋ณด๊ณ ํ์ง ์์ ์ ์์
- ๋ชจ๋ ๋ถ์ ๋๊ตฌ๋ False negative ๋๋ False positive๋ฅผ ๊ฐ์ง
- Approximation ์ ๋ต
- ์ฌ๋ฐ๋ฅธ ์ฝ๋๋ฅผ ์ํ ํจํด P ์ฐพ๊ธฐ
- ํ์ธํ๊ธฐ ์คํ ๊ฐ๋ฅํ๋ฉฐ(๋ถ์์ด ๋นจ๋ฆฌ ์ข ๋ฃ๋จ),
- ์ค์ ๋๋ถ๋ถ์ ์ฌ๋ฐ๋ฅธ ์ฝ๋๋ฅผ ์ปค๋ฒํ๊ณ (๋ฎ์ False positive),
- ์ค๋ฅ๊ฐ ์์์ ์๋ฏธํจ(False negative ์์)
- ์ฌ๋ฐ๋ฅธ ์ฝ๋๋ฅผ ์ํ ํจํด P ์ฐพ๊ธฐ
- ๋ถ์์ ์ค์ ์ ์ผ๋ก ๊ฝค ํ๋ฅญํ ์ ์์
- ๋ง์ ๋๊ตฌ๊ฐ ๋ฎ์ False positive/negative ๋น์จ์ ๊ฐ์ง
- Sound ๋๊ตฌ๋ False negative๊ฐ ์์
- ํ์ธํ๋ ์นดํ ๊ณ ๋ฆฌ ๋ด์์ ์ค๋ฅ๋ฅผ ์ ๋ ๋์น์ง ์์
Summary
- ์ ์ ๋ถ์: ํ๋ก๊ทธ๋จ์ ์คํํ์ง ์๊ณ ํ๋ก๊ทธ๋จ ์์ค๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ์๋ ๋ถ์
- Structural ๋ถ์์ ์ฝ๋ ๋ด ํจํด์ ์ฐพ์
- Control-flow ๋ถ์์ ๋ชจ๋ ๊ฐ๋ฅํ ๊ฒฝ๋ก ๋ถ์ (global ์์ฑ)
- Data-flow ๋ถ์์ ๋ชจ๋ ๊ฒฝ๋ก์์ ๋ณ์์ ๊ฐ๋ฅํ (abstract) ๊ฐ ๋ถ์
- Abstraction, Transfer function, Join
- Fix point ๊ณ์ฐ. termination
- ๋ถ์์ Unsoundํ๊ฑฐ๋ Incompleteํ๊ฑฐ๋ ๋ ๋ค์.


