Permalink
Browse files

Merged pull request #38

  • Loading branch information...
2 parents 49c9980 + e773605 commit e773b090fce4275aee5993fb72dadb72025aec78 @derickr committed Nov 24, 2012
Showing with 251 additions and 17 deletions.
  1. +37 −0 tests/array_map-php55.phpt
  2. +2 −0 tests/array_map.phpt
  3. +59 −0 tests/bug00905.phpt
  4. +65 −3 xdebug.c
  5. +4 −0 xdebug_private.h
  6. +34 −5 xdebug_stack.c
  7. +47 −9 xdebug_tracing.c
  8. +3 −0 xdebug_tracing.h
View
@@ -0,0 +1,37 @@
+--TEST--
+Test with internal callbacks
+--SKIPIF--
+<?php if (!version_compare(phpversion(), "5.5", '>=')) echo "skip >= PHP 5.5 needed\n"; ?>
+--INI--
+xdebug.default_enable=1
+xdebug.auto_trace=0
+xdebug.collect_params=3
+xdebug.collect_return=0
+xdebug.collect_assignments=0
+xdebug.auto_profile=0
+xdebug.profiler_enable=0
+xdebug.show_mem_delta=0
+xdebug.trace_format=0
+xdebug.var_display_max_depth=2
+xdebug.var_display_max_children=3
+--FILE--
+<?php
+$tf = xdebug_start_trace('/tmp/'. uniqid('xdt', TRUE));
+
+$ar = array('a', 'bb', 'ccc');
+$r = array_map('strlen', $ar);
+
+echo gettype($r), "\n";
+
+echo file_get_contents($tf);
+unlink($tf);
+?>
+--EXPECTF--
+array
+TRACE START [%d-%d-%d %d:%d:%d]
+%w%f %w%d -> array_map('strlen', array (0 => 'a', 1 => 'bb', 2 => 'ccc')) /%s/array_map-php55.php:5
+%w%f %w%d -> strlen('a') /%s/array_map-php55.php:5
+%w%f %w%d -> strlen('bb') /%s/array_map-php55.php:5
+%w%f %w%d -> strlen('ccc') /%s/array_map-php55.php:5
+%w%f %w%d -> gettype(array (0 => 1, 1 => 2, 2 => 3)) /%s/array_map-php55.php:7
+%w%f %w%d -> file_get_contents('/tmp/%s') /%s/array_map-php55.php:9
View
@@ -1,5 +1,7 @@
--TEST--
Test with internal callbacks
+--SKIPIF--
+<?php if (!version_compare(phpversion(), "5.5", '<')) echo "skip < PHP 5.5 needed\n"; ?>
--INI--
xdebug.default_enable=1
xdebug.auto_trace=0
View
@@ -0,0 +1,59 @@
+--TEST--
+Test for bug #905: Tracing for generators.
+--SKIPIF--
+<?php if (!version_compare(phpversion(), "5.5", '>=')) echo "skip >= PHP 5.5 needed\n"; ?>
+--INI--
+xdebug.enable=1
+xdebug.auto_trace=0
+xdebug.collect_params=3
+xdebug.collect_return=1
+xdebug.collect_assignments=0
+xdebug.auto_profile=0
+xdebug.profiler_enable=0
+xdebug.show_mem_delta=0
+xdebug.trace_format=0
+--FILE--
+<?php
+$tf = xdebug_start_trace('/tmp/'. uniqid('xdt', TRUE));
+
+function gen() {
+ yield 'a';
+ yield 'b';
+ yield 'key' => 'c';
+ yield 'd';
+ yield 10 => 'e';
+ yield 'f';
+}
+
+foreach (gen() as $key => $value) {
+ echo $key, ' => ', $value, "\n";
+}
+
+xdebug_stop_trace();
+echo file_get_contents($tf);
+unlink($tf);
+?>
+--EXPECTF--
+0 => a
+1 => b
+key => c
+2 => d
+10 => e
+11 => f
+TRACE START [%d-%d-%d %d:%d:%d]
+%w%f %w%d -> gen() %sbug00905.php:13
+ >=> (0 => 'a')
+%w%f %w%d -> gen() %sbug00905.php:13
+ >=> (1 => 'b')
+%w%f %w%d -> gen() %sbug00905.php:13
+ >=> ('key' => 'c')
+%w%f %w%d -> gen() %sbug00905.php:13
+ >=> (2 => 'd')
+%w%f %w%d -> gen() %sbug00905.php:13
+ >=> (10 => 'e')
+%w%f %w%d -> gen() %sbug00905.php:13
+ >=> (11 => 'f')
+%w%f %w%d -> gen() %sbug00905.php:13
+%w%f %w%d -> xdebug_stop_trace() %sbug00905.php:17
+%w%f %w%d
+TRACE END [%d-%d-%d %d:%d:%d]
View
@@ -65,11 +65,19 @@
zend_op_array* (*old_compile_file)(zend_file_handle* file_handle, int type TSRMLS_DC);
zend_op_array* xdebug_compile_file(zend_file_handle*, int TSRMLS_DC);
+#if PHP_VERSION_ID < 50500
void (*xdebug_old_execute)(zend_op_array *op_array TSRMLS_DC);
void xdebug_execute(zend_op_array *op_array TSRMLS_DC);
void (*xdebug_old_execute_internal)(zend_execute_data *current_execute_data, int return_value_used TSRMLS_DC);
void xdebug_execute_internal(zend_execute_data *current_execute_data, int return_value_used TSRMLS_DC);
+#else
+void (*xdebug_old_execute_ex)(zend_execute_data *execute_data TSRMLS_DC);
+void xdebug_execute_ex(zend_execute_data *execute_data TSRMLS_DC);
+
+void (*xdebug_old_execute_internal)(zend_execute_data *current_execute_data, struct _zend_fcall_info *fci, int return_value_used TSRMLS_DC);
+void xdebug_execute_internal(zend_execute_data *current_execute_data, struct _zend_fcall_info *fci, int return_value_used TSRMLS_DC);
+#endif
/* error callback replacement functions */
void (*xdebug_old_error_cb)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);
@@ -561,8 +569,13 @@ PHP_MINIT_FUNCTION(xdebug)
old_compile_file = zend_compile_file;
zend_compile_file = xdebug_compile_file;
+#if PHP_VERSION_ID < 50500
xdebug_old_execute = zend_execute;
zend_execute = xdebug_execute;
+#else
+ xdebug_old_execute_ex = zend_execute_ex;
+ zend_execute_ex = xdebug_execute_ex;
+#endif
xdebug_old_execute_internal = zend_execute_internal;
zend_execute_internal = xdebug_execute_internal;
@@ -700,7 +713,11 @@ PHP_MSHUTDOWN_FUNCTION(xdebug)
/* Reset compile, execute and error callbacks */
zend_compile_file = old_compile_file;
+#if PHP_VERSION_ID < 50500
zend_execute = xdebug_old_execute;
+#else
+ zend_execute_ex = xdebug_old_execute_ex;
+#endif
zend_execute_internal = xdebug_old_execute_internal;
zend_error_cb = xdebug_old_error_cb;
@@ -1216,10 +1233,17 @@ static int handle_breakpoints(function_stack_entry *fse, int breakpoint_type)
return 1;
}
+#if PHP_VERSION_ID < 50500
void xdebug_execute(zend_op_array *op_array TSRMLS_DC)
{
- zval **dummy;
zend_execute_data *edata = EG(current_execute_data);
+#else
+void xdebug_execute_ex(zend_execute_data *execute_data TSRMLS_DC)
+{
+ zend_op_array *op_array = execute_data->op_array;
+ zend_execute_data *edata = execute_data->prev_execute_data;
+#endif
+ zval **dummy;
function_stack_entry *fse, *xfse;
char *magic_cookie = NULL;
int do_return = (XG(do_trace) && XG(trace_file));
@@ -1230,14 +1254,22 @@ void xdebug_execute(zend_op_array *op_array TSRMLS_DC)
/* If we're evaluating for the debugger's eval capability, just bail out */
if (op_array && op_array->filename && strcmp("xdebug://debug-eval", op_array->filename) == 0) {
+#if PHP_VERSION_ID < 50500
xdebug_old_execute(op_array TSRMLS_CC);
+#else
+ xdebug_old_execute_ex(execute_data TSRMLS_CC);
+#endif
return;
}
/* if we're in a ZEND_EXT_STMT, we ignore this function call as it's likely
that it's just being called to check for breakpoints with conditions */
if (edata && edata->opline && edata->opline->opcode == ZEND_EXT_STMT) {
+#if PHP_VERSION_ID < 50500
xdebug_old_execute(op_array TSRMLS_CC);
+#else
+ xdebug_old_execute_ex(execute_data TSRMLS_CC);
+#endif
return;
}
@@ -1347,7 +1379,11 @@ void xdebug_execute(zend_op_array *op_array TSRMLS_DC)
xdebug_trace_function_begin(fse, function_nr TSRMLS_CC);
fse->symbol_table = EG(active_symbol_table);
+#if PHP_VERSION_ID < 50500
fse->execute_data = EG(current_execute_data);
+#else
+ fse->execute_data = EG(current_execute_data)->prev_execute_data;
+#endif
fse->This = EG(This);
if (XG(remote_enabled) || XG(collect_vars) || XG(show_local_vars)) {
@@ -1392,7 +1428,12 @@ void xdebug_execute(zend_op_array *op_array TSRMLS_DC)
EG(return_value_ptr_ptr) = &return_val;
clear = 1;
}
+
+#if PHP_VERSION_ID < 50500
xdebug_old_execute(op_array TSRMLS_CC);
+#else
+ xdebug_old_execute_ex(execute_data TSRMLS_CC);
+#endif
if (XG(profiler_enabled)) {
xdebug_profiler_function_user_end(fse, op_array TSRMLS_CC);
@@ -1403,7 +1444,16 @@ void xdebug_execute(zend_op_array *op_array TSRMLS_DC)
/* Store return value in the trace file */
if (XG(collect_return) && do_return && XG(do_trace) && XG(trace_file)) {
if (EG(return_value_ptr_ptr) && *EG(return_value_ptr_ptr)) {
- char* t = xdebug_return_trace_stack_retval(fse, *EG(return_value_ptr_ptr) TSRMLS_CC);
+ char *t;
+#if PHP_VERSION_ID >= 50500
+ if (op_array->fn_flags & ZEND_ACC_GENERATOR) {
+ t = xdebug_return_trace_stack_generator_retval(fse, (zend_generator *) EG(return_value_ptr_ptr) TSRMLS_CC);
+ } else {
+ t = xdebug_return_trace_stack_retval(fse, *EG(return_value_ptr_ptr) TSRMLS_CC);
+ }
+#else
+ t = xdebug_return_trace_stack_retval(fse, *EG(return_value_ptr_ptr) TSRMLS_CC);
+#endif
fprintf(XG(trace_file), "%s", t);
fflush(XG(trace_file));
xdfree(t);
@@ -1443,7 +1493,11 @@ static int check_soap_call(function_stack_entry *fse)
return 0;
}
+#if PHP_VERSION_ID < 50500
void xdebug_execute_internal(zend_execute_data *current_execute_data, int return_value_used TSRMLS_DC)
+#else
+void xdebug_execute_internal(zend_execute_data *current_execute_data, struct _zend_fcall_info *fci, int return_value_used TSRMLS_DC)
+#endif
{
zend_execute_data *edata = EG(current_execute_data);
function_stack_entry *fse;
@@ -1481,11 +1535,19 @@ void xdebug_execute_internal(zend_execute_data *current_execute_data, int return
if (XG(profiler_enabled)) {
xdebug_profiler_function_internal_begin(fse TSRMLS_CC);
}
+#if PHP_VERSION_ID < 50500
if (xdebug_old_execute_internal) {
xdebug_old_execute_internal(current_execute_data, return_value_used TSRMLS_CC);
} else {
execute_internal(current_execute_data, return_value_used TSRMLS_CC);
}
+#else
+ if (xdebug_old_execute_internal) {
+ xdebug_old_execute_internal(current_execute_data, fci, return_value_used TSRMLS_CC);
+ } else {
+ execute_internal(current_execute_data, fci, return_value_used TSRMLS_CC);
+ }
+#endif
if (XG(profiler_enabled)) {
xdebug_profiler_function_internal_end(fse TSRMLS_CC);
@@ -1499,7 +1561,7 @@ void xdebug_execute_internal(zend_execute_data *current_execute_data, int return
xdebug_trace_function_end(fse, function_nr TSRMLS_CC);
/* Store return value in the trace file */
- if (XG(collect_return) && do_return && XG(do_trace) && XG(trace_file)) {
+ if (XG(collect_return) && do_return && XG(do_trace) && XG(trace_file) && EG(opline_ptr)) {
cur_opcode = *EG(opline_ptr);
if (cur_opcode) {
zval *ret = xdebug_zval_ptr(cur_opcode->XDEBUG_TYPE(result), &(cur_opcode->result), current_execute_data->Ts TSRMLS_CC);
View
@@ -27,6 +27,10 @@
#include "zend_constants.h"
#include "zend_extensions.h"
#include "zend_exceptions.h"
+#if PHP_VERSION_ID >= 50500
+#include "zend_generators.h"
+#endif
+#include "zend_exceptions.h"
#include "zend_vm.h"
#include "zend_hash.h"
#include "xdebug_hash.h"
View
@@ -926,14 +926,30 @@ static void xdebug_build_fname(xdebug_func *tmp, zend_execute_data *edata TSRMLS
function_stack_entry *xdebug_add_stack_frame(zend_execute_data *zdata, zend_op_array *op_array, int type TSRMLS_DC)
{
- zend_execute_data *edata = EG(current_execute_data);
+ zend_execute_data *edata;
+ zend_op **opline_ptr = NULL;
function_stack_entry *tmp;
zend_op *cur_opcode;
zval **param;
int i = 0;
char *aggr_key = NULL;
int aggr_key_len = 0;
+#if PHP_VERSION_ID < 50500
+ edata = EG(current_execute_data);
+ opline_ptr = EG(opline_ptr);
+#else
+ if (type == XDEBUG_EXTERNAL) {
+ edata = EG(current_execute_data)->prev_execute_data;
+ if (edata) {
+ opline_ptr = &edata->opline;
+ }
+ } else {
+ edata = EG(current_execute_data);
+ opline_ptr = EG(opline_ptr);
+ }
+#endif
+
tmp = xdmalloc (sizeof (function_stack_entry));
tmp->var = NULL;
tmp->varc = 0;
@@ -953,7 +969,11 @@ function_stack_entry *xdebug_add_stack_frame(zend_execute_data *zdata, zend_op_a
if (edata && edata->op_array) {
/* Normal function calls */
tmp->filename = xdstrdup(edata->op_array->filename);
- } else if (edata && edata->prev_execute_data && XDEBUG_LLIST_TAIL(XG(stack))
+ } else if (
+ edata &&
+ edata->prev_execute_data &&
+ XDEBUG_LLIST_TAIL(XG(stack)) &&
+ ((function_stack_entry*) XDEBUG_LLIST_VALP(XDEBUG_LLIST_TAIL(XG(stack))))->filename
) {
tmp->filename = xdstrdup(((function_stack_entry*) XDEBUG_LLIST_VALP(XDEBUG_LLIST_TAIL(XG(stack))))->filename);
}
@@ -963,9 +983,18 @@ function_stack_entry *xdebug_add_stack_frame(zend_execute_data *zdata, zend_op_a
tmp->filename = (op_array && op_array->filename) ? xdstrdup(op_array->filename): NULL;
}
/* Call user function locations */
- if (!tmp->filename && XDEBUG_LLIST_TAIL(XG(stack)) && XDEBUG_LLIST_VALP(XDEBUG_LLIST_TAIL(XG(stack))) ) {
+ if (
+ !tmp->filename &&
+ XDEBUG_LLIST_TAIL(XG(stack)) &&
+ XDEBUG_LLIST_VALP(XDEBUG_LLIST_TAIL(XG(stack))) &&
+ ((function_stack_entry*) XDEBUG_LLIST_VALP(XDEBUG_LLIST_TAIL(XG(stack))))->filename
+ ) {
tmp->filename = xdstrdup(((function_stack_entry*) XDEBUG_LLIST_VALP(XDEBUG_LLIST_TAIL(XG(stack))))->filename);
}
+
+ if (!tmp->filename) {
+ tmp->filename = xdstrdup("UNKNOWN?");
+ }
#if HAVE_PHP_MEMORY_USAGE
tmp->prev_memory = XG(prev_memory);
tmp->memory = XG_MEMORY_USAGE();
@@ -984,8 +1013,8 @@ function_stack_entry *xdebug_add_stack_frame(zend_execute_data *zdata, zend_op_a
tmp->function.type = XFUNC_NORMAL;
} else if (tmp->function.type & XFUNC_INCLUDES) {
- if (EG(opline_ptr)) {
- cur_opcode = *EG(opline_ptr);
+ if (opline_ptr) {
+ cur_opcode = *opline_ptr;
tmp->lineno = cur_opcode->lineno;
} else {
tmp->lineno = 0;
Oops, something went wrong.

0 comments on commit e773b09

Please sign in to comment.