TCC can automatically generate memory and bound checks while allowing all C pointer operations. This feature can detect buffer overflows, invalid memory access, and other common memory errors at runtime, even when using non-patched libraries.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/TinyCC/tinycc/llms.txt
Use this file to discover all available pages before exploring further.
Bounds checking is activated with the
-b command-line option. When enabled, TCC defines the __TCC_BCHECK__ macro.How it works
The bounds checker instruments your code to track memory regions and validate all pointer accesses at runtime. It maintains a tree of valid memory regions and checks every pointer dereference against this tree.Types of errors detected
TinyCC’s bounds checker can detect numerous memory safety violations:Buffer overflow
Invalid range with standard string function
Invalid range with standard string function
Out of bounds in global or local arrays
Out of bounds in global or local arrays
Out of bounds in malloc'ed data
Out of bounds in malloc'ed data
Use-after-free
Access of freed memory
Access of freed memory
Double free
Double free
Environment variables
Control bounds checking behavior with environment variables:Controlling bounds checking in code
You can enable/disable bounds checking at runtime using the API:The
__bounds_checking(x) function adds x to a thread-local counter. When this counter is non-zero, bounds checking is disabled for that thread.Platform support
Bounds checking is available on:- i386 (Linux and Windows)
- x86_64 (Linux and Windows)
- ARM
- ARM64 (aarch64)
- RISC-V 64
Bounds checking is not available on all platforms. Check your specific TCC build for support.
Performance and compatibility
Performance impact
Code size and speed
Code size and speed
- Generated code is larger: Instrumentation adds checks before each pointer access
- Slower execution: Runtime validation has overhead (typically 2-10x slower)
- Memory overhead: Maintains tree of memory regions
Compatibility notes
Checked code interoperability
Major advantages:
- Pointer size unchanged: No modifications to pointer representation
- Binary compatible: Checked and unchecked code can be mixed freely
- Library compatible: Works with non-patched libraries
- Supports all C pointer operations: Even obscure casts work correctly
Practical examples
Basic usage
Advanced usage with debugging
Integration with backtrace
Implementation details
For those interested in how it works:Memory region tracking
Fromlib/bcheck.c:
- Stack variables (local arrays)
- Heap allocations (malloc, calloc, realloc)
- Global/static variables
- alloca() allocations
Checked functions
The following functions are automatically wrapped: Memory functions:malloc,calloc,realloc,freememalign(on supported platforms)mmap,munmap(Unix)
memcpy,memcmp,memmove,memsetstrlen,strcpy,strncpystrcmp,strncmpstrcat,strncatstrchr,strrchrstrdup
All checks are performed at runtime with minimal overhead, optimized using a splay tree data structure for fast lookups.
Best practices
- Development: Always use
-bduring development to catch memory errors early - Testing: Run your test suite with bounds checking enabled
- Production: Consider disabling for performance (after thorough testing)
- Debugging: Combine with
-gand-btfor maximum debug information - Signal handlers: Always disable checking in signal handlers using
__bounds_checking(1)