mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-11-04 06:37:55 +08:00 
			
		
		
		
	Fix #18477: Fix detecting availability of Xdebug's stack trace in yii\base\ErrorException
				
					
				
			This commit is contained in:
		@ -10,6 +10,7 @@ Yii Framework 2 Change Log
 | 
				
			|||||||
- Bug #18464: Fix bug with processing fallback messages when translation language is set to `null` (bizley)
 | 
					- Bug #18464: Fix bug with processing fallback messages when translation language is set to `null` (bizley)
 | 
				
			||||||
- Enh #18457: Add `EVENT_RESET` and `EVENT_FINISH` events to `yii\db\BatchQueryResult` (brandonkelly)
 | 
					- Enh #18457: Add `EVENT_RESET` and `EVENT_FINISH` events to `yii\db\BatchQueryResult` (brandonkelly)
 | 
				
			||||||
- Bug #18472: Fix initializing `db` component configuration in `yii\data\ActiveDataProvider` (bizley)
 | 
					- Bug #18472: Fix initializing `db` component configuration in `yii\data\ActiveDataProvider` (bizley)
 | 
				
			||||||
 | 
					- Bug #18477: Fix detecting availability of Xdebug's stack trace in `yii\base\ErrorException` (bizley)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
2.0.40 December 23, 2020
 | 
					2.0.40 December 23, 2020
 | 
				
			||||||
 | 
				
			|||||||
@ -44,24 +44,24 @@ class ErrorException extends \ErrorException
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        parent::__construct($message, $code, $severity, $filename, $lineno, $previous);
 | 
					        parent::__construct($message, $code, $severity, $filename, $lineno, $previous);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (function_exists('xdebug_get_function_stack')) {
 | 
					        if ($this->isXdebugStackAvailable()) {
 | 
				
			||||||
            // XDebug trace can't be modified and used directly with PHP 7
 | 
					            // Xdebug trace can't be modified and used directly with PHP 7
 | 
				
			||||||
            // @see https://github.com/yiisoft/yii2/pull/11723
 | 
					            // @see https://github.com/yiisoft/yii2/pull/11723
 | 
				
			||||||
            $xDebugTrace = array_slice(array_reverse(xdebug_get_function_stack()), 1, -1);
 | 
					            $xdebugTrace = array_slice(array_reverse(xdebug_get_function_stack()), 1, -1);
 | 
				
			||||||
            $trace = [];
 | 
					            $trace = [];
 | 
				
			||||||
            foreach ($xDebugTrace as $frame) {
 | 
					            foreach ($xdebugTrace as $frame) {
 | 
				
			||||||
                if (!isset($frame['function'])) {
 | 
					                if (!isset($frame['function'])) {
 | 
				
			||||||
                    $frame['function'] = 'unknown';
 | 
					                    $frame['function'] = 'unknown';
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // XDebug < 2.1.1: http://bugs.xdebug.org/view.php?id=695
 | 
					                // Xdebug < 2.1.1: http://bugs.xdebug.org/view.php?id=695
 | 
				
			||||||
                if (!isset($frame['type']) || $frame['type'] === 'static') {
 | 
					                if (!isset($frame['type']) || $frame['type'] === 'static') {
 | 
				
			||||||
                    $frame['type'] = '::';
 | 
					                    $frame['type'] = '::';
 | 
				
			||||||
                } elseif ($frame['type'] === 'dynamic') {
 | 
					                } elseif ($frame['type'] === 'dynamic') {
 | 
				
			||||||
                    $frame['type'] = '->';
 | 
					                    $frame['type'] = '->';
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // XDebug has a different key name
 | 
					                // Xdebug has a different key name
 | 
				
			||||||
                if (isset($frame['params']) && !isset($frame['args'])) {
 | 
					                if (isset($frame['params']) && !isset($frame['args'])) {
 | 
				
			||||||
                    $frame['args'] = $frame['params'];
 | 
					                    $frame['args'] = $frame['params'];
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -74,6 +74,32 @@ class ErrorException extends \ErrorException
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Ensures that Xdebug stack trace is available based on Xdebug version.
 | 
				
			||||||
 | 
					     * Idea taken from developer bishopb at https://github.com/rollbar/rollbar-php
 | 
				
			||||||
 | 
					     * @return bool
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private function isXdebugStackAvailable()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!function_exists('xdebug_get_function_stack')) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // check for Xdebug being installed to ensure origin of xdebug_get_function_stack()
 | 
				
			||||||
 | 
					        $version = phpversion('xdebug');
 | 
				
			||||||
 | 
					        if ($version === false) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Xdebug 2 and prior
 | 
				
			||||||
 | 
					        if (version_compare($version, '3.0.0', '<')) {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Xdebug 3 and later, proper mode is required
 | 
				
			||||||
 | 
					        return false !== strpos(ini_get('xdebug.mode'), 'develop');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Returns if error is one of fatal type.
 | 
					     * Returns if error is one of fatal type.
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
 | 
				
			|||||||
@ -15,10 +15,25 @@ use yiiunit\TestCase;
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
class ErrorExceptionTest extends TestCase
 | 
					class ErrorExceptionTest extends TestCase
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public function testXdebugTrace()
 | 
					    private function isXdebugStackAvailable()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (!function_exists('xdebug_get_function_stack')) {
 | 
					        if (!function_exists('xdebug_get_function_stack')) {
 | 
				
			||||||
            $this->markTestSkipped('Xdebug are required.');
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $version = phpversion('xdebug');
 | 
				
			||||||
 | 
					        if ($version === false) {
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (version_compare($version, '3.0.0', '<')) {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return false !== strpos(ini_get('xdebug.mode'), 'develop');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function testXdebugTrace()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!$this->isXdebugStackAvailable()) {
 | 
				
			||||||
 | 
					            $this->markTestSkipped('Xdebug is required.');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            throw new ErrorException();
 | 
					            throw new ErrorException();
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user