Permalink
Browse files

Added support for generators.

  • Loading branch information...
derickr committed Nov 24, 2012
1 parent 8576032 commit e773605d647d0d6b7e3ae09bc1e6fba8144739c7
Showing with 123 additions and 10 deletions.
  1. +59 −0 tests/bug00905.phpt
  2. +10 −1 xdebug.c
  3. +4 −0 xdebug_private.h
  4. +47 −9 xdebug_tracing.c
  5. +3 −0 xdebug_tracing.h
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
@@ -1444,7 +1444,16 @@ void xdebug_execute_ex(zend_execute_data *execute_data 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);
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
@@ -93,24 +93,30 @@ char* xdebug_return_trace_assignment(function_stack_entry *i, char *varname, zva
return str.d;
}
-char* xdebug_return_trace_stack_retval(function_stack_entry* i, zval* retval TSRMLS_DC)
+static void xdebug_return_trace_stack_common(xdebug_str *str, function_stack_entry *i TSRMLS_DC)
{
int j = 0; /* Counter */
+
+ xdebug_str_addl(str, " ", 20, 0);
+ if (XG(show_mem_delta)) {
+ xdebug_str_addl(str, " ", 8, 0);
+ }
+ for (j = 0; j < i->level; j++) {
+ xdebug_str_addl(str, " ", 2, 0);
+ }
+ xdebug_str_addl(str, " >=> ", 7, 0);
+}
+
+char* xdebug_return_trace_stack_retval(function_stack_entry* i, zval* retval TSRMLS_DC)
+{
xdebug_str str = {0, 0, NULL};
char *tmp_value;
if (XG(trace_format) != 0) {
return xdstrdup("");
}
- xdebug_str_addl(&str, " ", 20, 0);
- if (XG(show_mem_delta)) {
- xdebug_str_addl(&str, " ", 8, 0);
- }
- for (j = 0; j < i->level; j++) {
- xdebug_str_addl(&str, " ", 2, 0);
- }
- xdebug_str_addl(&str, " >=> ", 7, 0);
+ xdebug_return_trace_stack_common(&str, i TSRMLS_CC);
tmp_value = xdebug_get_zval_value(retval, 0, NULL);
if (tmp_value) {
@@ -121,6 +127,38 @@ char* xdebug_return_trace_stack_retval(function_stack_entry* i, zval* retval TSR
return str.d;
}
+#if PHP_VERSION_ID >= 50500
+char* xdebug_return_trace_stack_generator_retval(function_stack_entry* i, zend_generator* generator TSRMLS_DC)
+{
+ xdebug_str str = {0, 0, NULL};
+ char *tmp_value = NULL;
+
+ if (XG(trace_format) != 0) {
+ return xdstrdup("");
+ }
+
+ /* Generator key */
+ tmp_value = xdebug_get_zval_value(generator->key, 0, NULL);
+ if (tmp_value) {
+ xdebug_return_trace_stack_common(&str, i TSRMLS_CC);
+
+ xdebug_str_addl(&str, "(", 1, 0);
+ xdebug_str_add(&str, tmp_value, 1);
+ xdebug_str_addl(&str, " => ", 4, 0);
+
+ tmp_value = xdebug_get_zval_value(generator->value, 0, NULL);
+ if (tmp_value) {
+ xdebug_str_add(&str, tmp_value, 1);
+ }
+ xdebug_str_addl(&str, ")", 1, 0);
+ xdebug_str_addl(&str, "\n", 2, 0);
+ return str.d;
+ } else {
+ return xdstrdup("");
+ }
+}
+#endif
+
static char* return_trace_stack_frame_begin_normal(function_stack_entry* i TSRMLS_DC)
{
int c = 0; /* Comma flag */
View
@@ -20,6 +20,9 @@
#define XDEBUG_TRACING_H
char* xdebug_return_trace_stack_retval(function_stack_entry* i, zval* retval TSRMLS_DC);
+#if PHP_VERSION_ID >= 50500
+char* xdebug_return_trace_stack_generator_retval(function_stack_entry* i, zend_generator* generator TSRMLS_DC);
+#endif
char* xdebug_return_trace_assignment(function_stack_entry *i, char *varname, zval *retval, char *op, char *file, int fileno TSRMLS_DC);
void xdebug_trace_function_begin(function_stack_entry *fse, int function_nr TSRMLS_DC);

0 comments on commit e773605

Please sign in to comment.