summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--phpdbg.h2
-rw-r--r--phpdbg_help.c17
-rw-r--r--phpdbg_set.c32
-rw-r--r--phpdbg_set.h1
-rw-r--r--phpdbg_watch.c11
-rw-r--r--test.php11
6 files changed, 53 insertions, 21 deletions
diff --git a/phpdbg.h b/phpdbg.h
index 970a9022ad..42938d9e33 100644
--- a/phpdbg.h
+++ b/phpdbg.h
@@ -139,6 +139,8 @@
#define PHPDBG_IS_REMOTE (1<<26)
#define PHPDBG_IS_DISCONNECTED (1<<27)
+#define PHPDBG_SHOW_REFCOUNTS (1<<28)
+
#define PHPDBG_SEEK_MASK (PHPDBG_IN_UNTIL|PHPDBG_IN_FINISH|PHPDBG_IN_LEAVE)
#define PHPDBG_BP_RESOLVE_MASK (PHPDBG_HAS_FUNCTION_OPLINE_BP|PHPDBG_HAS_METHOD_OPLINE_BP|PHPDBG_HAS_FILE_OPLINE_BP)
#define PHPDBG_BP_MASK (PHPDBG_HAS_FILE_BP|PHPDBG_HAS_SYM_BP|PHPDBG_HAS_METHOD_BP|PHPDBG_HAS_OPLINE_BP|PHPDBG_HAS_COND_BP|PHPDBG_HAS_OPCODE_BP|PHPDBG_HAS_FUNCTION_OPLINE_BP|PHPDBG_HAS_METHOD_OPLINE_BP|PHPDBG_HAS_FILE_OPLINE_BP)
diff --git a/phpdbg_help.c b/phpdbg_help.c
index 365b75c8c9..250fb132d2 100644
--- a/phpdbg_help.c
+++ b/phpdbg_help.c
@@ -815,14 +815,15 @@ phpdbg_help_text_t phpdbg_help_text[] = {
"The **set** command is used to configure how phpdbg looks and behaves. Specific set commands "
"are as follows:" CR CR
-" **Type** **Alias** **Purpose**" CR
-" **prompt** **p** set the prompt" CR
-" **color** **c** set color <element> <color>" CR
-" **colors** **C** set colors <on|off>" CR
-" **oplog** **O** set oplog output" CR
-" **break** **b** set break **id** <on|off>" CR
-" **breaks** **B** set breaks <on|off>" CR
-" **quiet** **q** set quiet <on|off>" CR CR
+" **Type** **Alias** **Purpose**" CR
+" **prompt** **p** set the prompt" CR
+" **color** **c** set color <element> <color>" CR
+" **colors** **C** set colors <on|off>" CR
+" **oplog** **O** set oplog output" CR
+" **break** **b** set break **id** <on|off>" CR
+" **breaks** **B** set breaks <on|off>" CR
+" **quiet** **q** set quiet <on|off>" CR
+" **refcount** **r** set refcount <on|off> (refcount display upon hit watchpoint)" CR CR
"Valid colors are **none**, **white**, **red**, **green**, **yellow**, **blue**, **purple**, "
"**cyan** and **black**. All colours except **none** can be followed by an optional "
diff --git a/phpdbg_set.c b/phpdbg_set.c
index e8027a8930..aeb882657e 100644
--- a/phpdbg_set.c
+++ b/phpdbg_set.c
@@ -34,12 +34,13 @@ const phpdbg_command_t phpdbg_set_commands[] = {
PHPDBG_SET_COMMAND_D(prompt, "usage: set prompt [<string>]", 'p', set_prompt, NULL, "|s"),
#ifndef _WIN32
PHPDBG_SET_COMMAND_D(color, "usage: set color <element> <color>", 'c', set_color, NULL, "ss"),
- PHPDBG_SET_COMMAND_D(colors, "usage: set colors [<on|off>]", 'C', set_colors, NULL, "|b"),
+ PHPDBG_SET_COMMAND_D(colors, "usage: set colors [<on|off>]", 'C', set_colors, NULL, "|b"),
#endif
PHPDBG_SET_COMMAND_D(oplog, "usage: set oplog [<output>]", 'O', set_oplog, NULL, "|s"),
PHPDBG_SET_COMMAND_D(break, "usage: set break id [<on|off>]", 'b', set_break, NULL, "l|b"),
PHPDBG_SET_COMMAND_D(breaks, "usage: set breaks [<on|off>]", 'B', set_breaks, NULL, "|b"),
PHPDBG_SET_COMMAND_D(quiet, "usage: set quiet [<on|off>]", 'q', set_quiet, NULL, "|b"),
+ PHPDBG_SET_COMMAND_D(refcount, "usage: set refcount [<on|off>]", 'r', set_refcount, NULL, "|b"),
PHPDBG_END_COMMAND
};
@@ -195,18 +196,37 @@ PHPDBG_SET(oplog) /* {{{ */
PHPDBG_SET(quiet) /* {{{ */
{
if (!param || param->type == EMPTY_PARAM) {
- phpdbg_writeln("Quietness %s",
- PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off");
- } else switch (param->type) {
+ phpdbg_writeln("Quietness %s", PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off");
+ } else switch (param->type) {
case NUMERIC_PARAM: {
if (param->num) {
PHPDBG_G(flags) |= PHPDBG_IS_QUIET;
- } else PHPDBG_G(flags) &= ~PHPDBG_IS_QUIET;
+ } else {
+ PHPDBG_G(flags) &= ~PHPDBG_IS_QUIET;
+ }
} break;
-
+
phpdbg_default_switch_case();
}
return SUCCESS;
} /* }}} */
+PHPDBG_SET(refcount) /* {{{ */
+{
+ if (!param || param->type == EMPTY_PARAM) {
+ phpdbg_writeln("Showing refcounts on watchpoints %s", PHPDBG_G(flags) & PHPDBG_IS_QUIET ? "on" : "off");
+ } else switch (param->type) {
+ case NUMERIC_PARAM: {
+ if (param->num) {
+ PHPDBG_G(flags) |= PHPDBG_SHOW_REFCOUNTS;
+ } else {
+ PHPDBG_G(flags) &= ~PHPDBG_SHOW_REFCOUNTS;
+ }
+ } break;
+
+ phpdbg_default_switch_case();
+ }
+
+ return SUCCESS;
+} /* }}} */
diff --git a/phpdbg_set.h b/phpdbg_set.h
index 4d90aac5b2..67bf4cd7de 100644
--- a/phpdbg_set.h
+++ b/phpdbg_set.h
@@ -34,6 +34,7 @@ PHPDBG_SET(oplog);
PHPDBG_SET(break);
PHPDBG_SET(breaks);
PHPDBG_SET(quiet);
+PHPDBG_SET(refcount);
extern const phpdbg_command_t phpdbg_set_commands[];
diff --git a/phpdbg_watch.c b/phpdbg_watch.c
index 41c5788a19..fe161ab7a8 100644
--- a/phpdbg_watch.c
+++ b/phpdbg_watch.c
@@ -631,9 +631,16 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) {
/* Show to the user what changed and delete watchpoint upon removal */
if (memcmp(oldPtr, watch->addr.ptr, watch->size) != SUCCESS) {
- PHPDBG_G(watchpoint_hit) = 1;
+ if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS || (watch->type == WATCH_ON_ZVAL && memcmp(oldPtr, watch->addr.zv, sizeof(zvalue_value))) || (watch->type == WATCH_ON_HASHTABLE
+#if ZEND_DEBUG
+ && !watch->addr.ht->inconsistent
+#endif
+ && zend_hash_num_elements((HashTable *)oldPtr) != zend_hash_num_elements(watch->addr.ht))) {
+ PHPDBG_G(watchpoint_hit) = 1;
+
+ phpdbg_notice("Breaking on watchpoint %s", watch->str);
+ }
- phpdbg_notice("Breaking on watchpoint %s", watch->str);
switch (watch->type) {
case WATCH_ON_ZVAL: {
int removed = ((zval *)oldPtr)->refcount__gc != watch->addr.zv->refcount__gc && !zend_symtable_exists(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len + 1);
diff --git a/test.php b/test.php
index a18851ca4a..d93c81a89a 100644
--- a/test.php
+++ b/test.php
@@ -6,11 +6,12 @@ if (isset($include)) {
$stdout = fopen("php://stdout", "w+");
class phpdbg {
- public function isGreat($greeting = null) {
- printf(
- "%s: %s\n", __METHOD__, $greeting);
- return $this;
- }
+ private $sprintf = "%s: %s\n";
+
+ public function isGreat($greeting = null) {
+ printf($this->sprintf, __METHOD__, $greeting);
+ return $this;
+ }
}
function mine() {