Add breakpoint deleting

This commit is contained in:
Bob Weinand 2013-11-24 12:58:08 +01:00
parent b80baeb25e
commit 2b5c929153
6 changed files with 110 additions and 7 deletions

View File

@ -1,10 +1,10 @@
ChangeLog for phpdbg
====================
Version 0.1.1 2013-00-00
Version 0.2.0 2013-00-00
------------------------
1. Added "break delete <id>" command
Version 0.1.0 2013-11-23
------------------------

View File

@ -121,7 +121,7 @@
/* {{{ strings */
#define PHPDBG_ISSUES "http://github.com/krakjoe/phpdbg/issues"
#define PHPDBG_VERSION "0.1.1-dev" /* }}} */
#define PHPDBG_VERSION "0.2.0-dev" /* }}} */
/* {{{ output descriptors */
#define PHPDBG_STDIN 0
@ -136,6 +136,7 @@ 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 */
phpdbg_command_t *lcmd; /* last command */
phpdbg_param_t lparam; /* last param */

View File

@ -211,6 +211,7 @@ PHPDBG_API void phpdbg_set_breakpoint_expression(const char *expr, size_t expr_l
ZVAL_STRINGL(&new_break.code, expr, expr_len, 1);
new_break.hash = hash;
new_break.id = PHPDBG_G(bp_count)++;
cops = CG(compiler_options);
@ -476,6 +477,90 @@ 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;
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) {
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);
}
}
}
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;
}
}
}
} /* }}} */
PHPDBG_API void phpdbg_clear_breakpoints(TSRMLS_D) /* {{{ */
{
zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE]);

View File

@ -72,9 +72,10 @@ typedef struct _phpdbg_breakop_t {
* Breakpoint condition based representation
*/
typedef struct _phpdbg_breakcond_t {
zval code;
zend_op_array *ops;
int id;
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);
@ -94,6 +95,7 @@ int phpdbg_find_conditional_breakpoint(TSRMLS_D);
int phpdbg_find_catch(zend_uchar TSRMLS_DC);
int phpdbg_find_breakpoint(zend_execute_data* TSRMLS_DC);
PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC);
PHPDBG_API void phpdbg_clear_breakpoints(TSRMLS_D);
PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC);

View File

@ -121,3 +121,16 @@ PHPDBG_BREAK(op) /* {{{ */
return SUCCESS;
} /* }}} */
PHPDBG_BREAK(del) /* {{{ */
{
switch (param->type) {
case NUMERIC_PARAM: {
phpdbg_delete_breakpoint(param->num TSRMLS_CC);
} break;
phpdbg_default_switch_case();
}
return SUCCESS;
} /* }}} */

View File

@ -31,10 +31,11 @@
PHPDBG_BREAK(file);
PHPDBG_BREAK(method);
PHPDBG_BREAK(address);
PHPDBG_BREAK(op);
PHPDBG_BREAK(on);
PHPDBG_BREAK(lineno);
PHPDBG_BREAK(func);
PHPDBG_BREAK(op);
PHPDBG_BREAK(del);
/**
* Commands
@ -47,6 +48,7 @@ static const phpdbg_command_t phpdbg_break_commands[] = {
PHPDBG_COMMAND_D_EX(on, "specify breakpoint by expression", 'o', break_on, NULL, 1),
PHPDBG_COMMAND_D_EX(lineno, "specify breakpoint by line of currently executing file", 'l', break_lineno, NULL, 1),
PHPDBG_COMMAND_D_EX(func, "specify breakpoint by global function name", 'f', break_func, NULL, 1),
PHPDBG_COMMAND_D_EX(del, "delete breakpoint by identifier number", 'd', break_del, NULL, 1),
PHPDBG_END_COMMAND
};