Added plugin crash detection

This commit is contained in:
Shoghi Cervantes 2014-07-28 13:20:13 +02:00
parent bf09c48d62
commit 409eeda6ee
3 changed files with 27 additions and 7 deletions

View File

@ -143,7 +143,7 @@ class CrashDump{
E_USER_DEPRECATED => "E_USER_DEPRECATED", E_USER_DEPRECATED => "E_USER_DEPRECATED",
); );
$error["fullFile"] = $error["file"]; $error["fullFile"] = $error["file"];
$error["file"] = str_replace(["\\", ".php", "phar://", rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), "/"), rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH), "/")], ["/", "", "", "", ""], $error["file"]); $error["file"] = cleanPath($error["file"]);
$error["type"] = isset($errorConversion[$error["type"]]) ? $errorConversion[$error["type"]] : $error["type"]; $error["type"] = isset($errorConversion[$error["type"]]) ? $errorConversion[$error["type"]] : $error["type"];
if(($pos = strpos($error["message"], "\n")) !== false){ if(($pos = strpos($error["message"], "\n")) !== false){
$error["message"] = substr($error["message"], 0, $pos); $error["message"] = substr($error["message"], 0, $pos);
@ -162,6 +162,18 @@ class CrashDump{
$this->addLine(); $this->addLine();
$this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN"); $this->addLine("THIS CRASH WAS CAUSED BY A PLUGIN");
$this->data["plugin"] = true; $this->data["plugin"] = true;
foreach($this->server->getPluginManager()->getPlugins() as $plugin){
$reflection = new \ReflectionClass("pocketmine\\plugin\\PluginBase");
$file = $reflection->getProperty("file");
$file->setAccessible(true);
$filePath = \pocketmine\cleanPath($file->getValue($plugin));
var_dump($filePath, $error["file"]);
if(strpos($error["file"], $filePath) === 0){
$this->data["plugin"] = $plugin->getName();
$this->addLine("BAD PLUGIN: ".$plugin->getDescription()->getFullName());
break;
}
}
}else{ }else{
$this->data["plugin"] = false; $this->data["plugin"] = false;
} }

View File

@ -193,12 +193,16 @@ namespace pocketmine {
$params .= (is_object($value) ? get_class($value) . " " . (method_exists($value, "__toString") ? $value->__toString() : "object") : gettype($value) . " " . @strval($value)) . ", "; $params .= (is_object($value) ? get_class($value) . " " . (method_exists($value, "__toString") ? $value->__toString() : "object") : gettype($value) . " " . @strval($value)) . ", ";
} }
} }
$messages[] = "#$j " . (isset($trace[$i]["file"]) ? str_replace(["\\", ".php", "phar://", rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), "/"), rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH), "/")], ["/", "", "", "", ""], $trace[$i]["file"]) : "") . "(" . (isset($trace[$i]["line"]) ? $trace[$i]["line"] : "") . "): " . (isset($trace[$i]["class"]) ? $trace[$i]["class"] . (($trace[$i]["type"] === "dynamic" or $trace[$i]["type"] === "->") ? "->" : "::") : "") . $trace[$i]["function"] . "(" . substr($params, 0, -2) . ")"; $messages[] = "#$j " . (isset($trace[$i]["file"]) ? cleanPath($trace[$i]["file"]) : "") . "(" . (isset($trace[$i]["line"]) ? $trace[$i]["line"] : "") . "): " . (isset($trace[$i]["class"]) ? $trace[$i]["class"] . (($trace[$i]["type"] === "dynamic" or $trace[$i]["type"] === "->") ? "->" : "::") : "") . $trace[$i]["function"] . "(" . substr($params, 0, -2) . ")";
} }
return $messages; return $messages;
} }
function cleanPath($path){
return rtrim(str_replace(["\\", ".php", "phar://", rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), "/"), rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH), "/")], ["/", "", "", "", ""], $path), "/");
}
function error_handler($errno, $errstr, $errfile, $errline){ function error_handler($errno, $errstr, $errfile, $errline){
global $lastError; global $lastError;
if(error_reporting() === 0){ //@ error-control if(error_reporting() === 0){ //@ error-control
@ -228,7 +232,7 @@ namespace pocketmine {
} }
$logger = MainLogger::getLogger(); $logger = MainLogger::getLogger();
$oldFile = $errfile; $oldFile = $errfile;
$errfile = str_replace(["\\", ".php", "phar://", rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), "/"), rtrim(str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH), "/")], ["/", "", "", "", ""], $errfile); $errfile = cleanPath($errfile);
$logger->log($type, "An $errno error happened: \"$errstr\" in \"$errfile\" at line $errline"); $logger->log($type, "An $errno error happened: \"$errstr\" in \"$errfile\" at line $errline");
foreach(($trace = getTrace(3)) as $i => $line){ foreach(($trace = getTrace(3)) as $i => $line){
$logger->debug($line); $logger->debug($line);

View File

@ -1486,6 +1486,10 @@ class Server{
$this->pluginManager->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this->consoleSender); $this->pluginManager->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this->consoleSender);
$this->pluginManager->setUseTimings($this->getProperty("settings.enable-profiling", false)); $this->pluginManager->setUseTimings($this->getProperty("settings.enable-profiling", false));
$this->pluginManager->registerInterface("pocketmine\\plugin\\PharPluginLoader"); $this->pluginManager->registerInterface("pocketmine\\plugin\\PharPluginLoader");
register_shutdown_function(array($this, "crashDump"));
register_shutdown_function(array($this, "forceShutdown"));
$this->pluginManager->loadPlugins($this->pluginPath); $this->pluginManager->loadPlugins($this->pluginPath);
$this->updater = new AutoUpdater($this, $this->getProperty("auto-updater.host", "www.pocketmine.net")); $this->updater = new AutoUpdater($this, $this->getProperty("auto-updater.host", "www.pocketmine.net"));
@ -1709,7 +1713,10 @@ class Server{
foreach($this->getLevels() as $level){ foreach($this->getLevels() as $level){
$this->unloadLevel($level, true); $this->unloadLevel($level, true);
} }
$this->generationManager->shutdown();
if($this->generationManager instanceof GenerationRequestManager){
$this->generationManager->shutdown();
}
HandlerList::unregisterAll(); HandlerList::unregisterAll();
$this->scheduler->cancelAllTasks(); $this->scheduler->cancelAllTasks();
@ -1747,8 +1754,6 @@ class Server{
$this->tickCounter = 0; $this->tickCounter = 0;
register_shutdown_function(array($this, "crashDump"));
register_shutdown_function(array($this, "forceShutdown"));
if(function_exists("pcntl_signal")){ if(function_exists("pcntl_signal")){
pcntl_signal(SIGTERM, array($this, "shutdown")); pcntl_signal(SIGTERM, array($this, "shutdown"));
pcntl_signal(SIGINT, array($this, "shutdown")); pcntl_signal(SIGINT, array($this, "shutdown"));
@ -1780,7 +1785,6 @@ class Server{
} }
public function crashDump(){ public function crashDump(){
if($this->isRunning === false){ if($this->isRunning === false){
return; return;
} }