Static Bug Detector
Overview
Perform static analysis on source code to identify potential functional bugs. Detect common bug patterns, analyze control flow and data flow, and report suspicious locations with explanations, severity levels, and confidence assessments.
Bug Detection Workflow
Step 1: Understand the Code
Analyze the code structure and semantics:
- Identify language:
- Determine programming language
- Understand language-specific semantics
- Note language idioms and conventions
- Parse code structure:
- Functions/methods
- Classes/types
- Control flow (if, loops, etc.)
- Data flow (assignments, returns)
- Build context:
- Variable declarations and types
- Function signatures
- Class hierarchies
- Dependencies
- Identify scope:
- What code to analyze
- Entry points
- Critical paths
Step 2: Detect Bug Patterns
Scan for common bug patterns:
- Null dereference bugs:
- Variables from nullable sources
- Dereferences without null checks
- Null checks after use
- Undocumented null returns
- Incorrect conditions:
- Always true/false conditions
- Assignment in condition (= vs ==)
- Redundant conditions
- Inverted logic
- Wrong operators
- Unreachable code:
- Code after return/throw
- Always-false branches
- Dead code paths
- Inconsistent state:
- Partial state updates
- Updates without validation
- Non-atomic operations
- Broken invariants
- Logic errors:
- Off-by-one errors
- Wrong operator precedence
- Infinite loops
- Incorrect boolean logic
- Resource issues:
- Resource leaks
- Double free/close
- Use after free/close
- Type issues:
- Type mismatches
- Implicit coercion
- Invalid casts
Step 3: Analyze Severity
Assess the impact of each bug:
High Severity:
- Causes crashes or exceptions
- Data corruption
- Security vulnerabilities
- Guaranteed runtime errors
Medium Severity:
- Incorrect behavior
- Potential errors (context-dependent)
- Performance issues
- Maintainability problems
Low Severity:
- Code smells
- Redundant code
- Minor inefficiencies
- Style issues that might hide bugs
Step 4: Assess Confidence
Determine confidence in the bug report:
High Confidence (90-100%):
- Clear violation of language semantics
- Guaranteed to cause error
- Well-known bug pattern
- No ambiguity
Medium Confidence (60-89%):
- Likely bug but context-dependent
- May be intentional in rare cases
- Suspicious pattern
- Needs verification
Low Confidence (30-59%):
- Unusual but possibly valid
- Could be intentional design
- Needs more context
- Style issue that might hide bug
Factors:
- Code context available
- Language semantics clarity
- Pattern recognition
- Documentation consistency
Step 5: Generate Report
Produce structured bug report:
- For each bug:
- Bug type/category
- Location (file, line, range)
- Severity level
- Confidence level
- Description
- Why it's a bug
- Potential impact
- Recommendation/fix
- Organize by:
- Severity (high first)
- Confidence (high first)
- Location (file order)
- Bug type (grouped)
- Include:
- Code context
- Example fixes
- Related bugs
- Summary statistics
Bug Categories
For detailed patterns and examples, see [detection_patterns.md](references/detection_patterns.md).
Quick Reference
| Bug Category | Common Patterns | Severity | Detection Difficulty | |--------------|----------------|----------|---------------------| | Null Dereference | No null check, null after use | High | Easy | | Incorrect Conditions | = vs ==, always true/false | High-Medium | Easy | | Unreachable Code | After return, dead branch | Low | Easy | | Inconsistent State | Partial update, no validation | High-Medium | Medium | | Logic Errors | Off-by-one, wrong precedence | High-Medium | Medium | | Resource Issues | Leaks, double close | Medium | Medium | | Type Issues | Mismatch, implicit coercion | Medium-Low | Easy |
Examples
Example 1: Null Dereference
Input Code (Java):
public String getUserName(int userId) {
User user = userRepository.findById(userId);
return user.getName();
}
Analysis Output:
## Bug: Potential null dereference
**Location:** line 3
**Severity:** High
**Confidence:** High (95%)
### Description
Variable 'user' may be null but is dereferenced without null check.
### Why This Is a Bug
Method 'findById' may return null if user not found. Calling 'getName()'
on null will throw NullPointerException.
### Potential Impact
- Runtime NullPointerException
- Application crash
- Poor user experience
### Recommendation
Add null check before dereferencing:
public String getUserName(int userId) { User user = userRepository.findById(userId); if (user == null) { return null; // or throw exception } return user.getName(); }
Or use Optional:
public Optional<String> getUserName(int userId) { return Optional.ofNullable(userRepository.findById(userId)) .map(User::getName); }
Example 2: Incorrect Condition
Input Code (C):
int status = getStatus();
if (status = SUCCESS) {
printf("Operation successful\n");
}
Analysis Output:
## Bug: Assignment in condition
**Location:** line 2
**Severity:** High
**Confidence:** High (98%)
### Description
Using assignment operator '=' instead of comparison operator '==' in condition.
### Why This Is a Bug
Expression 'status = SUCCESS' assigns SUCCESS to status and evaluates to
SUCCESS value. This is almost always a typo for 'status == SUCCESS'.
### Potential Impact
- Condition always evaluates to true (if SUCCESS is non-zero)
- Original status value lost
- Logic error in program flow
### Recommendation
Change to comparison operator:
if (status == SUCCESS) { printf("Operation successful\n"); }
Most compilers warn about this. Enable warnings: -Wall -Wextra
Example 3: Off-by-One Error
Input Code (Python):
def process_array(arr):
for i in range(len(arr) + 1):
print(arr[i])
Analysis Output:
## Bug: Off-by-one error (array index out of bounds)
**Location:** line 2-3
**Severity:** High
**Confidence:** High (100%)
### Description
Loop iterates one past the end of array, causing IndexError.
### Why This Is a Bug
range(len(arr) + 1) produces indices 0 to len(arr) inclusive. Array
indices are 0 to len(arr)-1, so arr[len(arr)] is out of bounds.
### Potential Impact
- IndexError exception
- Program crash
- Incorrect behavior
### Recommendation
Remove the +1:
def process_array(arr): for i in range(len(arr)): print(arr[i])
Or use idiomatic iteration:
def process_array(arr): for item in arr: print(item)
Example 4: Resource Leak
Input Code (Python):
def read_config(path):
f = open(path)
config = json.load(f)
return config
Analysis Output:
## Bug: Resource leak
**Location:** line 2
**Severity:** Medium
**Confidence:** High (90%)
### Description
File opened but never closed, causing resource leak.
### Why This Is a Bug
File handle opened on line 2 is never closed. If exception occurs during
json.load or in normal execution, file remains open.
### Potential Impact
- File descriptor leak
- Resource exhaustion with many calls
- File locking issues on Windows
### Recommendation
Use context manager to ensure cleanup:
def read_config(path): with open(path) as f: config = json.load(f) return config
Or ensure close in finally:
def read_config(path): f = open(path) try: config = json.load(f) return config finally: f.close()
Example 5: Inconsistent State Update
**Input