Abstract
- GitHub์์ ๊ฐ์ฅ ๋ง์ด ๋ค์ด๋ก๋๋๋ Python ๋ผ์ด๋ธ๋ฌ๋ฆฌ 200๊ฐ๋ฅผ ๋์์ผ๋ก, 5๊ฐ ์ค 1๊ฐ์๋ C์ฝ๋๊ฐ ํฌํจ๋์ด ์๋ค.
- ์ ์ ๋ถ์๊ธฐ๋ ๋จ์ผ ์ธ์ด์ ์ด์ ์ ๋ง์ถ๋ ๊ฒฝํฅ์ด ์๊ณ Stub์ ์ฌ์ฉํ์ฌ ์ธ๋ถ ํจ์ ๋์์ ๋ชจ๋ธ๋งํ ์ ์๋ค.
- ๊ทธ๋ฌ๋ ์ด๋ ๊ตฌํํ๋ ๋ฐ ๋น์ฉ์ด ๋ง์ด ๋ค๊ณ ๋ถ์๊ธฐ์ soundness๋ฅผ ์ฝํ์ํจ๋ค.
- ๋ณธ ์ฐ๊ตฌ์์๋ C ํ์ฅ์ ํธ์ถํ๋ Python ํ๋ก๊ทธ๋จ์ ์ฒ๋ฆฌํ ์ ์๋ abstract interpretation์ ํตํด ์ ์ ๋ถ์๊ธฐ๋ฅผ ์ค๊ณํ๋ค.
- ์ ์ ๋ถ์๊ธฐ๋ Python, C ๋ฐ ์ธํฐํ์ด์ค์์ ๋ฐ์ํ ์ ์๋ ๋ฐํ์ ์ค๋ฅ๋ฅผ ๋ณด๊ณ ํ๋ค.
1. Introduction
- host language๋ ์ธํฐํ์ด์ค๋ฅผ ํตํด guest language๋ฅผ ํธ์ถํ๋ค. (==interface = boundary==)
- guest language: C, ๋ค์ดํฐ๋ธ ์ฝ๋, ๋ค์ดํฐ๋ธ C
- host language: Python
- ํ์ด์ฌ์์๋ ๊ธฐ๋ณธ C ๋ชจ๋์ ์ฌ์ฉํ๋ฉฐ ํจ์จ์ ์ธ C ์ฝ๋๋ฅผ ํธ์ถํ๋ high-level ํ์ด์ฌ ์ฝ๋๋ฅผ ์์ฑํ๋ค.
- ์ด๋ ํจ์จ์ ์ด์ง๋ง ์ฌ๋ฌ ๋ฒ๊ทธ๋ฅผ ๋ฐ์์ํค๋๋ฐ, ๊ฐ๋ฐ์๋ ๋ค์ํ ์์ ๋ฉ์ปค๋์ฆ๊ณผ ๋ฉ๋ชจ๋ฆฌ ํํ์์ ๊ณ ๋ คํด์ผ ํ๋ค.
- Python ๐ C
- ํ์ด์ฌ์ ์คํ ์ค ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด Exception ํํ๋ก ์บก์ํ๋์ด ๋ณด๊ณ ๋์ง๋ง, C ์ฝ๋ ์์ญ์์ ๋ฐํ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด ํ์ด์ฌ์ ์์ธ ์ฒ๋ฆฌ ์์คํ ์ด ์ด๋ฅผ ๊ฐ์งํ๊ธฐ๋ ์ ์ ์ด์์ฒด์ ๊ฐ ํ๋ก์ธ์ค๋ฅผ ๊ฐ์ ๋ก ์ข ๋ฃ(Hard crash)์์ผ ๋ฒ๋ฆด ์ ์๋ค.
- Representation: ํ์ด์ฌ ์ ์ ๊ฐ์ฒด๋ ์ต์ 24๋ฐ์ดํธ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ณ unlimited precision, C ์ ์๋ ๊ณ ์ ๋ ๊ธธ์ด(์ผ๋ฐ์ ์ผ๋ก 8~64๋นํธ ๋ฒ์)๋ฅผ ๊ฐ์ง๋ฉฐ ์ค๋ฒํ๋ก์ฐ๊ฐ ๋ฐ์ํ ์ ์๋ค.
- ์ ์ ๋ถ์๊ธฐ๋ Stub์ ์ฌ์ฉํ์ฌ ๋ค๋ฅธ ์ธ์ด์ ๋ํ ํธ์ถ ๋์์ ๋ชจ๋ธ๋งํ ์ ์์ง๋ง, ๊ตฌํํ๋ ๋ฐ์ ์๊ฐ ์์๊ฐ ๋ง์ด ๋๊ณ ์ค์ ์ฝ๋๋ฅผ ๋ถ์ํ๋ ๊ฒ์ด ์๋๊ธฐ ๋๋ฌธ์ ๊ฑด์ ์ฑ๊ณผ ์ ํ์ฑ ์ธก๋ฉด์ ํผ์ํ ์ ์๋ค.
- Mopsa๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌํ: ๋ค์ดํฐ๋ธ C ์ฝ๋์ ํ์ด์ฌ ์ฝ๋๋ฅผ ๋ชจ๋ ๋ถ์ํ๋ ๊ฒ์ ๋ชฉํ๋ก ํ๋ค. (๋ค์ดํฐ๋ธ ๋จ์์ ํ์ด์ฌ ์ฝ๋์ ๋ํ callback ํฌํจ)
- Abstract interpretation: precise, flow, and context-sensitive value analysis
- Mopsa + Multilanguage C/Python ํ๋ก๊ทธ๋จ์ ๋ํ ์ง์ ์ถ๊ฐ (boundary๋ฅผ ๋ชจ๋ธ๋งํ๋ ๋๋ฉ์ธ์ ์ถ๊ฐ)
Limitations
- garbage collection ๋ฏธ์ง์: reference counting์ ๊ธฐ๋ฐ์ผ๋ก ํ garbage collection์ ๋ณธ ์ฐ๊ตฌ์ semantic์ผ๋ก ์ง์๋์ง ์๋๋ค. ๋ฐ๋ผ์ deallocation์ ๊ฐ์งํ์ง ๋ชปํ๋ค. โ ์ฐธ์กฐ ์นด์ดํ ์ค๋ฅ(์กฐ๊ธฐ/์ง์ฐ ํด์ ) ํ์ง ๋ถ๊ฐ
- Lack of formal soundness proof: ๋ถ์ ๋๊ตฌ๊ฐ ์ค๊ณํ ๋ ผ๋ฆฌ ๋ชจ๋ธ์ด ์ค์ ํ์ด์ฌ ์ธํฐํ๋ฆฌํฐ(CPython)์ ๋์๊ณผ 100% ์ผ์นํ๋ค๋ ๊ฒ์ ์ฆ๋ช ํ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ ๋ฏธํ(FN)์ ๊ฐ๋ฅ์ฑ์ด ์๋ค.
- Builtins API ์ฌ๊ฐ์ง๋: ๋ถ์์ ํจ์จ์ฑ์ ์ํด ์ผ๋ถ ๋ณต์กํ API ๊ธฐ๋ฅ์ ๋ด๋ถ์ ์ผ๋ก ๋ฏธ๋ฆฌ ์ ์๋ ํจ์์ฒ๋ผ ๊ฐ์ฃผํ์ฌ ์ฒ๋ฆฌ ๐๐ป API ์์ฒด ๊ตฌํ๋ถ์ ๋ฐํ์ ์๋ฌ๊ฐ ์จ์ด ์๋ค๋ฉด ๋ถ์ ๋๊ตฌ๋ ์ด๋ฅผ ๊ฒ์ฆํ์ง ๋ชปํ๋ค.
- ์ผ๋ถ Python ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ(
pickle,sys.getsizeof๋ฑ) ๋ฏธ์ง์ - ๋ณต์กํ ๋์ ๋ฐฐ์ดยทํฌ์ธํฐ ๊ตฌ์กฐ์์ C ๋ถ์ ์ ๋ฐ๋ ์ ํ
3. Methodology
3.1. Idea
- Python C API๋ฅผ ๊ณต์ ๊ฒฝ๊ณ๋ก ์ผ์, ๊ฐ ์ธ์ด์ ์๋ฏธ๋ก ์ ๋ธ๋๋ฐ์ค๋ก ์ ์งํ๋ฉด์ ๊ฒฝ๊ณ ์ฐ์ฐ๋ง ๋ณ๋๋ก ์ ์ํ๋ค.
- ํต์ฌ ๊ฐ์ : C ์ฝ๋๋ Python ๋ด์ฅ ๊ฐ์ฒด์ API๋ฅผ ํตํด์๋ง ์ ๊ทผํ๋ค. API ํธ์ถ์ Python ์๋ฏธ๋ก ์ผ๋ก ์์ ๊ฐ๋ฅ
3.2. Concrete Semantics
๊ฒฐํฉ ์ํ (Combined State)
| ์ํ | ๊ตฌ์ฑ ์์ |
|---|---|
| Python ์ํ ฮฃp | ํ๊ฒฝ Ep (๋ณ์โ์ฃผ์) + ํ Hp (์ฃผ์โ๊ฐ์ฒด) + ํ๋ฆ ํ ํฐ (cur / exn) |
| C ์ํ ฮฃc | ๋ฉ๋ชจ๋ฆฌ ์ Ec + ํ Hc (์ฃผ์โ์์ ํ์ ยทํฌ๊ธฐ) |
| ๊ฒฐํฉ ์ํ ฮฃ | ฮฃp ร ฮฃc (์ฃผ์ ๊ณต๊ฐ Addr ๊ณต์ ) |
- C์์ PyType_GenericNew๋ก ํ ๋น๋ ๊ฐ์ฒด โ Python ๋ณ์
c๊ฐ ํด๋น ์ฃผ์๋ฅผ ์ง์ ์ฐธ์กฐ (๋ณต์ฌ ์์) PyAlloc์์ ํ์ ์ผ๋ก Python ๊ฐ์ฒด ๊ตฌ๋ถ โ C๊ฐ ์ง์ ์ ๊ทผ ์ ํ์ง ๊ฐ๋ฅ
๊ฒฝ๊ณ ํจ์ (Boundary Functions)
๋ ๋ฐฉํฅ ๋ชจ๋ lazy & shallow ๋ฐฉ์์ผ๋ก ๋์ํ๋ค.
- lazy: ์ค์ ๋ก ์ธ์ด๋ฅผ ๋๋๋๋ ๊ฐ์ฒด๋ง ๋ณํ
- shallow: ์ด๋ฏธ ์๋ ํ์ ๋ฑ๋ก๋ ์ฃผ์๋ ์ฌ๋ณํํ์ง ์์
| ๋ฐฉํฅ | ํจ์ | ์ฃผ์ ๋์ |
|---|---|---|
| Python โ C | p โช c | ob_type ์ด๊ธฐํ, PyAlloc์ผ๋ก C ํ์ ๋ฑ๋ก, ํด๋์ค๋ฉด PyType_Ready ํธ์ถ |
| C โ Python | c โช p | PyAlloc ์ฌ๋ถ ๊ฒ์ฌ, ob_type์ ์ฌ๊ท์ ์ผ๋ก Python ํ์ ๋ฑ๋ก |
์ธ์ด ์ ํ ์ฐ์ฐ 3์ข
โ C call from Python (Python์ด C ํจ์ ํธ์ถ)
in_check โ pโชc(self, args) โ C ํจ์ ์คํ โ out_check โ cโชp(๋ฐํ๊ฐ)
in_check: ์ธ์คํด์ค ํ์ ๊ฒ์ฌ, ์คํจ ์ TypeErrorout_check: NULL ๋ฐํ โ ์์ธ ์ค์ ์ผ๊ด์ฑ ๊ฒ์ฌ, ๋ถ์ผ์น ์ SystemError
โก Python call from C (C์์ Python ์ฝ๋ฐฑ PyObject_CallObject)
cโชp(f, args) โ Python ์๋ฏธ๋ก ์ผ๋ก ์คํ โ ์ ์์ด๋ฉด pโชc(๊ฒฐ๊ณผ)
โ ์์ธ ๋ฐ์์ด๋ฉด NULL + PyErr_SetNone
โข ์ ์ ๋ณํ (PyLong_AsLong / PyLong_FromLong)
- Python ์ ์(๋ฌดํ ์ ๋ฐ๋) โ C long(64๋นํธ) ๋ฒ์ ๊ฒ์ฌ
- ๋ฒ์ ์ด๊ณผ โ OverflowError, ํ์ ๋ถ์ผ์น โ TypeError
PyArg_ParseTuple์|iํฌ๋งท์ ์ด ๋ณํ์ ๋ด๋ถ์ ์ผ๋ก ์ฌ์ฉํ๋ฉฐ C ์ฝ๋ ๊ทธ๋๋ก ๋ถ์
3.3. Abstract Semantics
๊ณต์ ์ถ์ ๋๋ฉ์ธ
๊ฒฐํฉ ์ถ์ ์ํ: ฮฃ]pรc = ฮฃฬ]p ร ฮฃฬ]c ร ฮฃ]u
โ ๊ณต์
์ฃผ์ ํ ๋น ์ถ์ + ์์น ์ถ์ (Interval, Octagon ๋ฑ)
- Python๊ณผ C๊ฐ ๊ฐ์ ์์น ๋๋ฉ์ธ์ ๊ณต์ โ ์ธ์ด ๊ฐ ๊ด๊ณํ ๋ถ๋ณ์ ํํ ๊ฐ๋ฅ
- ์ถ์ ๊ฒฝ๊ณ ํจ์๋ ๊ตฌ์ฒด ๊ฒฝ๊ณ ํจ์์ 1:1 ๋์ โ ๊ฑด์ ์ฑ ์ฆ๋ช ์ด ๋จ์ํด์ง
๊ด๊ณํ ๋ถ์์ ์ด์
๋น๊ด๊ณํ(Interval)๋ง์ผ๋ก๋ Python ๋ณ์ i์ C ๊ตฌ์กฐ์ฒด ํ๋ count์ ๊ด๊ณ๋ฅผ ํํํ ์ ์๋ค.
# rel_count.py
for i in range(randint(1, 100)):
c.incr()
r = c.counter
assert(r == i + 1) # ๋น๊ด๊ณํ์ผ๋ก๋ ์ฆ๋ช
๋ถ๊ฐโ Octagon ๋๋ฉ์ธ์ผ๋ก num(@int) + 1 = num([Counter, offset16, s32]) ๊ด๊ณ๋ฅผ ํํํ๋ฉด ์ด์์
์ฆ๋ช
๊ฐ๋ฅ
3.4. Mopsa Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CPython ๋ค์ค์ธ์ด ๋๋ฉ์ธ โ โ ๊ฒฝ๊ณ ์ฐ์ฐ ๋ด๋น (์ ๊ท ~2,500์ค)
โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโค
โ Python ๋ถ์ โ C ๋ถ์ โ โ ๊ธฐ์กด ๋ถ์๊ธฐ ์ฌ์ฌ์ฉ (์นดํ
์์ ๊ณฑ)
โ ~12,600์ค โ ~11,700์ค โ
โโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโค
โ Universal ๋๋ฉ์ธ โ โ ์ ์ฐจ๊ฐ ๋ถ์, ๋ฃจํ, ์ฃผ์ ํ ๋น, ์์น ์ถ์
โ ~5,600์ค โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๊ณตํต ํ๋ ์์ํฌ ~13,200์ค
- ์ค์ ํ์ผ(DAG) ๋ก ๋๋ฉ์ธ ์กฐํฉ โ ๋ค์ค์ธ์ด ๋๋ฉ์ธ๋ง ์ถ๊ฐํ๋ฉด ๊ธฐ์กด ๋ถ์ ์ฌ์ฌ์ฉ ๊ฐ๋ฅ
- ์์น ์ถ์: ๊ธฐ๋ณธ๊ฐ Interval, ์ ํ์ ์ผ๋ก Octagon ๋ฑ ๊ด๊ณํ ๋๋ฉ์ธ์ผ๋ก ๊ต์ฒด ๊ฐ๋ฅ
- CPython C ํจ์ 60๊ฐ(~650์ค) ์๋ณธ ์ฝ๋ ๊ทธ๋๋ก ์ฌ์ฌ์ฉ
4. Detectable Runtime Error
| ์์ญ | ์ค๋ฅ ์ ํ |
|---|---|
| C ์ฝ๋ | ์ ์ ์ค๋ฒํ๋ก, ์ ๋ก ๋๋์ , ์๋ชป๋ ํฌ์ธํฐ/๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ |
| Python ์ฝ๋ | AttributeError, TypeError, ValueError |
| ๊ฒฝ๊ณ (API) | NULL โ ์์ธ ๋ถ์ผ์น(SystemError), ์ ์ ๋ณํ ์ค๋ฒํ๋ก(OverflowError) |
5. Results
| ๋ผ์ด๋ธ๋ฌ๋ฆฌ | C์ค | Py์ค | ๋ถ์ ์๊ฐ | C ์ ํ์ฑ | Py ์ ํ์ฑ |
|---|---|---|---|---|---|
| noise | 722 | 675 | 19s | 99.6% | 100.0% |
| ahocorasick | 3,541 | 1,336 | 59s | 93.1% | 98.0% |
| levenshtein | 5,441 | 357 | 1.6m | 79.9% | 93.2% |
| cdistance | 1,433 | 912 | 1.9m | 95.3% | 98.3% |
| llist | 2,829 | 1,686 | 4.3m | 99.0% | 98.8% |
| bitarray | 3,244 | 2,597 | 4.6m | 96.3% | 94.6% |
์ ํ์ฑ(Selectivity) = ์์ ํ์ ์ฐ์ฐ ์ / ์ ์ฒด ๊ฒ์ฌ ์. ๋์์๋ก ํ์ ๊ฒฝ๋ณด(false alarm)๊ฐ ์ ์.