Skip to content

Commit cebe433

Browse files
committed
Adds possibility to include called object in exception backtrace
1 parent dcc4b0f commit cebe433

File tree

6 files changed

+194
-5
lines changed

6 files changed

+194
-5
lines changed
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
--TEST--
2+
Exceptions providing object
3+
--FILE--
4+
<?php
5+
6+
class Test {
7+
public $random;
8+
9+
function __construct() {
10+
$this->random = random_int(0, 100);
11+
}
12+
13+
function doThrow(...$args) {
14+
throw new Exception();
15+
}
16+
17+
function funcDoThrow() {
18+
return fn(...$args) => $this->doThrow(...$args);
19+
}
20+
}
21+
22+
function doThrow(...$args) {
23+
(new Test())->funcDoThrow()(...$args);
24+
}
25+
26+
echo "zend.exception_ignore_args=0\n";
27+
echo "zend.exception_provide_object=1\n";
28+
ini_set("zend.exception_ignore_args", 0);
29+
ini_set("zend.exception_provide_object", 1);
30+
31+
try {
32+
doThrow("foo", "bar");
33+
} catch (Exception $e) {
34+
var_dump($e->getTrace());
35+
}
36+
37+
echo "zend.exception_ignore_args=1\n";
38+
echo "zend.exception_provide_object=0\n";
39+
ini_set("zend.exception_ignore_args", 1);
40+
ini_set("zend.exception_provide_object", 0);
41+
42+
try {
43+
doThrow("foo", "bar");
44+
} catch (Exception $e) {
45+
var_dump($e->getTrace());
46+
}
47+
48+
?>
49+
--EXPECTF--
50+
zend.exception_ignore_args=0
51+
zend.exception_provide_object=1
52+
array(3) {
53+
[0]=>
54+
array(7) {
55+
["file"]=>
56+
string(%d) "%sexception_provide_object.php"
57+
["line"]=>
58+
int(%d)
59+
["function"]=>
60+
string(7) "doThrow"
61+
["class"]=>
62+
string(4) "Test"
63+
["object"]=>
64+
object(Test)#%d (%d) {
65+
["random"]=>
66+
int(%d)
67+
}
68+
["type"]=>
69+
string(2) "->"
70+
["args"]=>
71+
array(2) {
72+
[0]=>
73+
string(3) "foo"
74+
[1]=>
75+
string(3) "bar"
76+
}
77+
}
78+
[1]=>
79+
array(7) {
80+
["file"]=>
81+
string(%d) "%sexception_provide_object.php"
82+
["line"]=>
83+
int(%d)
84+
["function"]=>
85+
string(%d) "{closure:Test::funcDoThrow():%d}"
86+
["class"]=>
87+
string(4) "Test"
88+
["object"]=>
89+
object(Test)#%d (%d) {
90+
["random"]=>
91+
int(%d)
92+
}
93+
["type"]=>
94+
string(2) "->"
95+
["args"]=>
96+
array(2) {
97+
[0]=>
98+
string(3) "foo"
99+
[1]=>
100+
string(3) "bar"
101+
}
102+
}
103+
[2]=>
104+
array(4) {
105+
["file"]=>
106+
string(%d) "%sexception_provide_object.php"
107+
["line"]=>
108+
int(%d)
109+
["function"]=>
110+
string(7) "doThrow"
111+
["args"]=>
112+
array(2) {
113+
[0]=>
114+
string(3) "foo"
115+
[1]=>
116+
string(3) "bar"
117+
}
118+
}
119+
}
120+
zend.exception_ignore_args=1
121+
zend.exception_provide_object=0
122+
array(3) {
123+
[0]=>
124+
array(5) {
125+
["file"]=>
126+
string(%d) "%sexception_provide_object.php"
127+
["line"]=>
128+
int(%d)
129+
["function"]=>
130+
string(7) "doThrow"
131+
["class"]=>
132+
string(4) "Test"
133+
["type"]=>
134+
string(2) "->"
135+
}
136+
[1]=>
137+
array(5) {
138+
["file"]=>
139+
string(%d) "%sexception_provide_object.php"
140+
["line"]=>
141+
int(%d)
142+
["function"]=>
143+
string(%d) "{closure:Test::funcDoThrow():%d}"
144+
["class"]=>
145+
string(4) "Test"
146+
["type"]=>
147+
string(2) "->"
148+
}
149+
[2]=>
150+
array(3) {
151+
["file"]=>
152+
string(%d) "%sexception_provide_object.php"
153+
["line"]=>
154+
int(%d)
155+
["function"]=>
156+
string(7) "doThrow"
157+
}
158+
}

