Commit: 3df8e29b0d24d378d168183028aed46c1826a511
Author: krakjoe <joe.watk...@live.co.uk> Tue, 26 Nov 2013 22:20:52
+0000
Parents: f8e7685975da5357bbe3e297377d7a8a0340acda
Branches: PHP-5.6
Link:
http://git.php.net/?p=php-src.git;a=commitdiff;h=3df8e29b0d24d378d168183028aed46c1826a511
Log:
many improvements in breakpoints
make file breakpoints faster
make exports happen in correct order
make deletes simpler, set flags correctly
fix info vars when no scope is set
Changed paths:
M phpdbg.c
M phpdbg.h
M phpdbg_bp.c
M phpdbg_bp.h
M phpdbg_info.c
diff --git a/phpdbg.c b/phpdbg.c
index f15e023..bd477e7 100644
--- a/phpdbg.c
+++ b/phpdbg.c
@@ -84,7 +84,7 @@ static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */
static void php_phpdbg_destroy_bp_file(void *brake) /* {{{ */
{
- zend_llist_destroy((zend_llist*)brake);
+ zend_hash_destroy((HashTable*)brake);
} /* }}} */
static void php_phpdbg_destroy_bp_symbol(void *brake) /* {{{ */
@@ -119,7 +119,7 @@ static void php_phpdbg_destroy_bp_condition(void *data) /*
{{{ */
}
} /* }}} */
-static void php_phpdbg_destroy_registered(void *data)
+static void php_phpdbg_destroy_registered(void *data) /* {{{ */
{
TSRMLS_FETCH();
@@ -127,7 +127,7 @@ static void php_phpdbg_destroy_registered(void *data)
destroy_zend_function(
function TSRMLS_CC);
-}
+} /* }}} */
static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */
{
@@ -137,6 +137,8 @@ static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */
zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], 8, NULL,
php_phpdbg_destroy_bp_opcode, 0);
zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], 8, NULL,
php_phpdbg_destroy_bp_methods, 0);
zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], 8, NULL,
php_phpdbg_destroy_bp_condition, 0);
+ zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], 8, NULL, NULL, 0);
+
zend_hash_init(&PHPDBG_G(seek), 8, NULL, NULL, 0);
zend_hash_init(&PHPDBG_G(registered), 8, NULL,
php_phpdbg_destroy_registered, 0);
@@ -151,6 +153,7 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE]);
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD]);
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]);
+ zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]);
zend_hash_destroy(&PHPDBG_G(seek));
zend_hash_destroy(&PHPDBG_G(registered));
diff --git a/phpdbg.h b/phpdbg.h
index b045d85..1d07ee1 100644
--- a/phpdbg.h
+++ b/phpdbg.h
@@ -79,6 +79,10 @@
#define PHPDBG_FINISH 4
#define PHPDBG_LEAVE 5
+/*
+ BEGIN: DO NOT CHANGE DO NOT CHANGE DO NOT CHANGE
+*/
+
/* {{{ tables */
#define PHPDBG_BREAK_FILE 0
#define PHPDBG_BREAK_SYM 1
@@ -86,7 +90,8 @@
#define PHPDBG_BREAK_METHOD 3
#define PHPDBG_BREAK_COND 4
#define PHPDBG_BREAK_OPCODE 5
-#define PHPDBG_BREAK_TABLES 6 /* }}} */
+#define PHPDBG_BREAK_MAP 6
+#define PHPDBG_BREAK_TABLES 7 /* }}} */
/* {{{ flags */
#define PHPDBG_HAS_FILE_BP (1<<1)
@@ -97,6 +102,10 @@
#define PHPDBG_HAS_OPCODE_BP (1<<6)
#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)
+/*
+ END: DO NOT CHANGE DO NOT CHANGE DO NOT CHANGE
+*/
+
#define PHPDBG_IN_COND_BP (1<<7)
#define PHPDBG_IN_EVAL (1<<8)
@@ -148,7 +157,6 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
zend_op_array *ops; /* op_array */
zval *retval; /* return value */
int bp_count; /* breakpoint count */
- int del_bp_num; /* breakpoint to delete */
int vmret; /* return from last opcode
handler execution */
FILE *oplog; /* opline log */
diff --git a/phpdbg_bp.c b/phpdbg_bp.c
index 75d0918..61c8f74 100644
--- a/phpdbg_bp.c
+++ b/phpdbg_bp.c
@@ -19,7 +19,6 @@
#include "zend.h"
#include "zend_hash.h"
-#include "zend_llist.h"
#include "phpdbg.h"
#include "phpdbg_bp.h"
#include "phpdbg_utils.h"
@@ -28,14 +27,27 @@
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
-static void phpdbg_llist_breakfile_dtor(void *data) /* {{{ */
+/*
+* Note:
+* A break point must always set the corect id and type
+* A set breakpoint function must always map new points
+*/
+static inline _phpdbg_break_mapping(int id, HashTable* table TSRMLS_DC) {
+ zend_hash_index_update(
+ &PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (id), (void**) &table,
sizeof(void*), NULL);
+}
+
+#define PHPDBG_BREAK_MAPPING(id, table) _phpdbg_break_mapping(id, table
TSRMLS_CC)
+#define PHPDBG_BREAK_UNMAPPING(id) \
+ zend_hash_index_del(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (id))
+
+static void phpdbg_file_breaks_dtor(void *data) /* {{{ */
{
phpdbg_breakfile_t *bp = (phpdbg_breakfile_t*) data;
efree((char*)bp->filename);
} /* }}} */
-
static void phpdbg_class_breaks_dtor(void *data) /* {{{ */
{
phpdbg_breakmethod_t *bp = (phpdbg_breakmethod_t*) data;
@@ -46,110 +58,63 @@ static void phpdbg_class_breaks_dtor(void *data) /* {{{ */
PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
{
- HashPosition position;
- HashTable *table = NULL;
-
- if (PHPDBG_G(flags) & PHPDBG_HAS_FILE_BP) {
- zend_llist *brakes;
-
- table = &PHPDBG_G(bp)[PHPDBG_BREAK_FILE];
-
- for (zend_hash_internal_pointer_reset_ex(table, &position);
- zend_hash_get_current_data_ex(table, (void*) &brakes,
&position) == SUCCESS;
- zend_hash_move_forward_ex(table, &position)) {
-
- zend_llist_position lposition;
- phpdbg_breakfile_t *brake;
- int count = zend_llist_count(brakes);
-
- if ((brake = zend_llist_get_first_ex(brakes,
&lposition))) {
- phpdbg_notice(
- "Exporting file breakpoints in %s
(%d)", brake->filename, count);
-
- do {
- fprintf(handle, "break file %s:%lu\n",
brake->filename, brake->line);
- } while ((brake =
zend_llist_get_next_ex(brakes, &lposition)));
- }
- }
- }
-
- if (PHPDBG_G(flags) & PHPDBG_HAS_SYM_BP) {
- phpdbg_breaksymbol_t *brake;
-
- table = &PHPDBG_G(bp)[PHPDBG_BREAK_SYM];
-
- phpdbg_notice("Exporting symbol breakpoints (%d)",
zend_hash_num_elements(table));
-
- for (zend_hash_internal_pointer_reset_ex(table, &position);
- zend_hash_get_current_data_ex(table, (void*) &brake,
&position) == SUCCESS;
- zend_hash_move_forward_ex(table, &position)) {
- fprintf(
- handle, "break %s\n", brake->symbol);
- }
- }
-
- if (PHPDBG_G(flags) & PHPDBG_HAS_METHOD_BP) {
- HashTable *class;
- phpdbg_breakmethod_t *brake;
- HashPosition mposition;
- zend_bool noted = 0;
-
- table = &PHPDBG_G(bp)[PHPDBG_BREAK_METHOD];
-
- for (zend_hash_internal_pointer_reset_ex(table, &position);
- zend_hash_get_current_data_ex(table, (void**) &class,
&position) == SUCCESS;
- zend_hash_move_forward_ex(table, &position)) {
- noted = 0;
-
- for (zend_hash_internal_pointer_reset_ex(class,
&mposition);
- zend_hash_get_current_data_ex(class, (void**)
&brake, &mposition) == SUCCESS;
- zend_hash_move_forward_ex(class, &mposition)) {
- if (!noted) {
- phpdbg_notice(
- "Exporting method breakpoints
in %s (%d)",
- brake->class_name,
zend_hash_num_elements(class));
- noted = 1;
+ HashPosition position[2];
+ HashTable **table = NULL;
+ zend_ulong id = 0L;
+
+ if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])) {
+ phpdbg_notice(
+ "Exporting %ld breakpoints",
+
zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]));
+
+ for
(zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP],
&position[0]);
+
zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (void**)&table,
&position[0]) == SUCCESS;
+
zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0])) {
+ phpdbg_breakbase_t *brake;
+
+
zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], NULL, NULL, &id,
0, &position[0]);
+
+ for (zend_hash_internal_pointer_reset_ex((*table),
&position[1]);
+ zend_hash_get_current_data_ex((*table),
(void**)&brake, &position[1]) == SUCCESS;
+ zend_hash_move_forward_ex((*table),
&position[1])) {
+ if (brake->id == id) {
+ switch (brake->type) {
+ case PHPDBG_BREAK_FILE: {
+ fprintf(handle,
+ "break file
%s:%lu\n",
+
((phpdbg_breakfile_t*)brake)->filename,
+
((phpdbg_breakfile_t*)brake)->line);
+ } break;
+
+ case PHPDBG_BREAK_SYM: {
+ fprintf(handle,
+ "break func
%s\n",
+
((phpdbg_breaksymbol_t*)brake)->symbol);
+ } break;
+
+ case PHPDBG_BREAK_METHOD: {
+ fprintf(handle,
+ "break method
%s::%s\n",
+
((phpdbg_breakmethod_t*)brake)->class_name,
+
((phpdbg_breakmethod_t*)brake)->func_name);
+ } break;
+
+ case PHPDBG_BREAK_OPCODE: {
+ fprintf(handle,
+ "break op
%s\n",
+
((phpdbg_breakop_t*)brake)->name);
+ } break;
+
+ case PHPDBG_BREAK_COND: {
+ fprintf(handle,
+ "break on
%s\n",
+
Z_STRVAL(((phpdbg_breakcond_t*)brake)->code));
+ } break;
+ }
}
-
- fprintf(
- handle, "break %s::%s\n",
brake->class_name, brake->func_name);
}
}
}
-
- if (PHPDBG_G(flags) & PHPDBG_HAS_OPCODE_BP) {
- phpdbg_breakop_t *brake;
-
- table = &PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE];
-
- phpdbg_notice(
- "Exporting opcode breakpoints (%d)",
zend_hash_num_elements(table));
-
- for (zend_hash_internal_pointer_reset_ex(table, &position);
- zend_hash_get_current_data_ex(table, (void**) &brake,
&position) == SUCCESS;
- zend_hash_move_forward_ex(table, &position)) {
-
- fprintf(
- handle, "break op %s\n", brake->name);
- }
- }
-
- if (PHPDBG_G(flags) & PHPDBG_HAS_COND_BP) {
- phpdbg_breakcond_t *brake;
-
- table = &PHPDBG_G(bp)[PHPDBG_BREAK_COND];
-
- phpdbg_notice(
- "Exporting conditional breakpoints (%d)",
zend_hash_num_elements(table));
-
- for (zend_hash_internal_pointer_reset_ex(table, &position);
- zend_hash_get_current_data_ex(table, (void**) &brake,
&position) == SUCCESS;
- zend_hash_move_forward_ex(table, &position)) {
-
- fprintf(
- handle, "break on %s\n", Z_STRVAL(brake->code));
- }
- }
} /* }}} */
PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num
TSRMLS_DC) /* {{{ */
@@ -158,32 +123,40 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char
*path, long line_num TSRML
if (VCWD_STAT(path, &sb) != FAILURE) {
if (sb.st_mode & (S_IFREG|S_IFLNK)) {
+ HashTable *broken;
phpdbg_breakfile_t new_break;
- zend_llist *break_files_ptr;
size_t path_len = strlen(path);
- new_break.filename = estrndup(path, path_len);
- new_break.line = line_num;
-
- PHPDBG_G(flags) |= PHPDBG_HAS_FILE_BP;
-
if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE],
- new_break.filename, path_len,
(void**)&break_files_ptr) == FAILURE) {
- zend_llist break_files;
-
- zend_llist_init(&break_files,
sizeof(phpdbg_breakfile_t),
- phpdbg_llist_breakfile_dtor, 0);
+ path, path_len, (void**)&broken) == FAILURE) {
+ HashTable breaks;
+
+ zend_hash_init(&breaks, 8, NULL,
phpdbg_file_breaks_dtor, 0);
zend_hash_update(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE],
- new_break.filename, path_len,
&break_files, sizeof(zend_llist),
- (void**)&break_files_ptr);
+ path, path_len, &breaks,
sizeof(HashTable),
+ (void**)&broken);
}
-
- new_break.id = PHPDBG_G(bp_count)++;
- zend_llist_add_element(break_files_ptr, &new_break);
-
- phpdbg_notice("Breakpoint #%d added at %s:%ld",
- new_break.id, new_break.filename,
new_break.line);
+
+ if (!zend_hash_index_exists(broken, line_num)) {
+ PHPDBG_G(flags) |= PHPDBG_HAS_FILE_BP;
+
+ new_break.filename = estrndup(path, path_len);
+ new_break.line = line_num;
+ new_break.id = PHPDBG_G(bp_count)++;
+ new_break.type = PHPDBG_BREAK_FILE;
+
+ zend_hash_index_update(
+ broken, line_num, (void**)&new_break,
sizeof(phpdbg_breakfile_t), NULL);
+
+ phpdbg_notice("Breakpoint #%d added at %s:%ld",
+ new_break.id, new_break.filename,
new_break.line);
+
+ PHPDBG_BREAK_MAPPING(new_break.id, broken);
+ } else {
+ phpdbg_error("Breakpoint at %s:%ld exists",
path, line_num);
+ }
+
} else {
phpdbg_error("Cannot set breakpoint in %s, it is not a
regular file", path);
}
@@ -201,12 +174,15 @@ PHPDBG_API void phpdbg_set_breakpoint_symbol(const char
*name, size_t name_len T
new_break.symbol = estrndup(name, name_len);
new_break.id = PHPDBG_G(bp_count)++;
-
+ new_break.type = PHPDBG_BREAK_SYM;
+
zend_hash_update(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM],
new_break.symbol,
name_len, &new_break, sizeof(phpdbg_breaksymbol_t),
NULL);
phpdbg_notice("Breakpoint #%d added at %s",
new_break.id, new_break.symbol);
+
+ PHPDBG_BREAK_MAPPING(new_break.id,
&PHPDBG_G(bp)[PHPDBG_BREAK_SYM]);
} else {
phpdbg_notice("Breakpoint exists at %s", name);
}
@@ -238,12 +214,15 @@ PHPDBG_API void phpdbg_set_breakpoint_method(const char*
class_name, const char*
new_break.func_name = estrndup(func_name, func_len);
new_break.func_len = func_len;
new_break.id = PHPDBG_G(bp_count)++;
-
+ new_break.type = PHPDBG_BREAK_METHOD;
+
zend_hash_update(class_table, lcname, func_len,
&new_break, sizeof(phpdbg_breakmethod_t), NULL);
phpdbg_notice("Breakpoint #%d added at %s::%s",
new_break.id, class_name, func_name);
+
+ PHPDBG_BREAK_MAPPING(new_break.id, class_table);
} else {
phpdbg_notice("Breakpoint exists at %s::%s", class_name,
func_name);
}
@@ -261,12 +240,14 @@ PHPDBG_API void phpdbg_set_breakpoint_opline(zend_ulong
opline TSRMLS_DC) /* {{{
new_break.name = NULL;
new_break.opline = opline;
new_break.id = PHPDBG_G(bp_count)++;
-
+ new_break.type = PHPDBG_BREAK_OPLINE;
+
zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE],
opline,
&new_break, sizeof(phpdbg_breakline_t), NULL);
phpdbg_notice("Breakpoint #%d added at %#lx",
new_break.id, new_break.opline);
+ PHPDBG_BREAK_MAPPING(new_break.id,
&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
} else {
phpdbg_notice("Breakpoint exists at %#lx", opline);
}
@@ -286,6 +267,7 @@ PHPDBG_API void phpdbg_set_breakpoint_opcode(const char
*name, size_t name_len T
new_break.hash = hash;
new_break.name = estrndup(name, name_len);
new_break.id = PHPDBG_G(bp_count)++;
+ new_break.type = PHPDBG_BREAK_OPCODE;
zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], hash,
&new_break, sizeof(phpdbg_breakop_t), NULL);
@@ -293,6 +275,7 @@ PHPDBG_API void phpdbg_set_breakpoint_opcode(const char
*name, size_t name_len T
PHPDBG_G(flags) |= PHPDBG_HAS_OPCODE_BP;
phpdbg_notice("Breakpoint #%d added at %s", new_break.id, name);
+ PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE]);
} /* }}} */
PHPDBG_API void phpdbg_set_breakpoint_opline_ex(phpdbg_opline_ptr_t opline
TSRMLS_DC) /* {{{ */
@@ -304,12 +287,14 @@ PHPDBG_API void
phpdbg_set_breakpoint_opline_ex(phpdbg_opline_ptr_t opline TSRML
new_break.opline = (zend_ulong) opline;
new_break.id = PHPDBG_G(bp_count)++;
-
+ new_break.type = PHPDBG_BREAK_OPLINE;
+
zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE],
(zend_ulong) opline, &new_break,
sizeof(phpdbg_breakline_t), NULL);
phpdbg_notice("Breakpoint #%d added at %#lx",
new_break.id, new_break.opline);
+ PHPDBG_BREAK_MAPPING(new_break.id,
&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
}
} /* }}} */
@@ -326,6 +311,7 @@ PHPDBG_API void phpdbg_set_breakpoint_expression(const char
*expr, size_t expr_l
new_break.hash = hash;
new_break.id = PHPDBG_G(bp_count)++;
+ new_break.type = PHPDBG_BREAK_COND;
cops = CG(compiler_options);
@@ -353,6 +339,7 @@ PHPDBG_API void phpdbg_set_breakpoint_expression(const char
*expr, size_t expr_l
brake->id, Z_STRVAL(brake->code), brake->ops);
PHPDBG_G(flags) |= PHPDBG_HAS_COND_BP;
+ PHPDBG_BREAK_MAPPING(new_break.id,
&PHPDBG_G(bp)[PHPDBG_BREAK_COND]);
} else {
phpdbg_error(
"Failed to compile code for expression %s",
expr);
@@ -367,23 +354,19 @@ PHPDBG_API void phpdbg_set_breakpoint_expression(const
char *expr, size_t expr_l
int phpdbg_find_breakpoint_file(zend_op_array *op_array TSRMLS_DC) /* {{{ */
{
+ HashTable *breaks;
+ phpdbg_breakfile_t *brake;
size_t name_len = strlen(op_array->filename);
- zend_llist *break_list;
- zend_llist_element *le;
-
+
if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], op_array->filename,
- name_len, (void**)&break_list) == FAILURE) {
+ name_len, (void**)&breaks) == FAILURE) {
return FAILURE;
}
- for (le = break_list->head; le; le = le->next) {
- const phpdbg_breakfile_t *bp = (phpdbg_breakfile_t*)le->data;
-
- if (bp->line == (*EG(opline_ptr))->lineno) {
- phpdbg_notice("Breakpoint #%d at %s:%ld",
- bp->id, bp->filename, bp->line);
- return SUCCESS;
- }
+ if (zend_hash_index_find(breaks, (*EG(opline_ptr))->lineno,
(void**)&brake) == SUCCESS) {
+ phpdbg_notice("Breakpoint #%d at %s:%ld",
+ brake->id, brake->filename, brake->line);
+ return SUCCESS;
}
return FAILURE;
@@ -598,102 +581,75 @@ int phpdbg_find_breakpoint(zend_execute_data*
execute_data TSRMLS_DC) /* {{{ */
return FAILURE;
} /* }}} */
-int phpdbg_delete_breakpoint_from_file_llist(void *brake) { /* {{{ */
- TSRMLS_FETCH();
- return ((phpdbg_breakfile_t*)brake)->id == PHPDBG_G(del_bp_num);
-} /* }}} */
-
PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */
{
- if (PHPDBG_G(flags) & PHPDBG_HAS_SYM_BP) {
- HashPosition position;
- phpdbg_breaksymbol_t *brake;
+ HashTable **table;
- for
(zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM],
&position);
-
zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], (void**) &brake,
&position) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM],
&position)) {
- if (brake->id == num) {
- zend_hash_del(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM],
brake->symbol, strlen(brake->symbol));
- return;
- }
- }
- }
-
- if (PHPDBG_G(flags) & PHPDBG_HAS_METHOD_BP) {
- HashPosition position[2];
- phpdbg_breakmethod_t *brake;
- HashTable *class_table;
-
- for
(zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD],
&position[0]);
-
zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], (void**)
&class_table, &position[0]) == SUCCESS;
-
zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], &position[0])) {
- for (zend_hash_internal_pointer_reset_ex(class_table,
&position[1]);
- zend_hash_get_current_data_ex(class_table,
(void**) &brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex(class_table,
&position[1])) {
- if (brake->id == num) {
- zend_hash_del(class_table,
brake->func_name, brake->func_len);
- return;
- }
- }
- }
- }
-
- if (PHPDBG_G(flags) & PHPDBG_HAS_FILE_BP) {
- HashPosition position;
- zend_llist *points;
-
- for
(zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE],
&position);
-
zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], (void**)
&points, &position) == SUCCESS;
-
zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], &position)) {
- size_t size = points->size;
- PHPDBG_G(del_bp_num) = num;
- zend_llist_apply_with_del(points,
phpdbg_delete_breakpoint_from_file_llist);
- if (size != points->size) {
- return;
- }
- }
- }
-
- if (PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP) {
+ if (zend_hash_index_find(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], num,
(void**)&table) == SUCCESS) {
HashPosition position;
- phpdbg_breakline_t *brake;
-
- for
(zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE],
&position);
-
zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (void**)
&brake, &position) == SUCCESS;
-
zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position)) {
- if (brake->id == num) {
-
zend_hash_index_del(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], brake->opline);
- return;
- }
- }
- }
-
- if (PHPDBG_G(flags) & PHPDBG_HAS_COND_BP) {
- HashPosition position;
- phpdbg_breakcond_t *brake;
-
- for
(zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND],
&position);
-
zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], (void**)
&brake, &position) == SUCCESS;
-
zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) {
- if (brake->id == num) {
-
zend_hash_index_del(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], brake->hash);
- return;
- }
- }
- }
-
- if (PHPDBG_G(flags) & PHPDBG_HAS_OPCODE_BP) {
- HashPosition position;
- phpdbg_breakop_t *brake;
-
- for
(zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE],
&position);
-
zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], (void**)
&brake, &position) == SUCCESS;
-
zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], &position)) {
+ phpdbg_breakbase_t *brake;
+
+ for (zend_hash_internal_pointer_reset_ex((*table), &position);
+ zend_hash_get_current_data_ex((*table), (void**)&brake,
&position) == SUCCESS;
+ zend_hash_move_forward_ex((*table), &position)) {
+ char *key;
+ zend_uint klen;
+ zend_ulong idx;
+
if (brake->id == num) {
-
zend_hash_index_del(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], brake->hash);
+ int type = brake->type;
+ char *name = NULL;
+ size_t name_len = 0L;
+
+ switch (type) {
+ case PHPDBG_BREAK_FILE:
+ case PHPDBG_BREAK_METHOD:
+ if
(zend_hash_num_elements((*table)) == 1) {
+ name =
estrdup(brake->name);
+ name_len = strlen(name);
+ if
(zend_hash_num_elements(&PHPDBG_G(bp)[type]) == 1) {
+ PHPDBG_G(flags)
&= ~(1<<(brake->type+1));
+ }
+ }
+ break;
+
+ default: {
+ if
(zend_hash_num_elements((*table)) == 1) {
+ PHPDBG_G(flags) &=
~(1<<(brake->type+1));
+ }
+ }
+ }
+
+ switch (zend_hash_get_current_key_ex(
+ (*table), &key, &klen, &idx, 0,
&position)) {
+
+ case HASH_KEY_IS_STRING:
+ zend_hash_del((*table), key,
klen);
+ break;
+
+ default:
+ zend_hash_index_del((*table),
idx);
+ }
+
+ switch (type) {
+ case PHPDBG_BREAK_FILE:
+ case PHPDBG_BREAK_METHOD:
+ if (name) {
+
zend_hash_del(&PHPDBG_G(bp)[type], name, name_len);
+ efree(name);
+ }
+ break;
+ }
+deleted:
+ phpdbg_notice("Deleted breakpoint #%ld", num);
+ PHPDBG_BREAK_UNMAPPING(num);
return;
- }
+ }
}
+
+ phpdbg_error("Failed to delete breakpoint #%ld", num);
+ } else {
+ phpdbg_error("Failed to find breakpoint #%ld", num);
}
} /* }}} */
@@ -705,7 +661,8 @@ PHPDBG_API void phpdbg_clear_breakpoints(TSRMLS_D) /* {{{ */
zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE]);
zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD]);
zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]);
-
+ zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]);
+
PHPDBG_G(flags) &= ~PHPDBG_BP_MASK;
PHPDBG_G(bp_count) = 0;
@@ -742,7 +699,6 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type
TSRMLS_DC) /* {{{ */
if
(zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD],
&class_name, &class_len, &class_idx, 0,
&position[0]) == HASH_KEY_IS_STRING) {
-
phpdbg_breakmethod_t *brake;
for
(zend_hash_internal_pointer_reset_ex(class_table, &position[1]);
@@ -756,23 +712,23 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type
TSRMLS_DC) /* {{{ */
} break;
case PHPDBG_BREAK_FILE: if ((PHPDBG_G(flags) &
PHPDBG_HAS_FILE_BP)) {
- HashPosition position;
- zend_llist *points;
-
+ HashPosition position[2];
+ HashTable *points;
+
phpdbg_writeln(SEPARATE);
phpdbg_writeln("File Breakpoints:");
- for
(zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE],
&position);
-
zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], (void**)
&points, &position) == SUCCESS;
-
zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], &position)) {
- zend_llist_position lposition;
+ for
(zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE],
&position[0]);
+
zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], (void**)
&points, &position[0]) == SUCCESS;
+
zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], &position[0])) {
phpdbg_breakfile_t *brake;
- if ((brake = zend_llist_get_first_ex(points,
&lposition))) {
- do {
- phpdbg_writeln("#%d\t\t%s:%lu",
brake->id, brake->filename, brake->line);
- } while ((brake =
zend_llist_get_next_ex(points, &lposition)));
+ for
(zend_hash_internal_pointer_reset_ex(points, &position[1]);
+ zend_hash_get_current_data_ex(points,
(void**)&brake, &position[1]) == SUCCESS;
+ zend_hash_move_forward_ex(points,
&position[1])) {
+ phpdbg_writeln("#%d\t\t%s:%lu",
brake->id, brake->filename, brake->line);
}
}
+
} break;
case PHPDBG_BREAK_OPLINE: if ((PHPDBG_G(flags) &
PHPDBG_HAS_OPLINE_BP)) {
diff --git a/phpdbg_bp.h b/phpdbg_bp.h
index eb30e3e..84162ec 100644
--- a/phpdbg_bp.h
+++ b/phpdbg_bp.h
@@ -23,60 +23,73 @@
/* {{{ */
typedef struct _zend_op *phpdbg_opline_ptr_t; /* }}} */
+/* {{{ breakpoint base */
+typedef struct _phpdbg_breakbase_t {
+ int id;
+ zend_uchar type;
+ const char *name;
+} phpdbg_breakbase_t; /* }}} */
+
/**
* Breakpoint file-based representation
*/
typedef struct _phpdbg_breakfile_t {
+ int id;
+ zend_uchar type;
const char *filename;
long line;
- int id;
} phpdbg_breakfile_t;
/**
* Breakpoint symbol-based representation
*/
typedef struct _phpdbg_breaksymbol_t {
- const char *symbol;
int id;
+ zend_uchar type;
+ const char *symbol;
} phpdbg_breaksymbol_t;
/**
* Breakpoint method based representation
*/
typedef struct _phpdbg_breakmethod_t {
+ int id;
+ zend_uchar type;
const char *class_name;
size_t class_len;
const char *func_name;
size_t func_len;
- int id;
} phpdbg_breakmethod_t;
/**
* Breakpoint opline based representation
*/
typedef struct _phpdbg_breakline_t {
+ int id;
+ zend_uchar type;
const char *name;
zend_ulong opline;
- int id;
} phpdbg_breakline_t;
/**
* Breakpoint opcode based representation
*/
typedef struct _phpdbg_breakop_t {
- zend_ulong hash;
- const char *name;
int id;
+ zend_uchar type;
+ const char *name;
+ zend_ulong hash;
} phpdbg_breakop_t;
/**
* Breakpoint condition based representation
*/
typedef struct _phpdbg_breakcond_t {
+ int id;
+ zend_uchar type;
zend_ulong hash;
zval code;
zend_op_array *ops;
- int id;
} phpdbg_breakcond_t;
PHPDBG_API void phpdbg_set_breakpoint_file(const char*, long TSRMLS_DC);
diff --git a/phpdbg_info.c b/phpdbg_info.c
index 727e676..f44d192 100644
--- a/phpdbg_info.c
+++ b/phpdbg_info.c
@@ -73,6 +73,11 @@ PHPDBG_INFO(vars) /* {{{ */
char *var;
zval **data;
+ if (!EG(active_op_array)) {
+ phpdbg_error("No active op array!");
+ return SUCCESS;
+ }
+
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php