find-race-conditions
Race Condition Detection
Analyze PHP code for concurrency issues and race conditions.
Detection Patterns
1. Check-Then-Act (TOCTOU)
// BUG: Time-of-check to time-of-use
if (file_exists($path)) {
$content = file_get_contents($path); // File may be deleted
}
// BUG: Check then modify
if (!$user->hasOrder()) {
$order = new Order();
$user->addOrder($order); // Another request may add order
}
// BUG: Inventory check-then-act
if ($product->getStock() >= $quantity) {
$product->decreaseStock($quantity); // Race with other orders
}
2. Shared Mutable State
// BUG: Static mutable property
class Counter {
private static int $count = 0;
public function increment(): void {
self::$count++; // Not atomic
}
}
// BUG: Shared cache without locking
class Cache {
private array $data = [];
public function getOrSet(string $key, callable $factory): mixed {
if (!isset($this->data[$key])) {
$this->data[$key] = $factory(); // May compute twice
}
return $this->data[$key];
}
}
3. Read-Modify-Write Without Lock
// BUG: Non-atomic increment
$counter = $redis->get('counter');
$redis->set('counter', $counter + 1); // Lost update
// BUG: Balance update
$balance = $account->getBalance();
$account->setBalance($balance - $amount); // Race condition
// FIXED: Use atomic operations
$redis->incr('counter');
4. File System Race Conditions
// BUG: Directory creation race
if (!is_dir($path)) {
mkdir($path); // Another process may create it
}
// BUG: File write race
$data = json_decode(file_get_contents($file));
$data['count']++;
file_put_contents($file, json_encode($data)); // Lost update
5. Database Race Conditions
// BUG: No optimistic locking
$entity = $repository->find($id);
$entity->setStatus('processed');
$entityManager->flush(); // Another process may have changed it
// BUG: Unique constraint race
if (!$repository->findByEmail($email)) {
$user = new User($email);
$entityManager->persist($user); // Duplicate may be created
}
6. Session Race Conditions
// BUG: Session data race
$cart = $_SESSION['cart'];
$cart[] = $newItem;
$_SESSION['cart'] = $cart; // Lost update with concurrent requests
Grep Patterns
# Check-then-act patterns
Grep: "if\s*\(file_exists\([^)]+\)\)\s*\{[^}]*file_get_contents" --glob "**/*.php"
# Static mutable properties
Grep: "private static\s+(?!readonly)" --glob "**/*.php"
# Read-modify-write on Redis
Grep: "->get\([^)]+\)[^;]*\+[^;]*->set" --glob "**/*.php"
# Non-atomic increment
Grep: "\+\+|\-\-|self::\$\w+\s*\+=" --glob "**/*.php"
Severity Classification
| Pattern | Severity |
|---|---|
| Financial data race | π΄ Critical |
| Inventory TOCTOU | π΄ Critical |
| Unique constraint race | π Major |
| File system race | π Major |
| Cache stampede | π‘ Minor |
| Counter race | π‘ Minor |
Fixes
Use Locks
// Database lock
$connection->beginTransaction();
$entity = $repository->find($id, LockMode::PESSIMISTIC_WRITE);
$entity->process();
$connection->commit();
Use Atomic Operations
// Redis atomic increment
$redis->incr('counter');
// Database atomic update
$connection->executeStatement(
'UPDATE products SET stock = stock - ? WHERE id = ? AND stock >= ?',
[$quantity, $productId, $quantity]
);
Use Optimistic Locking
#[Version]
private int $version;
// Will throw OptimisticLockException on conflict
Output Format
### Race Condition: [Description]
**Severity:** π΄/π /π‘
**Location:** `file.php:line`
**Type:** [TOCTOU|Shared State|Read-Modify-Write|...]
**Issue:**
[Description of the race condition]
**Code:**
```php
// Problematic code
Fix:
// Thread-safe version
More from dykyi-roman/awesome-claude-code
psr-overview-knowledge
PHP Standards Recommendations (PSR) overview knowledge base. Provides comprehensive reference for all accepted PSRs including PSR-1,3,4,6,7,11,12,13,14,15,16,17,18,20. Use for PSR selection decisions and compliance audits.
22detect-code-smells
Detects code smells in PHP codebases. Identifies God Class, Feature Envy, Data Clumps, Long Parameter List, Long Method, Primitive Obsession, Message Chains, Inappropriate Intimacy. Generates actionable reports with refactoring recommendations.
15clean-arch-knowledge
Clean Architecture knowledge base. Provides patterns, antipatterns, and PHP-specific guidelines for Clean Architecture and Hexagonal Architecture audits.
15ddd-knowledge
DDD architecture knowledge base. Provides patterns, antipatterns, and PHP-specific guidelines for Domain-Driven Design audits.
14testing-knowledge
Testing knowledge base for PHP 8.4 projects. Provides testing pyramid, AAA pattern, naming conventions, isolation principles, DDD testing guidelines, and PHPUnit patterns.
12bug-root-cause-finder
Root cause analysis methods for PHP bugs. Provides 5 Whys technique, fault tree analysis, git bisect guidance, and stack trace parsing.
12