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

Reply via email to