mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-07 02:08:21 +00:00
Allow thread errors and their traces to be properly recorded in crashdumps (#5910)
until now, any thread crash would show as a generic crash since we aren't able to get the trace from the crashed thread directly. This uses some dirty tricks to export a partially serialized stack trace to the main thread, where it can be written into a crashdump. This enables us to see proper crash information for async tasks in the crash archive (finally!!!) as well as being able to capture RakLib errors properly.
This commit is contained in:
@ -26,6 +26,7 @@ namespace pocketmine\scheduler;
|
||||
use pmmp\thread\Thread as NativeThread;
|
||||
use pocketmine\snooze\SleeperHandler;
|
||||
use pocketmine\thread\log\ThreadSafeLogger;
|
||||
use pocketmine\thread\ThreadCrashException;
|
||||
use pocketmine\thread\ThreadSafeClassLoader;
|
||||
use pocketmine\timings\Timings;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
@ -215,12 +216,17 @@ class AsyncPool{
|
||||
}
|
||||
}
|
||||
}
|
||||
if($crashedTask !== null){
|
||||
$message = "Worker $workerId crashed while running task " . get_class($crashedTask) . "#" . spl_object_id($crashedTask);
|
||||
$info = $entry->worker->getCrashInfo();
|
||||
if($info !== null){
|
||||
if($crashedTask !== null){
|
||||
$message = "Worker $workerId crashed while running task " . get_class($crashedTask) . "#" . spl_object_id($crashedTask);
|
||||
}else{
|
||||
$message = "Worker $workerId crashed while doing unknown work";
|
||||
}
|
||||
throw new ThreadCrashException($message, $info);
|
||||
}else{
|
||||
$message = "Worker $workerId crashed for unknown reason";
|
||||
throw new \RuntimeException("Worker $workerId crashed for unknown reason");
|
||||
}
|
||||
throw new \RuntimeException($message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,6 @@ use pocketmine\thread\Worker;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use function gc_enable;
|
||||
use function ini_set;
|
||||
use function set_exception_handler;
|
||||
|
||||
class AsyncWorker extends Worker{
|
||||
/** @var mixed[] */
|
||||
@ -68,20 +67,17 @@ class AsyncWorker extends Worker{
|
||||
}
|
||||
|
||||
$this->saveToThreadStore(self::TLS_KEY_NOTIFIER, $this->sleeperEntry->createNotifier());
|
||||
}
|
||||
|
||||
set_exception_handler(function(\Throwable $e){
|
||||
$this->logger->logException($e);
|
||||
});
|
||||
protected function onUncaughtException(\Throwable $e) : void{
|
||||
parent::onUncaughtException($e);
|
||||
$this->logger->logException($e);
|
||||
}
|
||||
|
||||
public function getLogger() : ThreadSafeLogger{
|
||||
return $this->logger;
|
||||
}
|
||||
|
||||
public function handleException(\Throwable $e) : void{
|
||||
$this->logger->logException($e);
|
||||
}
|
||||
|
||||
public function getThreadName() : string{
|
||||
return "AsyncWorker#" . $this->id;
|
||||
}
|
||||
|
Reference in New Issue
Block a user