# [PATCH] Add an optional size limit to debug_backtrace

- Thread: https://externals.io/message/1812
- Original archive: https://news-web.php.net/php.internals/1812
- Started by David Brown on 2003-05-20T17:59:03+00:00
- Messages: 2
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #1812 — David Brown — 2003-05-20T17:59:03+00:00

URL: https://externals.io/message/1812#1812

Hi:

Attached is a patch that adds an optional 'limit' parameter to
debug_backtrace, which limits the size of the returned array. In cases
where a script wants debug information only for the current function, or
for the function <n> levels above that, we can save a lot of unnecessary
call-stack traversal and zval allocation by bailing out early. For a
sufficiently large call depth and a small <n>, I'd expect this to
improve performance quite a bit.

The patch adds a total of six lines to the function, and one test in the
main loop for the zero-argument case. Should apply cleanly to both PHP_4_3
and HEAD.

Is there any chance this could be applied? :)

Thanks in advance,

- Dave
  dave@codewhore.org


--- Zend/zend_builtin_functions.c~	2003-05-20 11:33:36.000000000 -0400
+++ Zend/zend_builtin_functions.c	2003-05-20 13:34:40.000000000 -0400
@@ -1173,7 +1173,7 @@
 	return arg_array;
 }
 
-/* {{{ proto void debug_backtrace(void)
+/* {{{ proto void debug_backtrace([int limit])
    Prints out a backtrace */
 ZEND_FUNCTION(debug_backtrace)
 {
@@ -1189,11 +1189,18 @@
 	void **args = cur_arg_pos;
 	int arg_stack_consistent = 0;
 	int frames_on_stack = 0;
+	zval **limit_zval = NULL;
+	long limit;
 
-	if (ZEND_NUM_ARGS()) {
+	if (ZEND_NUM_ARGS() > 1) {
 		ZEND_WRONG_PARAM_COUNT();
 	}
 
+	if (ZEND_NUM_ARGS() == 1 && zend_get_parameters_ex(1, &limit_zval) == SUCCESS) {
+		convert_to_long_ex(limit_zval);
+		limit = (*limit_zval)->value.lval;
+	}
+
 	while (--args >= EG(argument_stack).elements) {
 		if (*args--) {
 			break;
@@ -1217,6 +1224,9 @@
 	array_init(return_value);
 
 	while (ptr) {
+		if (limit_zval && --limit < 0)
+			break;
+
 		MAKE_STD_ZVAL(stack_frame);
 		array_init(stack_frame);

---

## #1821 — David Brown — 2003-05-20T19:34:10+00:00

URL: https://externals.io/message/1812#1821 · In reply to: #1812

| Hi:
| <patch>

Or, so as to not turn this into the Integer Overflow and Crappy C
Competition (IOCCC <grin>), perhaps this instead:

--- Zend/zend_builtin_functions.c~	2003-05-20 11:33:36.000000000 -0400
+++ Zend/zend_builtin_functions.c	2003-05-20 15:31:09.000000000 -0400
@@ -1173,7 +1173,7 @@
 	return arg_array;
 }
 
-/* {{{ proto void debug_backtrace(void)
+/* {{{ proto void debug_backtrace([int limit])
    Prints out a backtrace */
 ZEND_FUNCTION(debug_backtrace)
 {
@@ -1189,11 +1189,21 @@
 	void **args = cur_arg_pos;
 	int arg_stack_consistent = 0;
 	int frames_on_stack = 0;
+	zval **limit_zval = NULL;
+	long limit;
 
-	if (ZEND_NUM_ARGS()) {
+	if (ZEND_NUM_ARGS() > 1) {
 		ZEND_WRONG_PARAM_COUNT();
 	}
 
+	if (ZEND_NUM_ARGS() == 1 && zend_get_parameters_ex(1, &limit_zval) == SUCCESS) {
+		convert_to_long_ex(limit_zval);
+		if ((limit = (*limit_zval)->value.lval) <= 0) {
+			zend_error(E_WARNING, "Limit must be a non-zero positive integer");
+			return;
+		}
+	}
+
 	while (--args >= EG(argument_stack).elements) {
 		if (*args--) {
 			break;
@@ -1217,6 +1227,9 @@
 	array_init(return_value);
 
 	while (ptr) {
+		if (limit_zval && --limit < 0)
+			break;
+
 		MAKE_STD_ZVAL(stack_frame);
 		array_init(stack_frame);


Thanks,

- Dave
  dave@codewhore.org
