Skip to content

Commit

Permalink
Catch fatal errors on shutdown
Browse files Browse the repository at this point in the history
  • Loading branch information
nikic committed Sep 12, 2020
1 parent efcdc05 commit 392bf4a
Showing 1 changed file with 21 additions and 0 deletions.
21 changes: 21 additions & 0 deletions src/Fuzzer.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ final class Fuzzer {

private ?string $coverageDir = null;
private array $fileInfos = [];
private ?string $lastInput = null;

private int $runs = 0;
private int $lastInterestingRun = 0;
Expand Down Expand Up @@ -193,6 +194,9 @@ private function runInput(string $input) {
if (\extension_loaded('pcntl')) {
\pcntl_alarm($this->timeout);
}

// Remember the last input in case PHP generates a fatal error.
$this->lastInput = $input;
FuzzingContext::reset();
$crashInfo = null;
try {
Expand Down Expand Up @@ -417,6 +421,7 @@ public function handleCliArgs() {

$this->setupTimeoutHandler();
$this->setupErrorHandler();
$this->setupShutdownHandler();
$this->loadTarget($getOpt->getOperand('target'));

$command->getHandler()($getOpt);
Expand Down Expand Up @@ -489,4 +494,20 @@ private function setupErrorHandler(): void {
'[%d] %s in %s on line %d', $errno, $errstr, $errfile, $errline));
});
}

private function setupShutdownHandler(): void {
// If a fatal error occurs, at least recover the crashing input.
// TODO: We could support fork mode to continue fuzzing after this (and allow minimization).
register_shutdown_function(function() {
$error = error_get_last();
if ($error === null || $error['type'] != E_ERROR) {
return;
}

$crashInfo = "Fatal error: {$error['message']} in {$error['file']} on line {$error['line']}";
$entry = new CorpusEntry($this->lastInput, [], $crashInfo);
$entry->storeAtPath($this->outputDir . '/crash-' . $entry->hash . '.txt');
$this->printCrash('CRASH', $entry);
});
}
}

0 comments on commit 392bf4a

Please sign in to comment.