A fast, accurate static analysis tool for detecting memory errors in C programs.
MemProf analyzes C source code without executing it, identifying memory-related bugs that cause crashes, security vulnerabilities, and undefined behavior.
- Memory Leak Detection - Tracks allocations through all code paths, identifies unreleased memory
- Double-Free Detection - Catches attempts to free already-freed memory
- Use-After-Free Detection - Flags access to memory after deallocation
- Buffer Overflow Detection - Pattern-based detection of out-of-bounds access
- Uninitialized Variable Detection - Identifies reads before writes
- Unsafe Function Warnings - Flags dangerous functions like
gets,strcpy,sprintf
# Clone the repository
git clone https://github.com/Warxiik/memprof.git
cd memprof
# Build with CMake
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
# Install (optional)
cmake --install build- C17-compatible compiler (GCC 8+, Clang 6+, MSVC 2019+)
- CMake 3.16 or later
# Analyze a single file
memprof main.c
# Analyze multiple files
memprof src/*.c
# Scan directory recursively
memprof -r ./src
# Output as JSON (for CI/tooling integration)
memprof -f json -o report.json src/
# Generate HTML report
memprof -f html -o report.html src/
# Check only specific issues
memprof --check=leak,double-free main.c
# Fail on warnings (for CI pipelines)
memprof --fail-on-warning -r ./srcsrc/server.c:142:5: error[MP001]: memory leak
142 | char *buffer = malloc(1024);
| ^~~~~~
= note: allocated here but never freed
= note: function returns at line 158 without freeing 'buffer'
src/parser.c:89:9: error[MP020]: use-after-free
89 | return node->data;
| ^~~~~~~~~~
= note: 'node' was freed at line 85
85 | free(node);
| ^~~~~~~~~~
src/utils.c:34:5: warning[MP032]: unsafe function
34 | strcpy(dest, src);
| ^~~~~~~~~~~~~~~~~~
= help: consider using strncpy or strlcpy instead
Found 2 errors and 1 warning in 3 files
| Code | Severity | Description |
|---|---|---|
| MP001 | Error | Memory allocated but never freed |
| MP002 | Error | Memory leak on conditional path |
| MP003 | Error | Memory leak before return statement |
| MP010 | Error | Double free detected |
| MP011 | Warning | Potential double free on conditional path |
| MP020 | Error | Use-after-free: accessing freed memory |
| MP021 | Error | Passing freed pointer to function |
| MP030 | Error | Array index out of bounds |
| MP031 | Error | Buffer overflow in string operation |
| MP032 | Warning | Use of unsafe function |
| MP040 | Error | Read of uninitialized variable |
| MP041 | Error | Dereference of uninitialized pointer |
| MP050 | Warning | Unchecked malloc return value |
| MP051 | Warning | Potential null pointer dereference |
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Source │───▶│ Lexer │───▶│ Parser │
│ Code │ │ (Tokenizer) │ │ (AST) │
└─────────────┘ └─────────────┘ └─────────────┘
│
▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Reporter │◀───│ Analyzer │◀───│ Symbol │
│ (Output) │ │ (Detectors) │ │ Table │
└─────────────┘ └─────────────┘ └─────────────┘
- Lexer: Hand-written tokenizer with precise source location tracking
- Parser: Recursive descent parser producing a typed AST
- Symbol Table: Tracks variables, types, and memory states across scopes
- Analyzer: Runs detection passes over the AST
- Reporter: Formats diagnostics for terminal, JSON, or HTML output
MemProf uses static analysis to reason about program behavior without execution:
- Tokenization: Source code is broken into tokens (identifiers, keywords, operators)
- Parsing: Tokens are assembled into an Abstract Syntax Tree (AST)
- Symbol Resolution: Variables are tracked through scopes with their types
- Memory State Tracking: Each pointer is modeled with a state machine:
UNALLOCATED ──malloc()──▶ ALLOCATED ──free()──▶ FREED │ │ │ scope exit │ use ▼ ▼ LEAK USE-AFTER-FREE - Path-Sensitive Analysis: Conditional branches are analyzed separately and merged
Colored output similar to Clang/GCC with source snippets and underlined tokens.
LSP-compatible format for IDE integration:
{
"file": "main.c",
"diagnostics": [{
"range": {"start": {"line": 10, "character": 4}, "end": {"line": 10, "character": 25}},
"severity": 1,
"code": "MP001",
"source": "memprof",
"message": "Memory leak: 'ptr' allocated but never freed"
}]
}Self-contained report with syntax highlighting and interactive navigation.
MemProf performs intra-procedural analysis (within functions). It does not:
- Follow allocations across function calls (inter-procedural analysis)
- Expand macros or process
#includedirectives - Handle complex pointer arithmetic or aliasing
- Analyze multi-threaded code
For production code, consider complementing MemProf with dynamic analysis tools like Valgrind or AddressSanitizer.
Contributions are welcome! Please open an issue or submit a pull request.
MIT License - see LICENSE for details.
Inspired by the error reporting style of Clang and Rust, and the static analysis approaches of Coverity and PVS-Studio.
