C 언어의 위험한 API를 안전하게 다루는 Fil-C의 비결
Fil-C는 setjmp/longjmp 및 ucontext API를 메모리 안전하게 지원하는 새로운 구현 방식을 제시함
기존 C 언어의 스택 손상(Stack Corruption) 및 댕글링 스택(Dangling Stack) 문제를 해결하는 데 중점
데이터 격리 아키텍처(Data Isolation Architecture)와 불변(Immutable) 컨텍스트 객체를 활용하여 안정성 확보
가비지 컬렉션(GC) 통합 및 스레드 친화성(Thread Affinity) 규칙을 통해 복잡한 런타임 환경에서도 안전성 보장
setjmp/longjmp의 근본적인 위험성 분석
커뮤니티에서는 setjmp/longjmp가 컴파일러 최적화와 결합될 때 발생하는 댕글링 스택(Dangling Stack) 문제를 지적합니다. 특히 `volatile` 키워드나 인라인 어셈블리 없이도 컴파일러가 스택 프레임 재사용(Spill Slot Reuse)을 통해 예기치 않은 동작을 유발할 수 있다는 점이 강조됩니다. Fil-C는 이러한 문제를 컴파일러 수준에서 setjmp 호출을 특별히 처리하고, 스택 슬롯 재사용을 억제하여 해결한다고 설명합니다.
Fil-C의 ucontext API 메모리 안전성 확보 전략
Fil-C는 ucontext API 사용 시 데이터 격리 아키텍처(Data Isolation Architecture)를 적용하여 스택 관리를 전적으로 내부적으로 처리합니다. 사용자가 제공하는 `ss_sp` 필드는 무시되며, 내부적으로 안전하게 할당된 스택을 사용합니다. 또한, 상태 머신(State Machine)을 통해 컨텍스트의 생명주기를 엄격히 관리하며, 스레드 친화성(Thread Affinity)을 강제하여 다른 스레드에서의 컨텍스트 접근을 차단합니다.
GC 통합 및 댕글링 포인터 문제 해결
가비지 컬렉션(GC) 환경에서 댕글링 포인터(Dangling Pointer) 문제는 Fil-C의 주요 난제 중 하나입니다. Fil-C는 `zfiber_context` 객체에 GC 루트(GC Roots) 정보를 저장하고, 회색 컨텍스트(Grey Context) 추적 메커니즘을 도입하여 GC가 컨텍스트 스택을 안전하게 스캔하도록 합니다. 이를 통해 컨텍스트 전환 중에도 GC가 유효한 객체만 추적하도록 보장합니다.
setjmp/longjmp와 ucontext API의 차이점 및 Fil-C의 접근 방식
논의에서는 `setjmp/longjmp`가 예외 처리나 복잡한 제어 흐름에 사용되는 반면, `ucontext` API는 코루틴(Coroutine) 및 파이버(Fiber) 구현에 더 적합하다고 설명합니다. Fil-C는 두 API 모두 메모리 안전하게 지원하지만, `ucontext` API의 경우 `getcontext`의 초기화 역할, `makecontext`의 복잡한 계약, `swapcontext`의 유연성 등을 고려하여 제한적인 사용 패턴을 강제함으로써 안정성을 높였습니다.