A simplified model of Fil-C
This post meticulously breaks down a simplified model of Fil-C, a system designed to bring memory safety to C/C++. It details how Fil-C achieves this through source code transformations, instrumenting pointers with metadata for bounds checking and introducing a garbage collector. The article's technical depth and focus on core C/C++ challenges make it a compelling read for those interested in systems programming and memory management.
The Lowdown
Fil-C proposes a method to make C/C++ memory-safe, addressing common issues like buffer overflows and use-after-free errors. This article presents a simplified model to demystify its core mechanisms, transforming C/C++ code to include runtime checks and memory management features typically found in higher-level languages.
- Pointer Instrumentation: Every local pointer variable gains an accompanying
AllocationRecord*variable, storing metadata about the allocated memory block. AllocationRecordStructure: This struct holdsvisible_bytes(the actual data pointer),invisible_bytes(a parallel array storingAllocationRecord*for heap-stored pointers), andlength.- Rewritten Operations: Trivial pointer assignments and arithmetic operations are modified to also propagate their associated
AllocationRecord*. - Custom Memory Management: Calls to
mallocare replaced withfilc_malloc, which allocates not only the requestedvisible_bytesbut alsoinvisible_bytesand theAllocationRecorditself. - Bounds Checking: Pointer dereferences are augmented with
assertstatements that use theAllocationRecordto verify the pointer is within allocated bounds. - Heap Pointer Tracking: For pointers stored on the heap,
invisible_bytesacts as a shadow memory, storing the correspondingAllocationRecord*values alongside the data. - Garbage Collection: While
filc_freereleasesvisible_bytesandinvisible_bytes, theAllocationRecorditself is managed by a garbage collector. This enables memory to be freed even iffreeis forgotten and allows for safe handling of local variables whose addresses escape their scope. memmoveHandling: Special attention is given tomemmoveto ensure that alongside thevisible_bytesmovement, the correspondinginvisible_bytes(containing pointer metadata) are also moved for aligned blocks.- Production System Complexities: The article briefly touches upon further challenges in a real-world Fil-C implementation, such as thread safety, function pointer validation, and various performance and memory optimizations.
- Potential Use Cases: Fil-C could be used to make existing C/C++ code memory-safe (at a performance cost), as a memory bug-finding tool (similar to ASan), for safe compile-time evaluation in languages like Zig, or as a concrete system for exploring pointer provenance.
The simplified model provides a clear conceptual understanding of how Fil-C imbues C/C++ with memory safety features, primarily through comprehensive code transformation and the introduction of a garbage collector, albeit with performance and memory overheads.