Claude-skill-registry check-memory-safety
Check Mojo code for memory safety issues (ownership violations, use-after-free, etc.). Use to catch memory bugs.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/check-memory-safety" ~/.claude/skills/majiayu000-claude-skill-registry-check-memory-safety && rm -rf "$T"
manifest:
skills/data/check-memory-safety/SKILL.mdsource content
Check Memory Safety
Validate Mojo code for memory safety violations and ownership issues.
When to Use
- Code review focused on memory safety
- Testing for use-after-free issues
- Verifying ownership transfer correctness
- Catching double-free or segmentation fault sources
- Validating SIMD memory access patterns
Quick Reference
# Find potential use-after-free patterns grep -n "var .* = .*\^" *.mojo | head -20 # Check for uninitialized access grep -n "List\[.*\]()" *.mojo | grep -A 2 "\..*\[" # Verify ownership transfer grep -n "owned\|var.*=" *.mojo | sort # Check pointer operations grep -n "DTypePointer\|alloc\|free\|__del__" *.mojo # Find scope issues grep -n "{" *.mojo | wc -l # Check nesting depth
Memory Safety Patterns
Safe Ownership Transfer:
- ✅
- Caller loses accessfn take(var data: List[Int]) - ✅
- Transfer from struct fieldreturn self.data^ - ✅
- Move to new variablevar copy = data^ - ❌
- Ambiguous, use varfn take(data: List[Int]) - ❌
- Missing transfer operatorreturn self.data
Safe Initialization:
- ✅
thenvar shape = List[Int]()shape.append(dim) - ✅
var data = DTypePointer[DType.float32].alloc(size) - ✅ Check
before allocationsize > 0 - ❌
thenvar list = List[Int]()
(uninitialized)list[0] = value - ❌
oralloc(0)
(invalid size)alloc(negative)
Safe Pointer Usage:
- ✅ Allocate before use:
alloc(size) - ✅ Store size separately for bounds checking
- ✅ Verify pointer validity before dereference
- ❌ Use after free (manually deleted pointer)
- ❌ Out-of-bounds access
- ❌ Null pointer dereference
Safe Scope Management:
- ✅ Owned values dropped at scope end
- ✅ RAII pattern with proper cleanup
- ✅ Lifetime boundaries clear
- ❌ Variable used after scope exit
- ❌ Reference to stack variable returned
- ❌ Missing ownership transfer between scopes
Safety Validation Workflow
- Identify pointers: Find all pointer operations
- Check allocation: Verify all pointers allocated before use
- Trace ownership: Follow ownership transfers
- Verify lifetimes: Check value scopes
- Find violations: Identify safety issues
- Suggest fixes: Provide safety corrections
- Verify fixes: Compile to confirm safety
Output Format
Report memory safety issues with:
- Issue Type - Use-after-free, double-free, uninitialized, bounds, etc.
- Location - File and line number
- Code Snippet - The problematic code
- Root Cause - Why it's unsafe
- Risk Level - Segfault, undefined behavior, or warning
- Fix - How to correct it safely
Common Safety Issues & Fixes
Uninitialized List Access:
- Problem:
var list = List[Int](); list[0] = 5 - Risk: Out-of-bounds write, segmentation fault
- Fix: Use
insteadlist.append(5)
Use After Move:
- Problem:
(list moved, now invalid)var a = list^; print(list) - Risk: Use-after-free
- Fix: Don't use list after transfer, or create copy
Missing Bounds Check:
- Problem: Access
without size checktensor._data[index] - Risk: Out-of-bounds access, segfault
- Fix: Add
or check in loopassert index < size
Pointer Without Size:
- Problem:
but size not trackedvar ptr = alloc(size) - Risk: Invalid access, use-after-free
- Fix: Store size, verify before access
Double-Free:
- Problem: Manual
called twice on same pointerfree() - Risk: Heap corruption, segfault
- Fix: Use RAII, don't call free manually
Error Handling
| Problem | Solution |
|---|---|
| Compiler not available | Build with to get errors |
| Complex ownership | Trace step-by-step through ownership chain |
| Generic code | Check all type instantiations |
| External code | Verify contract assumptions |
| False positives | Verify with test execution |
Safety Checklist
Before committing Mojo code:
- All pointers have size tracked
- All List/Dict allocations use append/insert
- All ownership transfers use
^ - No variables used after move
- All pointer access has bounds check
- Scope lifetimes match usage
- Compiler produces no errors or warnings
References
- See CLAUDE.md for ownership patterns
- See validate-mojo-patterns for pattern checking
- See mojo-lint-syntax for syntax issues