If you’ve ever stared at a large C codebase wondering whether two function calls touch the same shared state, you know the pain. Manual code review is error-prone, and full program analysis can be overkill. prongC was built to solve exactly this problem. It’s a lightweight static analysis tool that detects shared variable accesses between function calls without requiring whole-program analysis.
The Problem It Solves
Consider this scenario: you have two function calls in your code:
foo(arg1, arg2, shared_arg);
bar(shared_arg, arg3);
Can you safely reorder them? Do they both read or modify the same variables? prongC gives you a definitive answer by tracing how each argument flows through the function bodies.
Key features
- No whole-program analysis – prongC only works with the functions and files you specify
- Individual parameter and global tracing – prongC can identify all variable accesses to globals or parameters you specify individually
- Compile database support – works seamlessly with
compile_commands.json - Multithreaded parsing – parse C files faster with
-joption
Usage
You tell prongC which files to analyze and which function calls to examine:
prongc --files="file1.c,file2.c" \
--functions="foo(arg1, arg2, shared_arg);bar(shared_arg, arg3)" \
-j8
Enter fullscreen mode Exit fullscreen mode
The tool traces how each argument is used through the program and reports any overlaps.
You can also trace individual parameters of functions or globals by name:
prongc --files="file.c" \
--functions="foo(arg1)" \
--trace="foo@arg1"
Enter fullscreen mode Exit fullscreen mode
Useful for
- Finding hidden variable access overlaps
- Verifying function call reordering safety
- Investigating side effects in legacy C code you’re maintaining
- Exploring data dependencies across multiple files
- Undestanding unfamiliar codebases faster by uncovering data relationships
Output example
-------------------
Variable overlap:
foo(char *arg1, int arg2, bool shared_arg) → file1.c, line: 639, col: 6 │ READ : shared_arg
if (shared_arg) {
^
bar(bool shared_arg, size_t arg3) → file1.c, line: 699, col: 25 │ READ : shared_arg
var = shared_arg;
^
-------------------
Enter fullscreen mode Exit fullscreen mode
Or for individual variable tracing
Input example:
prongc --files="file.c" \
--functions="foo(arg1, arg2, arg3)" \
--trace="foo@arg1"
Enter fullscreen mode Exit fullscreen mode
Output:
-------------------
Tracing foo@arg1:
foo(char *arg1, int arg2, bool arg3) → file.c, line: 540, col: 9 │ READ : arg1
local = arg1;
^
-------------------
Enter fullscreen mode Exit fullscreen mode
답글 남기기