Distinguish between direct and indirect plugin crash involvement

If a plugin was involved in a crash, we can't safely blame it for the crash, since it might have innocently triggered a core bug. Furthermore, it's difficult to accurately detect plugin causing things like invalid argument crashes.
This commit is contained in:
Dylan K. Taylor 2018-12-27 17:18:46 +00:00
parent 2cdf97b7b5
commit 22a6b817d7

View File

@ -87,7 +87,11 @@ class CrashDump{
* having their content changed, version format changing, etc.
* It is not necessary to increase this when adding new fields.
*/
private const FORMAT_VERSION = 1;
private const FORMAT_VERSION = 2;
private const PLUGIN_INVOLVEMENT_NONE = "none";
private const PLUGIN_INVOLVEMENT_DIRECT = "direct";
private const PLUGIN_INVOLVEMENT_INDIRECT = "indirect";
/** @var Server */
private $server;
@ -245,13 +249,13 @@ class CrashDump{
$this->addLine("Line: " . $error["line"]);
$this->addLine("Type: " . $error["type"]);
$this->data["plugin"] = false;
if(!$this->determinePluginFromFile($error["fullFile"])){ //fatal errors won't leave any stack trace
$this->data["plugin_involvement"] = self::PLUGIN_INVOLVEMENT_NONE;
if(!$this->determinePluginFromFile($error["fullFile"], true)){ //fatal errors won't leave any stack trace
foreach($error["trace"] as $frame){
if(!isset($frame["file"])){
continue; //PHP core
}
if($this->determinePluginFromFile($frame["file"])){
if($this->determinePluginFromFile($frame["file"], false)){
break;
}
}
@ -277,12 +281,17 @@ class CrashDump{
$this->addLine();
}
private function determinePluginFromFile(string $filePath) : bool{
private function determinePluginFromFile(string $filePath, bool $crashFrame) : bool{
$frameCleanPath = Utils::cleanPath($filePath); //this will be empty in phar stub
if($frameCleanPath !== "" and strpos($frameCleanPath, "src/pocketmine/") === false and strpos($frameCleanPath, "vendor/pocketmine/") === false and file_exists($filePath)){
$this->addLine();
$this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN");
$this->data["plugin"] = true;
if($crashFrame){
$this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN");
$this->data["plugin_involvement"] = self::PLUGIN_INVOLVEMENT_DIRECT;
}else{
$this->addLine("A PLUGIN WAS INVOLVED IN THIS CRASH");
$this->data["plugin_involvement"] = self::PLUGIN_INVOLVEMENT_INDIRECT;
}
$reflection = new \ReflectionClass(PluginBase::class);
$file = $reflection->getProperty("file");