Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c14fff0

Browse files
committed
minor #19656 [FrameworkBundle][Debug] Fix default config and cleaning of traces (nicolas-grekas)
This PR was merged into the 3.2-dev branch. Discussion ---------- [FrameworkBundle][Debug] Fix default config and cleaning of traces | Q | A | ------------- | --- | Branch? | master | Bug fix? | yes | Tests pass? | yes | Fixed tickets | Follow up #19568 | License | MIT | Doc PR | - The default value of `framework.php_errors.log` must be `%kernel.debug%` to have deprecations and silenced errors logged in dev as before. Cleaning the trace was broken because a closure can't be bound to an internal class. This PR fixes both issues and enhance trace cleaning a bit by removing arguments from traces so that they take less memory when collected as part of the context of log messages. Commits ------- f640870 [FrameworkBundle][Debug] Fix default config and cleaning of traces
2 parents d64bcda + f640870 commit c14fff0

File tree

5 files changed

+39
-29
lines changed

5 files changed

+39
-29
lines changed

UPGRADE-4.0.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,6 @@ FrameworkBundle
121121
* The `Controller::getUser()` method has been removed in favor of the ability
122122
to typehint the security user object in the action.
123123

124-
* The default value of the `framework.php_errors.log` configuration key is set to true.
125-
126124
HttpKernel
127125
----------
128126

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -704,8 +704,8 @@ private function addPhpErrorsSection(ArrayNodeDefinition $rootNode)
704704
->children()
705705
->booleanNode('log')
706706
->info('Use the app logger instead of the PHP logger for logging PHP errors.')
707-
->defaultValue(false)
708-
->treatNullLike(false)
707+
->defaultValue($this->debug)
708+
->treatNullLike($this->debug)
709709
->end()
710710
->booleanNode('throw')
711711
->info('Throw PHP errors as \ErrorException instances.')

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ protected static function getBundleDefaultConfig()
275275
),
276276
'workflows' => array(),
277277
'php_errors' => array(
278-
'log' => false,
278+
'log' => true,
279279
'throw' => true,
280280
),
281281
);

src/Symfony/Component/Debug/ErrorHandler.php

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ class ErrorHandler
8989
private $tracedErrors = 0x77FB; // E_ALL - E_STRICT - E_PARSE
9090
private $screamedErrors = 0x55; // E_ERROR + E_CORE_ERROR + E_COMPILE_ERROR + E_PARSE
9191
private $loggedErrors = 0;
92+
private $traceReflector;
9293

9394
private $isRecursive = 0;
9495
private $isRoot = false;
@@ -147,6 +148,8 @@ public function __construct(BufferingLogger $bootstrappingLogger = null)
147148
$this->bootstrappingLogger = $bootstrappingLogger;
148149
$this->setDefaultLogger($bootstrappingLogger);
149150
}
151+
$this->traceReflector = new \ReflectionProperty('Exception', 'trace');
152+
$this->traceReflector->setAccessible(true);
150153
}
151154

152155
/**
@@ -389,16 +392,37 @@ public function handleError($type, $message, $file, $line, array $context, array
389392
self::$toStringException = null;
390393
} elseif (!$throw && !($type & $level)) {
391394
$errorAsException = new SilencedErrorContext($type, $file, $line);
392-
} elseif ($this->scopedErrors & $type) {
393-
$errorAsException = new ContextErrorException($logMessage, 0, $type, $file, $line, $context);
394395
} else {
395-
$errorAsException = new \ErrorException($logMessage, 0, $type, $file, $line);
396+
if ($this->scopedErrors & $type) {
397+
$errorAsException = new ContextErrorException($logMessage, 0, $type, $file, $line, $context);
398+
} else {
399+
$errorAsException = new \ErrorException($logMessage, 0, $type, $file, $line);
400+
}
401+
402+
// Clean the trace by removing function arguments and the first frames added by the error handler itself.
403+
if ($throw || $this->tracedErrors & $type) {
404+
$backtrace = $backtrace ?: $errorAsException->getTrace();
405+
$lightTrace = $backtrace;
406+
407+
for ($i = 0; isset($backtrace[$i]); ++$i) {
408+
if (isset($backtrace[$i]['file'], $backtrace[$i]['line']) && $backtrace[$i]['line'] === $line && $backtrace[$i]['file'] === $file) {
409+
$lightTrace = array_slice($lightTrace, 1 + $i);
410+
break;
411+
}
412+
}
413+
if (!($throw || $this->scopedErrors & $type)) {
414+
for ($i = 0; isset($lightTrace[$i]); ++$i) {
415+
unset($lightTrace[$i]['args']);
416+
}
417+
}
418+
$this->traceReflector->setValue($errorAsException, $lightTrace);
419+
} else {
420+
$this->traceReflector->setValue($errorAsException, array());
421+
}
396422
}
397423

398424
if ($throw) {
399425
if (E_USER_ERROR & $type) {
400-
$backtrace = $backtrace ?: $errorAsException->getTrace();
401-
402426
for ($i = 1; isset($backtrace[$i]); ++$i) {
403427
if (isset($backtrace[$i]['function'], $backtrace[$i]['type'], $backtrace[$i - 1]['function'])
404428
&& '__toString' === $backtrace[$i]['function']
@@ -440,14 +464,6 @@ public function handleError($type, $message, $file, $line, array $context, array
440464
throw $errorAsException;
441465
}
442466

443-
if (!($this->tracedErrors & $type) && $errorAsException instanceof \Exception) {
444-
static $freeTrace = null;
445-
if (null === $freeTrace) {
446-
$freeTrace = \Closure::bind(function ($e) { $e->trace = array(); }, null, \Exception::class);
447-
}
448-
$freeTrace($errorAsException);
449-
}
450-
451467
if ($this->isRecursive) {
452468
$log = 0;
453469
} elseif (self::$stackedErrorLevels) {

src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,20 +80,16 @@ public function testNotice()
8080
$this->assertArrayHasKey('foobar', $exception->getContext());
8181

8282
$trace = $exception->getTrace();
83+
8384
$this->assertEquals(__FILE__, $trace[0]['file']);
84-
$this->assertEquals('Symfony\Component\Debug\ErrorHandler', $trace[0]['class']);
85-
$this->assertEquals('handleError', $trace[0]['function']);
86-
$this->assertEquals('->', $trace[0]['type']);
85+
$this->assertEquals(__CLASS__, $trace[0]['class']);
86+
$this->assertEquals('triggerNotice', $trace[0]['function']);
87+
$this->assertEquals('::', $trace[0]['type']);
8788

88-
$this->assertEquals(__FILE__, $trace[1]['file']);
89+
$this->assertEquals(__FILE__, $trace[0]['file']);
8990
$this->assertEquals(__CLASS__, $trace[1]['class']);
90-
$this->assertEquals('triggerNotice', $trace[1]['function']);
91-
$this->assertEquals('::', $trace[1]['type']);
92-
93-
$this->assertEquals(__FILE__, $trace[1]['file']);
94-
$this->assertEquals(__CLASS__, $trace[2]['class']);
95-
$this->assertEquals(__FUNCTION__, $trace[2]['function']);
96-
$this->assertEquals('->', $trace[2]['type']);
91+
$this->assertEquals(__FUNCTION__, $trace[1]['function']);
92+
$this->assertEquals('->', $trace[1]['type']);
9793
} finally {
9894
restore_error_handler();
9995
restore_exception_handler();

0 commit comments

Comments
 (0)