diff --git a/src/pocketmine/CrashDump.php b/src/pocketmine/CrashDump.php index 9454d4466..72833cef8 100644 --- a/src/pocketmine/CrashDump.php +++ b/src/pocketmine/CrashDump.php @@ -159,7 +159,7 @@ class CrashDump{ $error = $lastExceptionError; }else{ $error = (array) error_get_last(); - $error["trace"] = Utils::getTrace(4); //Skipping CrashDump->baseCrash, CrashDump->construct, Server->crashDump + $error["trace"] = Utils::printableCurrentTrace(3); //Skipping CrashDump->baseCrash, CrashDump->construct, Server->crashDump $errorConversion = [ E_ERROR => "E_ERROR", E_WARNING => "E_WARNING", diff --git a/src/pocketmine/Server.php b/src/pocketmine/Server.php index 031c10c62..1de1a99a8 100644 --- a/src/pocketmine/Server.php +++ b/src/pocketmine/Server.php @@ -2206,7 +2206,7 @@ class Server{ "fullFile" => $e->getFile(), "file" => $errfile, "line" => $errline, - "trace" => Utils::getTrace(0, $trace) + "trace" => Utils::printableTrace($trace) ]; global $lastExceptionError, $lastError; diff --git a/src/pocketmine/network/mcpe/protocol/LoginPacket.php b/src/pocketmine/network/mcpe/protocol/LoginPacket.php index 3a801b8e9..a8beb83dc 100644 --- a/src/pocketmine/network/mcpe/protocol/LoginPacket.php +++ b/src/pocketmine/network/mcpe/protocol/LoginPacket.php @@ -90,7 +90,7 @@ class LoginPacket extends DataPacket{ $logger = \GlobalLogger::get(); $logger->debug(get_class($e) . " was thrown while decoding connection request in login (protocol version " . ($this->protocol ?? "unknown") . "): " . $e->getMessage()); - foreach(Utils::getTrace(0, $e->getTrace()) as $line){ + foreach(Utils::printableTrace($e->getTrace()) as $line){ $logger->debug($line); } } diff --git a/src/pocketmine/utils/MainLogger.php b/src/pocketmine/utils/MainLogger.php index 388faabf8..3f5e0f3f6 100644 --- a/src/pocketmine/utils/MainLogger.php +++ b/src/pocketmine/utils/MainLogger.php @@ -210,7 +210,7 @@ class MainLogger extends \AttachableThreadedLogger{ $errfile = Utils::cleanPath($errfile); $message = get_class($e) . ": \"$errstr\" ($errno) in \"$errfile\" at line $errline"; - $stack = Utils::getTrace(0, $trace); + $stack = Utils::printableTrace($trace); $this->synchronized(function() use ($type, $message, $stack) : void{ $this->log($type, $message); diff --git a/src/pocketmine/utils/Utils.php b/src/pocketmine/utils/Utils.php index bd13a3c6d..03d08da6b 100644 --- a/src/pocketmine/utils/Utils.php +++ b/src/pocketmine/utils/Utils.php @@ -461,24 +461,13 @@ class Utils{ } /** - * @param int $start - * @param array|null $trace + * @param array $trace * * @return array */ - public static function getTrace($start = 0, $trace = null){ - if($trace === null){ - if(function_exists("xdebug_get_function_stack")){ - $trace = array_reverse(xdebug_get_function_stack()); - }else{ - $e = new \Exception(); - $trace = $e->getTrace(); - } - } - + public static function printableTrace(array $trace) : array{ $messages = []; - $j = 0; - for($i = (int) $start; isset($trace[$i]); ++$i, ++$j){ + for($i = 0; isset($trace[$i]); ++$i){ $params = ""; if(isset($trace[$i]["args"]) or isset($trace[$i]["params"])){ if(isset($trace[$i]["args"])){ @@ -491,12 +480,39 @@ class Utils{ return (is_object($value) ? get_class($value) . " object" : gettype($value) . " " . (is_array($value) ? "Array()" : Utils::printable(@strval($value)))); }, $args)); } - $messages[] = "#$j " . (isset($trace[$i]["file"]) ? self::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"] . "(" . Utils::printable($params) . ")"; + $messages[] = "#$i " . (isset($trace[$i]["file"]) ? self::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"] . "(" . Utils::printable($params) . ")"; } - return $messages; } + /** + * @param int $skipFrames + * + * @return array + */ + public static function currentTrace(int $skipFrames = 0) : array{ + ++$skipFrames; //omit this frame from trace, in addition to other skipped frames + if(function_exists("xdebug_get_function_stack")){ + $trace = array_reverse(xdebug_get_function_stack()); + }else{ + $e = new \Exception(); + $trace = $e->getTrace(); + } + for($i = 0; $i < $skipFrames; ++$i){ + unset($trace[$i]); + } + return array_values($trace); + } + + /** + * @param int $skipFrames + * + * @return array + */ + public static function printableCurrentTrace(int $skipFrames = 0) : array{ + return self::printableTrace(self::currentTrace(++$skipFrames)); + } + public static function cleanPath($path){ return str_replace(["\\", ".php", "phar://", str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PATH), str_replace(["\\", "phar://"], ["/", ""], \pocketmine\PLUGIN_PATH)], ["/", "", "", "", ""], $path); }