]> granicus.if.org Git - php/commitdiff
Add breakpoint deleting
authorBob Weinand <bobwei9@hotmail.com>
Sun, 24 Nov 2013 11:58:08 +0000 (12:58 +0100)
committerBob Weinand <bobwei9@hotmail.com>
Sun, 24 Nov 2013 11:58:08 +0000 (12:58 +0100)
Changelog.md
phpdbg.h
phpdbg_bp.c
phpdbg_bp.h
phpdbg_break.c
phpdbg_break.h

index 32ecce879f53e3d5621a3f0691fc0e697edf62c8..ea7900a47ef3f29fdaffb8cff0aa3e915b327d74 100644 (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
 ------------------------
index af13f6699648649ecedd821f322170cc30e4b930..60a713a98ded1dcd23c3ba105d6c3ed82e56acb7 100644 (file)
--- a/phpdbg.h
+++ b/phpdbg.h
 
 /* {{{ 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 */
index bdd2eef3aefa4ead2f03a888fe799a9f3132a354..c06afde936356bb0f4ec3bbe9119e0d9510da95f 100644 (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]);
index 92d2a634dbf45c41b859927f3d639f33413a6763..e96c6ec44f998372748b0b6402d37f2afa97bab4 100644 (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);
 
index 62404b3d31d21779082846ed86b56d6f5687d0b4..c5d91220ff72b4bde8d86bfef444c7b06f723567 100644 (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;
+} /* }}} */
index a4f55f314b2f3e23a4b5b4ab9509c559e115d9c4..1d6f594bc8f220ceba3c6b5305cb85c9cf7dbbf0 100644 (file)
 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
 };