Zend/zend.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ ZEND_INI_BEGIN()
270270
STD_ZEND_INI_BOOLEAN("zend.signal_check", SIGNAL_CHECK_DEFAULT, ZEND_INI_SYSTEM, OnUpdateBool, check, zend_signal_globals_t, zend_signal_globals)
271271
#endif
272272
STD_ZEND_INI_BOOLEAN("zend.exception_ignore_args", "0", ZEND_INI_ALL, OnUpdateBool, exception_ignore_args, zend_executor_globals, executor_globals)
273+
STD_ZEND_INI_BOOLEAN("zend.exception_provide_object", "0", ZEND_INI_ALL, OnUpdateBool, exception_provide_object, zend_executor_globals, executor_globals)
273274
STD_ZEND_INI_ENTRY("zend.exception_string_param_max_len", "15", ZEND_INI_ALL, OnSetExceptionStringParamMaxLen, exception_string_param_max_len, zend_executor_globals, executor_globals)
274275
STD_ZEND_INI_ENTRY("fiber.stack_size", NULL, ZEND_INI_ALL, OnUpdateFiberStackSize, fiber_stack_size, zend_executor_globals, executor_globals)
275276
#ifdef ZEND_CHECK_STACK_LIMIT

Zend/zend_exceptions.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,14 +290,19 @@ static zend_object *zend_default_exception_new(zend_class_entry *class_type) /*
290290
zval tmp;
291291
zval trace;
292292
zend_string *filename;
293+
int options = 0;
293294

294295
zend_object *object = zend_objects_new(class_type);
295296
object_properties_init(object, class_type);
296297

297298
if (EG(current_execute_data)) {
298-
zend_fetch_debug_backtrace(&trace,
299-
0,
300-
EG(exception_ignore_args) ? DEBUG_BACKTRACE_IGNORE_ARGS : 0, 0);
299+
if (EG(exception_ignore_args)) {
300+
options |= DEBUG_BACKTRACE_IGNORE_ARGS;
301+
}
302+
if (EG(exception_provide_object)) {
303+
options |= DEBUG_BACKTRACE_PROVIDE_OBJECT;
304+
}
305+
zend_fetch_debug_backtrace(&trace, 0, options, 0);
301306
} else {
302307
ZVAL_EMPTY_ARRAY(&trace);
303308
}

Zend/zend_globals.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ struct _zend_executor_globals {
235235

236236
int user_error_handler_error_reporting;
237237
bool exception_ignore_args;
238+
bool exception_provide_object;
238239
zval user_error_handler;
239240
zval user_exception_handler;
240241
zend_stack user_error_handlers_error_reporting;

php.ini-development

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,12 +367,24 @@ zend.enable_gc = On
367367

368368
; Allows to include or exclude arguments from stack traces generated for exceptions.
369369
; In production, it is recommended to turn this setting on to prohibit the output
370-
; of sensitive information in stack traces
370+
; of sensitive information in stack traces.
371+
; Note: This increases the refcount of the objects in arguments, and therefore delays
372+
; object destruction until all references have been destroyed.
371373
; Default Value: Off
372374
; Development Value: Off
373375
; Production Value: On
374376
zend.exception_ignore_args = Off
375377

378+
; Allows to include or exclude called object from stack traces generated for exceptions.
379+
; In production, it is recommended to turn this setting off to prohibit the output
380+
; of sensitive information in stack traces.
381+
; Note: This increases the refcount of the objects, and therefore delays object
382+
; destruction until all references have been destroyed.
383+
; Default Value: Off
384+
; Development Value: On
385+
; Production Value: Off
386+
zend.exception_provide_object = On
387+
376388
; Allows setting the maximum string length in an argument of a stringified stack trace
377389
; to a value between 0 and 1000000.
378390
; This has no effect when zend.exception_ignore_args is enabled.

php.ini-production

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,12 +367,24 @@ zend.enable_gc = On
367367

368368
; Allows to include or exclude arguments from stack traces generated for exceptions.
369369
; In production, it is recommended to turn this setting on to prohibit the output
370-
; of sensitive information in stack traces
370+
; of sensitive information in stack traces.
371+
; Note: This increases the refcount of the objects in arguments, and therefore delays
372+
; object destruction until all references have been destroyed.
371373
; Default Value: Off
372374
; Development Value: Off
373375
; Production Value: On
374376
zend.exception_ignore_args = On
375377

378+
; Allows to include or exclude called object from stack traces generated for exceptions.
379+
; In production, it is recommended to turn this setting off to prohibit the output
380+
; of sensitive information in stack traces.
381+
; Note: This increases the refcount of the objects, and therefore delays object
382+
; destruction until all references have been destroyed.
383+
; Default Value: Off
384+
; Development Value: On
385+
; Production Value: Off
386+
zend.exception_provide_object = Off
387+
376388
; Allows setting the maximum string length in an argument of a stringified stack trace
377389
; to a value between 0 and 1000000.
378390
; This has no effect when zend.exception_ignore_args is enabled.

0 commit comments

Comments
 (0)