]> granicus.if.org Git - php/commitdiff
Fixed deletion of watchpoints
authorBob Weinand <bobwei9@hotmail.com>
Fri, 20 Dec 2013 03:21:08 +0000 (22:21 -0500)
committerBob Weinand <bobwei9@hotmail.com>
Fri, 20 Dec 2013 03:21:08 +0000 (22:21 -0500)
phpdbg_btree.c
phpdbg_watch.c

index 21f3fedcbb1ddcc1634beea4f67b96890d0539ce..6b70d1453d750cd90040e017820323b5db755404 100644 (file)
@@ -184,18 +184,24 @@ int phpdbg_btree_delete(phpdbg_btree *tree, zend_ulong idx) {
        } while (i--);
 
        if (i_last_dual_branch == -1) {
-               efree(tree);
-               tree = NULL;
+               efree(tree->branch);
+               tree->branch = NULL;
        } else {
                if (last_dual_branch->branches[last_dual_branch_branch] == last_dual_branch + 1) {
                        memcpy(last_dual_branch + 1, last_dual_branch->branches[!last_dual_branch_branch], i_last_dual_branch * sizeof(phpdbg_btree_branch));
-                       efree(last_dual_branch->branches[last_dual_branch_branch]);
+                       efree(last_dual_branch->branches[!last_dual_branch_branch]);
                        last_dual_branch->branches[!last_dual_branch_branch] = last_dual_branch + 1;
+
+                       branch = last_dual_branch->branches[!last_dual_branch_branch];
+                       for (i = i_last_dual_branch; i--;) {
+                               branch->branches[!!branch->branches[1]] = last_dual_branch + i_last_dual_branch - i + 1;
+                               branch = branch->branches[!!branch->branches[1]];
+                       }
                } else {
                        efree(last_dual_branch->branches[last_dual_branch_branch]);
                }
 
-               last_dual_branch->branches[i_last_dual_branch] = NULL;
+               last_dual_branch->branches[last_dual_branch_branch] = NULL;
        }
 
        return SUCCESS;
index 5df867a2b45dede597c73c232236735c073c092a..0c5eab1005c3ae42e4428f00bd85cc1eb3144416 100644 (file)
@@ -48,7 +48,14 @@ static inline size_t phpdbg_get_total_page_size(void *addr, size_t size) {
 }
 
 static phpdbg_watchpoint_t *phpdbg_check_for_watchpoint(void *addr TSRMLS_DC) {
-       phpdbg_watchpoint_t *watch = phpdbg_btree_find_closest(&PHPDBG_G(watchpoint_tree), (zend_ulong)phpdbg_get_page_boundary(addr) + phpdbg_pagesize - 1)->ptr;
+       phpdbg_watchpoint_t *watch;
+       phpdbg_btree_result *result = phpdbg_btree_find_closest(&PHPDBG_G(watchpoint_tree), (zend_ulong)phpdbg_get_page_boundary(addr) + phpdbg_pagesize - 1);
+
+       if (result == NULL) {
+               return NULL;
+       }
+
+       watch = result->ptr;
 
        /* check if that addr is in a mprotect()'ed memory area */
        if ((char *)phpdbg_get_page_boundary(watch->addr.ptr) > (char *)addr || (char *)phpdbg_get_page_boundary(watch->addr.ptr) + phpdbg_get_total_page_size(watch->addr.ptr, watch->size) < (char *)addr) {
@@ -161,7 +168,8 @@ static int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable *par
                                        phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t));
                                        zend_hash_get_current_key_zval_ex(parent, key, &position);
                                        convert_to_string(key);
-                                       watch->str_len = asprintf(&watch->str, "%.*s%.*s%s", i, input, Z_STRLEN_P(key), Z_STRVAL_P(key), input[len - 1] == ']'?"]":"");
+                                       watch->str = emalloc(i + Z_STRLEN_P(key) + 2);
+                                       watch->str_len = sprintf(watch->str, "%.*s%.*s%s", i, input, Z_STRLEN_P(key), Z_STRVAL_P(key), input[len - 1] == ']'?"]":"");
                                        efree(key);
                                        watch->name_in_parent = estrndup(last_index, index_len);
                                        watch->name_in_parent_len = index_len;
@@ -284,7 +292,7 @@ void phpdbg_watchpoints_clean(TSRMLS_DC) {
 static void phpdbg_watch_dtor(void *pDest) {
        TSRMLS_FETCH();
 
-       phpdbg_watchpoint_t *watch = (phpdbg_watchpoint_t *)pDest;
+       phpdbg_watchpoint_t *watch = *(phpdbg_watchpoint_t **)pDest;
 
        phpdbg_deactivate_watchpoint(watch);
        phpdbg_btree_delete(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr);