diff options
author | Rasmus Lerdorf <rasmus@php.net> | 2014-10-26 16:58:45 -0700 |
---|---|---|
committer | Rasmus Lerdorf <rasmus@php.net> | 2014-10-26 16:58:45 -0700 |
commit | 8d84b1f67adb71bdb2394b62faad04b22f6226f3 (patch) | |
tree | 0c1c1ed2aaef8eee971575eb5e336631295f4951 /sapi/phpdbg/phpdbg_bp.c | |
parent | fb85d0322d39d49f37e32df6f68c9769f2cce0e4 (diff) | |
parent | 09da8952d0434b53e740ffaca66a8051cd39cf93 (diff) | |
download | php-git-8d84b1f67adb71bdb2394b62faad04b22f6226f3.tar.gz |
Merge branch 'master' of git.php.net:php-src
* 'master' of git.php.net:php-src: (240 commits)
Do not execute anything after quit or clean command
Fix last commit, and do not output unnecessary information
Stabilize execution, always run destructors and extended file breakpoints
Fix nullptr dereference in clean without exec context
remove dodgy param parser, bring userland breakpoint api inline with PHP7
disable output buffering by default
Add question to reset execution in run/exec/clean
- Updated to version 2014.9 (2014i)
actually remove this
disable output buffering, better breakpoint api for userland, remove hand parsing of params
Fix phpdbg output when outputting via php with active output handlers
Fixed Closure::call() NEWS/UPGRADING
Set engine back to initial state after fatal-ed ev command
Fix eventual stack overflow after clean cmd
Fix listing of files with no absolute path
updated libmagic.patch in master
updated libmagic.patch in 5.6
updated libmagic.patch in 5.5
NEWS
NEWS
...
Diffstat (limited to 'sapi/phpdbg/phpdbg_bp.c')
-rw-r--r-- | sapi/phpdbg/phpdbg_bp.c | 930 |
1 files changed, 413 insertions, 517 deletions
diff --git a/sapi/phpdbg/phpdbg_bp.c b/sapi/phpdbg/phpdbg_bp.c index e30b87c313..f6610cd0ca 100644 --- a/sapi/phpdbg/phpdbg_bp.c +++ b/sapi/phpdbg/phpdbg_bp.c @@ -1,6 +1,6 @@ /* +----------------------------------------------------------------------+ - | PHP Version 7 | + | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2014 The PHP Group | +----------------------------------------------------------------------+ @@ -43,8 +43,7 @@ static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execut */ static inline void _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); + zend_hash_index_update_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], id, table); } #define PHPDBG_BREAK_MAPPING(id, table) _phpdbg_break_mapping(id, table TSRMLS_CC) @@ -58,29 +57,29 @@ static inline void _phpdbg_break_mapping(int id, HashTable *table TSRMLS_DC) b.hits = 0; \ } while(0) -static void phpdbg_file_breaks_dtor(void *data) /* {{{ */ +static void phpdbg_file_breaks_dtor(zval *data) /* {{{ */ { - phpdbg_breakfile_t *bp = (phpdbg_breakfile_t*) data; + phpdbg_breakfile_t *bp = (phpdbg_breakfile_t*) Z_PTR_P(data); efree((char*)bp->filename); } /* }}} */ -static void phpdbg_class_breaks_dtor(void *data) /* {{{ */ +static void phpdbg_class_breaks_dtor(zval *data) /* {{{ */ { - phpdbg_breakmethod_t *bp = (phpdbg_breakmethod_t*) data; + phpdbg_breakmethod_t *bp = (phpdbg_breakmethod_t *) Z_PTR_P(data); efree((char*)bp->class_name); efree((char*)bp->func_name); } /* }}} */ -static void phpdbg_opline_class_breaks_dtor(void *data) /* {{{ */ +static void phpdbg_opline_class_breaks_dtor(zval *data) /* {{{ */ { - zend_hash_destroy((HashTable *)data); + zend_hash_destroy((HashTable *) Z_PTR_P(data)); } /* }}} */ -static void phpdbg_opline_breaks_dtor(void *data) /* {{{ */ +static void phpdbg_opline_breaks_dtor(zval *data) /* {{{ */ { - phpdbg_breakopline_t *bp = (phpdbg_breakopline_t *) data; + phpdbg_breakopline_t *bp = (phpdbg_breakopline_t *) Z_PTR_P(data); if (bp->class_name) { efree((char*)bp->class_name); @@ -92,45 +91,30 @@ static void phpdbg_opline_breaks_dtor(void *data) /* {{{ */ PHPDBG_API void phpdbg_reset_breakpoints(TSRMLS_D) /* {{{ */ { - if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])) { - HashPosition position[2]; - HashTable **table = NULL; + HashTable *table; - 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_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], table) { + phpdbg_breakbase_t *brake; - 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])) { - brake->hits = 0; - } - } - } + ZEND_HASH_FOREACH_PTR(table, brake) { + brake->hits = 0; + } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); } /* }}} */ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ { - HashPosition position[2]; - HashTable **table = NULL; + HashTable *table; zend_ulong id = 0L; if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])) { - phpdbg_notice( - "Exporting %d breakpoints", - zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])); + phpdbg_notice("exportbreakpoint", "count=\"%d\"", "Exporting %d breakpoints", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])); + /* this only looks like magic, it isn't */ - 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])) { + ZEND_HASH_FOREACH_NUM_KEY_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], id, table) { 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])) { + ZEND_HASH_FOREACH_PTR(table, brake) { if (brake->id == id) { switch (brake->type) { case PHPDBG_BREAK_FILE: { @@ -155,7 +139,7 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ case PHPDBG_BREAK_METHOD_OPLINE: { fprintf(handle, - "break %s::%s#%ld\n", + "break %s::%s#%llu\n", ((phpdbg_breakopline_t*)brake)->class_name, ((phpdbg_breakopline_t*)brake)->func_name, ((phpdbg_breakopline_t*)brake)->opline_num); @@ -163,14 +147,14 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ case PHPDBG_BREAK_FUNCTION_OPLINE: { fprintf(handle, - "break %s#%ld\n", + "break %s#%llu\n", ((phpdbg_breakopline_t*)brake)->func_name, ((phpdbg_breakopline_t*)brake)->opline_num); } break; case PHPDBG_BREAK_FILE_OPLINE: { fprintf(handle, - "break %s:#%ld\n", + "break %s:#%llu\n", ((phpdbg_breakopline_t*)brake)->class_name, ((phpdbg_breakopline_t*)brake)->opline_num); } break; @@ -214,8 +198,8 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ } break; } } - } - } + } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); } } /* }}} */ @@ -223,58 +207,116 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML { php_stream_statbuf ssb; char realpath[MAXPATHLEN]; - - if (php_stream_stat_path(path, &ssb) != FAILURE) { - if (ssb.sb.st_mode & (S_IFREG|S_IFLNK)) { - HashTable *broken; - phpdbg_breakfile_t new_break; - size_t path_len = 0L; - - if (VCWD_REALPATH(path, realpath)) { - path = realpath; - } - path_len = strlen(path); - - if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], - path, path_len, (void**)&broken) == FAILURE) { - HashTable breaks; + const char *original_path = path; + zend_bool pending; - zend_hash_init(&breaks, 8, NULL, phpdbg_file_breaks_dtor, 0); + HashTable *broken, *file_breaks = &PHPDBG_G(bp)[PHPDBG_BREAK_FILE]; + phpdbg_breakfile_t new_break; + size_t path_len = 0L; - zend_hash_update(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], - path, path_len, &breaks, sizeof(HashTable), - (void**)&broken); + if (VCWD_REALPATH(path, realpath)) { + path = realpath; + } + path_len = strlen(path); + + if (!zend_hash_str_exists(&PHPDBG_G(file_sources), path, path_len)) { + if (php_stream_stat_path(path, &ssb) == FAILURE) { + if (original_path[0] == '/') { + phpdbg_error("breakpoint", "type=\"nofile\" add=\"fail\" file=\"%s\"", "Cannot stat %s, it does not exist", original_path); + return; } - if (!zend_hash_index_exists(broken, line_num)) { - PHPDBG_G(flags) |= PHPDBG_HAS_FILE_BP; + file_breaks = &PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING]; + path = original_path; + path_len = strlen(path); + pending = 1; + } else if (!(ssb.sb.st_mode & (S_IFREG|S_IFLNK))) { + phpdbg_error("breakpoint", "type=\"notregular\" add=\"fail\" file=\"%s\"", "Cannot set breakpoint in %s, it is not a regular file", path); + return; + } + } + + if (!(broken = zend_hash_str_find_ptr(file_breaks, path, path_len))) { + HashTable breaks; + zend_hash_init(&breaks, 8, NULL, phpdbg_file_breaks_dtor, 0); - PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_FILE); - new_break.filename = estrndup(path, path_len); - new_break.line = line_num; + broken = zend_hash_str_add_mem(file_breaks, path, path_len, &breaks, sizeof(HashTable)); + } - zend_hash_index_update( - broken, line_num, (void**)&new_break, sizeof(phpdbg_breakfile_t), NULL); + if (!zend_hash_index_exists(broken, line_num)) { + PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_FILE); + new_break.filename = estrndup(path, path_len); + new_break.line = line_num; - phpdbg_notice("Breakpoint #%d added at %s:%ld", - new_break.id, new_break.filename, new_break.line); + zend_hash_index_update_mem(broken, line_num, &new_break, sizeof(phpdbg_breakfile_t)); - PHPDBG_BREAK_MAPPING(new_break.id, broken); - } else { - phpdbg_error("Breakpoint at %s:%ld exists", path, line_num); - } + if (pending) { + PHPDBG_G(flags) |= PHPDBG_HAS_PENDING_FILE_BP; + phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" file=\"%s\" line=\"%ld\" pending=\"pending\"", "Pending breakpoint #%d added at %s:%ld", new_break.id, new_break.filename, new_break.line); } else { - phpdbg_error("Cannot set breakpoint in %s, it is not a regular file", path); + PHPDBG_G(flags) |= PHPDBG_HAS_FILE_BP; + + phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" file=\"%s\" line=\"%ld\"", "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("Cannot stat %s, it does not exist", path); + phpdbg_error("breakpoint", "type=\"exists\" add=\"fail\" file=\"%s\" line=\"%ld\"", "Breakpoint at %s:%ld exists", path, line_num); } } /* }}} */ +PHPDBG_API void phpdbg_resolve_pending_file_break(const char *file TSRMLS_DC) /* {{{ */ +{ + HashTable *fileht; + uint filelen = strlen(file); + zend_string *cur; + + ZEND_HASH_FOREACH_STR_KEY_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], cur, fileht) { + if (cur->len < filelen && file[filelen - cur->len - 1] == '/' && !memcmp(file + filelen - cur->len, cur->val, cur->len)) { + phpdbg_breakfile_t *brake, new_brake; + HashTable *master; + dtor_func_t dtor; + + PHPDBG_G(flags) |= PHPDBG_HAS_FILE_BP; + + if (!(master = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], file, filelen))) { + dtor = PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING].pDestructor; + PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING].pDestructor = NULL; + fileht = zend_hash_str_add_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], file, filelen, fileht, sizeof(HashTable)); + } + + ZEND_HASH_FOREACH_PTR(fileht, brake) { + new_brake = *brake; + new_brake.filename = estrndup(file, filelen); + PHPDBG_BREAK_UNMAPPING(brake->id); + + if (master) { + zend_hash_index_update_mem(master, brake->line, &new_brake, sizeof(phpdbg_breakfile_t)); + PHPDBG_BREAK_MAPPING(brake->id, master); + } else { + efree((char *) brake->filename); + *brake = new_brake; + PHPDBG_BREAK_MAPPING(brake->id, fileht); + } + } ZEND_HASH_FOREACH_END(); + + zend_hash_del(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], cur); + + if (!master) { + PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING].pDestructor = dtor; + } + + if (!zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING])) { + PHPDBG_G(flags) &= ~PHPDBG_HAS_PENDING_FILE_BP; + } + } + } ZEND_HASH_FOREACH_END(); +} /* }}} */ + PHPDBG_API void phpdbg_set_breakpoint_symbol(const char *name, size_t name_len TSRMLS_DC) /* {{{ */ { - if (!zend_hash_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], name, name_len)) { + if (!zend_hash_str_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], name, name_len)) { phpdbg_breaksymbol_t new_break; PHPDBG_G(flags) |= PHPDBG_HAS_SYM_BP; @@ -282,15 +324,13 @@ PHPDBG_API void phpdbg_set_breakpoint_symbol(const char *name, size_t name_len T PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_SYM); new_break.symbol = estrndup(name, name_len); - zend_hash_update(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], new_break.symbol, - name_len, &new_break, sizeof(phpdbg_breaksymbol_t), NULL); + zend_hash_str_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], new_break.symbol, name_len, &new_break, sizeof(phpdbg_breaksymbol_t)); - phpdbg_notice("Breakpoint #%d added at %s", - new_break.id, new_break.symbol); + phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" function=\"%s\"", "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); + phpdbg_error("breakpoint", "type=\"exists\" add=\"fail\" function=\"%s\"", "Breakpoint exists at %s", name); } } /* }}} */ @@ -301,16 +341,12 @@ PHPDBG_API void phpdbg_set_breakpoint_method(const char *class_name, const char size_t func_len = strlen(func_name); char *lcname = zend_str_tolower_dup(func_name, func_len); - if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], class_name, - class_len, (void**)&class_table) != SUCCESS) { + if (!(class_table = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], class_name, class_len))) { zend_hash_init(&class_breaks, 8, NULL, phpdbg_class_breaks_dtor, 0); - zend_hash_update( - &PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], - class_name, class_len, - (void**)&class_breaks, sizeof(HashTable), (void**)&class_table); + class_table = zend_hash_str_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], class_name, class_len, &class_breaks, sizeof(HashTable)); } - if (!zend_hash_exists(class_table, lcname, func_len)) { + if (!zend_hash_str_exists(class_table, lcname, func_len)) { phpdbg_breakmethod_t new_break; PHPDBG_G(flags) |= PHPDBG_HAS_METHOD_BP; @@ -321,15 +357,13 @@ 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; - zend_hash_update(class_table, lcname, func_len, - &new_break, sizeof(phpdbg_breakmethod_t), NULL); + zend_hash_str_update_mem(class_table, lcname, func_len, &new_break, sizeof(phpdbg_breakmethod_t)); - phpdbg_notice("Breakpoint #%d added at %s::%s", - new_break.id, class_name, func_name); + phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" method=\"%s::%s\"", "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); + phpdbg_error("breakpoint", "type=\"exists\" add=\"fail\" method=\"%s::%s\"", "Breakpoint exists at %s::%s", class_name, func_name); } efree(lcname); @@ -347,14 +381,12 @@ PHPDBG_API void phpdbg_set_breakpoint_opline(zend_ulong opline TSRMLS_DC) /* {{{ new_break.opline = opline; new_break.base = NULL; - zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline, - &new_break, sizeof(phpdbg_breakline_t), NULL); + zend_hash_index_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline, &new_break, sizeof(phpdbg_breakline_t)); - phpdbg_notice("Breakpoint #%d added at %#lx", - new_break.id, new_break.opline); + phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" opline=\"%#lx\"", "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); + phpdbg_error("breakpoint", "type=\"exists\" add=\"fail\" opline=\"%#lx\"", "Breakpoint exists at %#lx", opline); } } /* }}} */ @@ -363,11 +395,11 @@ PHPDBG_API int phpdbg_resolve_op_array_break(phpdbg_breakopline_t *brake, zend_o phpdbg_breakline_t opline_break; if (op_array->last <= brake->opline_num) { if (brake->class_name == NULL) { - phpdbg_error("There are only %d oplines in function %s (breaking at opline %ld impossible)", op_array->last, brake->func_name, brake->opline_num); + phpdbg_error("breakpoint", "type=\"maxoplines\" add=\"fail\" maxoplinenum=\"%d\" function=\"%s\" usedoplinenum=\"%ld\"", "There are only %d oplines in function %s (breaking at opline %ld impossible)", op_array->last, brake->func_name, brake->opline_num); } else if (brake->func_name == NULL) { - phpdbg_error("There are only %d oplines in file %s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->opline_num); + phpdbg_error("breakpoint", "type=\"maxoplines\" add=\"fail\" maxoplinenum=\"%d\" file=\"%s\" usedoplinenum=\"%ld\"", "There are only %d oplines in file %s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->opline_num); } else { - phpdbg_error("There are only %d oplines in method %s::%s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->func_name, brake->opline_num); + phpdbg_error("breakpoint", "type=\"maxoplines\" add=\"fail\" maxoplinenum=\"%d\" method=\"%s::%s\" usedoplinenum=\"%ld\"", "There are only %d oplines in method %s::%s (breaking at opline %ld impossible)", op_array->last, brake->class_name, brake->func_name, brake->opline_num); } return FAILURE; @@ -389,7 +421,7 @@ PHPDBG_API int phpdbg_resolve_op_array_break(phpdbg_breakopline_t *brake, zend_o PHPDBG_G(flags) |= PHPDBG_HAS_OPLINE_BP; - zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline_break.opline, &opline_break, sizeof(phpdbg_breakline_t), NULL); + zend_hash_index_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline_break.opline, &opline_break, sizeof(phpdbg_breakline_t)); return SUCCESS; } /* }}} */ @@ -398,40 +430,36 @@ PHPDBG_API void phpdbg_resolve_op_array_breaks(zend_op_array *op_array TSRMLS_DC { HashTable *func_table = &PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE]; HashTable *oplines_table; - HashPosition position; phpdbg_breakopline_t *brake; - if (op_array->scope != NULL && - zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], op_array->scope->name, op_array->scope->name_length, (void **)&func_table) == FAILURE) { + if (op_array->scope != NULL && !(func_table = zend_hash_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], op_array->scope->name))) { return; } if (op_array->function_name == NULL) { - if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], op_array->filename, strlen(op_array->filename), (void **)&oplines_table) == FAILURE) { + if (!(oplines_table = zend_hash_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], op_array->filename))) { return; } - } else if (zend_hash_find(func_table, op_array->function_name?op_array->function_name:"", op_array->function_name?strlen(op_array->function_name):0, (void **)&oplines_table) == FAILURE) { + } else if (!op_array->function_name || !(oplines_table = zend_hash_find_ptr(func_table, op_array->function_name))) { return; } - for (zend_hash_internal_pointer_reset_ex(oplines_table, &position); - zend_hash_get_current_data_ex(oplines_table, (void**) &brake, &position) == SUCCESS; - zend_hash_move_forward_ex(oplines_table, &position)) { + ZEND_HASH_FOREACH_PTR(oplines_table, brake) { if (phpdbg_resolve_op_array_break(brake, op_array TSRMLS_CC) == SUCCESS) { phpdbg_breakline_t *opline_break; zend_hash_internal_pointer_end(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]); - zend_hash_get_current_data(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (void **)&opline_break); + opline_break = zend_hash_get_current_data_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]); - phpdbg_notice("Breakpoint #%d resolved at %s%s%s#%ld (opline %#lx)", + phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" symbol=\"%s\" num=\"%ld\" opline=\"%#lx\"", "Breakpoint #%d resolved at %s%s%s#%ld (opline %#lx)", brake->id, - brake->class_name?brake->class_name:"", - brake->class_name&&brake->func_name?"::":"", - brake->func_name?brake->func_name:"", + brake->class_name ? brake->class_name : "", + brake->class_name && brake->func_name ? "::" : "", + brake->func_name ? brake->func_name : "", brake->opline_num, brake->opline); } - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRMLS_DC) /* {{{ */ @@ -452,8 +480,9 @@ PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRML } else { zend_execute_data *execute_data = EG(current_execute_data); do { - if (execute_data->op_array->function_name == NULL && execute_data->op_array->scope == NULL && !memcmp(execute_data->op_array->filename, new_break->class_name, new_break->class_len)) { - if (phpdbg_resolve_op_array_break(new_break, execute_data->op_array TSRMLS_CC) == SUCCESS) { + zend_op_array *op_array = &execute_data->func->op_array; + if (op_array->function_name == NULL && op_array->scope == NULL && new_break->class_len == op_array->filename->len && !memcmp(op_array->filename->val, new_break->class_name, new_break->class_len)) { + if (phpdbg_resolve_op_array_break(new_break, op_array TSRMLS_CC) == SUCCESS) { return SUCCESS; } else { return 2; @@ -465,16 +494,16 @@ PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRML } if (new_break->class_name != NULL) { - zend_class_entry **ce; - if (zend_hash_find(EG(class_table), zend_str_tolower_dup(new_break->class_name, new_break->class_len), new_break->class_len + 1, (void **)&ce) == FAILURE) { + zend_class_entry *ce; + if (!(ce = zend_hash_str_find_ptr(EG(class_table), zend_str_tolower_dup(new_break->class_name, new_break->class_len), new_break->class_len))) { return FAILURE; } - func_table = &(*ce)->function_table; + func_table = &ce->function_table; } - if (zend_hash_find(func_table, zend_str_tolower_dup(new_break->func_name, new_break->func_len), new_break->func_len + 1, (void **)&func) == FAILURE) { + if (!(func = zend_hash_str_find_ptr(func_table, zend_str_tolower_dup(new_break->func_name, new_break->func_len), new_break->func_len))) { if (new_break->class_name != NULL && new_break->func_name != NULL) { - phpdbg_error("Method %s doesn't exist in class %s", new_break->func_name, new_break->class_name); + phpdbg_error("breakpoint", "type=\"nomethod\" method=\"%s::%s\"", "Method %s doesn't exist in class %s", new_break->func_name, new_break->class_name); return 2; } return FAILURE; @@ -482,9 +511,9 @@ PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRML if (func->type != ZEND_USER_FUNCTION) { if (new_break->class_name == NULL) { - phpdbg_error("%s is not an user defined function, no oplines exist", new_break->func_name); + phpdbg_error("breakpoint", "type=\"internalfunction\" function=\"%s\"", "%s is not an user defined function, no oplines exist", new_break->func_name); } else { - phpdbg_error("%s::%s is not an user defined method, no oplines exist", new_break->class_name, new_break->func_name); + phpdbg_error("breakpoint", "type=\"internalfunction\" method=\"%s::%s\"", "%s::%s is not an user defined method, no oplines exist", new_break->class_name, new_break->func_name); } return 2; } @@ -512,37 +541,29 @@ PHPDBG_API void phpdbg_set_breakpoint_method_opline(const char *class, const cha switch (phpdbg_resolve_opline_break(&new_break TSRMLS_CC)) { case FAILURE: - phpdbg_notice("Pending breakpoint #%d at %s::%s#%ld", new_break.id, new_break.class_name, new_break.func_name, opline); + phpdbg_notice("breakpoint", "pending=\"pending\" id=\"%d\" method=\"%::%s\" num=\"%ld\"", "Pending breakpoint #%d at %s::%s#%ld", new_break.id, new_break.class_name, new_break.func_name, opline); break; case SUCCESS: - phpdbg_notice("Breakpoint #%d added at %s::%s#%ld", new_break.id, new_break.class_name, new_break.func_name, opline); + phpdbg_notice("breakpoint", "id=\"%d\" method=\"%::%s\" num=\"%ld\"", "Breakpoint #%d added at %s::%s#%ld", new_break.id, new_break.class_name, new_break.func_name, opline); break; case 2: return; } - if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], new_break.class_name, new_break.class_len, (void **)&class_table) == FAILURE) { + if (!(class_table = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], new_break.class_name, new_break.class_len))) { zend_hash_init(&class_breaks, 8, NULL, phpdbg_opline_class_breaks_dtor, 0); - zend_hash_update( - &PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], - new_break.class_name, - new_break.class_len, - (void **)&class_breaks, sizeof(HashTable), (void **)&class_table); + class_table = zend_hash_str_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], new_break.class_name, new_break.class_len, &class_breaks, sizeof(HashTable)); } - if (zend_hash_find(class_table, new_break.func_name, new_break.func_len, (void **)&method_table) == FAILURE) { + if (!(method_table = zend_hash_str_find_ptr(class_table, new_break.func_name, new_break.func_len))) { zend_hash_init(&method_breaks, 8, NULL, phpdbg_opline_breaks_dtor, 0); - zend_hash_update( - class_table, - new_break.func_name, - new_break.func_len, - (void **)&method_breaks, sizeof(HashTable), (void **)&method_table); + method_table = zend_hash_str_update_mem(class_table, new_break.func_name, new_break.func_len, &method_breaks, sizeof(HashTable)); } if (zend_hash_index_exists(method_table, opline)) { - phpdbg_notice("Breakpoint already exists for %s::%s#%ld", new_break.class_name, new_break.func_name, opline); + phpdbg_error("breakpoint", "type=\"exists\" method=\"%s\" num=\"%ld\"", "Breakpoint already exists for %s::%s#%ld", new_break.class_name, new_break.func_name, opline); efree((char*)new_break.func_name); efree((char*)new_break.class_name); PHPDBG_G(bp_count)--; @@ -553,7 +574,7 @@ PHPDBG_API void phpdbg_set_breakpoint_method_opline(const char *class, const cha PHPDBG_BREAK_MAPPING(new_break.id, method_table); - zend_hash_index_update(method_table, opline, &new_break, sizeof(phpdbg_breakopline_t), NULL); + zend_hash_index_update_mem(method_table, opline, &new_break, sizeof(phpdbg_breakopline_t)); } PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, zend_ulong opline TSRMLS_DC) /* {{{ */ @@ -571,28 +592,24 @@ PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, zend switch (phpdbg_resolve_opline_break(&new_break TSRMLS_CC)) { case FAILURE: - phpdbg_notice("Pending breakpoint #%d at %s#%ld", new_break.id, new_break.func_name, opline); + phpdbg_notice("breakpoint", "pending=\"pending\" id=\"%d\" function=\"%s\" num=\"%ld\"", "Pending breakpoint #%d at %s#%ld", new_break.id, new_break.func_name, opline); break; case SUCCESS: - phpdbg_notice("Breakpoint #%d added at %s#%ld", new_break.id, new_break.func_name, opline); + phpdbg_notice("breakpoint", "id=\"%d\" function=\"%s\" num=\"%ld\"", "Breakpoint #%d added at %s#%ld", new_break.id, new_break.func_name, opline); break; case 2: return; } - if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], new_break.func_name, new_break.func_len, (void **)&func_table) == FAILURE) { + if (!(func_table = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], new_break.func_name, new_break.func_len))) { zend_hash_init(&func_breaks, 8, NULL, phpdbg_opline_breaks_dtor, 0); - zend_hash_update( - &PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], - new_break.func_name, - new_break.func_len, - (void **)&func_breaks, sizeof(HashTable), (void **)&func_table); + func_table = zend_hash_str_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], new_break.func_name, new_break.func_len, &func_breaks, sizeof(HashTable)); } if (zend_hash_index_exists(func_table, opline)) { - phpdbg_notice("Breakpoint already exists for %s#%ld", new_break.func_name, opline); + phpdbg_error("breakpoint", "type=\"exists\" function=\"%s\" num=\"%ld\"", "Breakpoint already exists for %s#%ld", new_break.func_name, opline); efree((char*)new_break.func_name); PHPDBG_G(bp_count)--; return; @@ -602,7 +619,7 @@ PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, zend PHPDBG_G(flags) |= PHPDBG_HAS_FUNCTION_OPLINE_BP; - zend_hash_index_update(func_table, opline, &new_break, sizeof(phpdbg_breakopline_t), NULL); + zend_hash_index_update_mem(func_table, opline, &new_break, sizeof(phpdbg_breakopline_t)); } PHPDBG_API void phpdbg_set_breakpoint_file_opline(const char *file, zend_ulong opline TSRMLS_DC) /* {{{ */ @@ -620,28 +637,24 @@ PHPDBG_API void phpdbg_set_breakpoint_file_opline(const char *file, zend_ulong o switch (phpdbg_resolve_opline_break(&new_break TSRMLS_CC)) { case FAILURE: - phpdbg_notice("Pending breakpoint #%d at %s:%ld", new_break.id, new_break.class_name, opline); + phpdbg_notice("breakpoint", "pending=\"pending\" id=\"%d\" file=\"%s\" num=\"%ld\"", "Pending breakpoint #%d at %s:%ld", new_break.id, new_break.class_name, opline); break; case SUCCESS: - phpdbg_notice("Breakpoint #%d added at %s:%ld", new_break.id, new_break.class_name, opline); + phpdbg_notice("breakpoint", "id=\"%d\" file=\"%s\" num=\"%ld\"", "Breakpoint #%d added at %s:%ld", new_break.id, new_break.class_name, opline); break; case 2: return; } - if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], new_break.class_name, new_break.class_len, (void **)&file_table) == FAILURE) { + if (!(file_table = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], new_break.class_name, new_break.class_len))) { zend_hash_init(&file_breaks, 8, NULL, phpdbg_opline_breaks_dtor, 0); - zend_hash_update( - &PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], - new_break.class_name, - new_break.class_len, - (void **)&file_breaks, sizeof(HashTable), (void **)&file_table); + file_table = zend_hash_str_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], new_break.class_name, new_break.class_len, &file_breaks, sizeof(HashTable)); } if (zend_hash_index_exists(file_table, opline)) { - phpdbg_notice("Breakpoint already exists for %s:%ld", new_break.class_name, opline); + phpdbg_error("breakpoint", "type=\"exists\" file=\"%s\" num=\"%d\"", "Breakpoint already exists for %s:%ld", new_break.class_name, opline); efree((char*)new_break.class_name); PHPDBG_G(bp_count)--; return; @@ -651,7 +664,7 @@ PHPDBG_API void phpdbg_set_breakpoint_file_opline(const char *file, zend_ulong o PHPDBG_G(flags) |= PHPDBG_HAS_FILE_OPLINE_BP; - zend_hash_index_update(file_table, opline, &new_break, sizeof(phpdbg_breakopline_t), NULL); + zend_hash_index_update_mem(file_table, opline, &new_break, sizeof(phpdbg_breakopline_t)); } PHPDBG_API void phpdbg_set_breakpoint_opcode(const char *name, size_t name_len TSRMLS_DC) /* {{{ */ @@ -660,8 +673,7 @@ PHPDBG_API void phpdbg_set_breakpoint_opcode(const char *name, size_t name_len T zend_ulong hash = zend_hash_func(name, name_len); if (zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], hash)) { - phpdbg_notice( - "Breakpoint exists for %s", name); + phpdbg_error("breakpoint", "type=\"exists\" opcode=\"%s\"", "Breakpoint exists for %s", name); return; } @@ -669,12 +681,11 @@ 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); - zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], hash, - &new_break, sizeof(phpdbg_breakop_t), NULL); + zend_hash_index_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], hash, &new_break, sizeof(phpdbg_breakop_t)); PHPDBG_G(flags) |= PHPDBG_HAS_OPCODE_BP; - phpdbg_notice("Breakpoint #%d added at %s", new_break.id, name); + phpdbg_notice("breakpoint", "id=\"%d\" opcode=\"%s\"", "Breakpoint #%d added at %s", new_break.id, name); PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE]); } /* }}} */ @@ -688,12 +699,12 @@ PHPDBG_API void phpdbg_set_breakpoint_opline_ex(phpdbg_opline_ptr_t opline TSRML PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_OPLINE); new_break.opline = (zend_ulong) opline; - zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], - (zend_ulong) opline, &new_break, sizeof(phpdbg_breakline_t), NULL); + zend_hash_index_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (zend_ulong) opline, &new_break, sizeof(phpdbg_breakline_t)); - phpdbg_notice("Breakpoint #%d added at %#lx", - new_break.id, new_break.opline); + phpdbg_notice("breakpoint", "id=\"%d\" opline=\"%#lx\"", "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_error("breakpoint", "type=\"exists\" opline=\"%#lx\"", "Breakpoint exists for opline %#lx", (zend_ulong) opline); } } /* }}} */ @@ -721,35 +732,30 @@ static inline void phpdbg_create_conditional_break(phpdbg_breakcond_t *brake, co new_break.code = estrndup(expr, expr_len); new_break.code_len = expr_len; - Z_STRLEN(pv) = expr_len + sizeof("return ;") - 1; - Z_STRVAL(pv) = emalloc(Z_STRLEN(pv) + 1); + Z_STR(pv) = zend_string_alloc(expr_len + sizeof("return ;") - 1, 0); memcpy(Z_STRVAL(pv), "return ", sizeof("return ") - 1); memcpy(Z_STRVAL(pv) + sizeof("return ") - 1, expr, expr_len); Z_STRVAL(pv)[Z_STRLEN(pv) - 1] = ';'; Z_STRVAL(pv)[Z_STRLEN(pv)] = '\0'; - Z_TYPE(pv) = IS_STRING; + Z_TYPE_INFO(pv) = IS_STRING; - new_break.ops = zend_compile_string( - &pv, "Conditional Breakpoint Code" TSRMLS_CC); + new_break.ops = zend_compile_string(&pv, "Conditional Breakpoint Code" TSRMLS_CC); zval_dtor(&pv); if (new_break.ops) { - zend_hash_index_update( - &PHPDBG_G(bp)[PHPDBG_BREAK_COND], hash, &new_break, - sizeof(phpdbg_breakcond_t), (void**)&brake); + brake = zend_hash_index_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], hash, &new_break, sizeof(phpdbg_breakcond_t)); - phpdbg_notice("Conditional breakpoint #%d added %s/%p", - brake->id, brake->code, brake->ops); + phpdbg_notice("breakpoint", "id=\"%d\" expression=\"%s\" ptr=\"%p\"", "Conditional breakpoint #%d added %s/%p", brake->id, 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); + phpdbg_error("compile", "expression=\"%s\"", "Failed to compile code for expression %s", expr); efree((char*)new_break.code); PHPDBG_G(bp_count)--; } + CG(compiler_options) = cops; } /* }}} */ @@ -762,7 +768,7 @@ PHPDBG_API void phpdbg_set_breakpoint_expression(const char *expr, size_t expr_l phpdbg_create_conditional_break( &new_break, NULL, expr, expr_len, expr_hash TSRMLS_CC); } else { - phpdbg_notice("Conditional break %s exists", expr); + phpdbg_error("breakpoint", "type=\"exists\" expression=\"%s\"", "Conditional break %s exists", expr); } } /* }}} */ @@ -771,35 +777,30 @@ PHPDBG_API void phpdbg_set_breakpoint_at(const phpdbg_param_t *param TSRMLS_DC) phpdbg_breakcond_t new_break; phpdbg_param_t *condition; zend_ulong hash = 0L; - + if (param->next) { condition = param->next; hash = zend_inline_hash_func(condition->str, condition->len); - + if (!zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], hash)) { - phpdbg_create_conditional_break( - &new_break, param, - condition->str, condition->len, hash TSRMLS_CC); + phpdbg_create_conditional_break(&new_break, param, condition->str, condition->len, hash TSRMLS_CC); } else { - phpdbg_notice( - "Conditional break %s exists at the specified location", condition->str); - } + phpdbg_notice("breakpoint", "type=\"exists\" arg=\"%s\"", "Conditional break %s exists at the specified location", condition->str); + } } - + } /* }}} */ static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_file(zend_op_array *op_array TSRMLS_DC) /* {{{ */ { HashTable *breaks; phpdbg_breakbase_t *brake; - size_t name_len = strlen(op_array->filename); - if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], op_array->filename, - name_len, (void**)&breaks) == FAILURE) { + if (!(breaks = zend_hash_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], op_array->filename))) { return NULL; } - if (zend_hash_index_find(breaks, (*EG(opline_ptr))->lineno, (void**)&brake) == SUCCESS) { + if (EG(current_execute_data) && (brake = zend_hash_index_find_ptr(breaks, EG(current_execute_data)->opline->lineno))) { return brake; } @@ -809,88 +810,73 @@ static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_file(zend_op_array *op_ static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_symbol(zend_function *fbc TSRMLS_DC) /* {{{ */ { const char *fname; + size_t flen; zend_op_array *ops; - phpdbg_breakbase_t *brake; if (fbc->type != ZEND_USER_FUNCTION) { return NULL; } - ops = (zend_op_array*)fbc; + ops = (zend_op_array *) fbc; if (ops->scope) { /* find method breaks here */ return phpdbg_find_breakpoint_method(ops TSRMLS_CC); } - fname = ops->function_name; - - if (!fname) { + if (ops->function_name) { + fname = ops->function_name->val; + flen = ops->function_name->len; + } else { fname = "main"; + flen = 4; } - if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], fname, strlen(fname), (void**)&brake) == SUCCESS) { - return brake; - } - - return NULL; + return zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], fname, flen); } /* }}} */ static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_method(zend_op_array *ops TSRMLS_DC) /* {{{ */ { HashTable *class_table; - phpdbg_breakbase_t *brake; + phpdbg_breakbase_t *brake = NULL; - if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], ops->scope->name, - ops->scope->name_length, (void**)&class_table) == SUCCESS) { - char *lcname = zend_str_tolower_dup(ops->function_name, strlen(ops->function_name)); - size_t lcname_len = strlen(lcname); - - if (zend_hash_find( - class_table, - lcname, - lcname_len, (void**)&brake) == SUCCESS) { - efree(lcname); - return brake; - } + if ((class_table = zend_hash_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], ops->scope->name))) { + size_t lcname_len = ops->function_name->len; + char *lcname = zend_str_tolower_dup(ops->function_name->val, lcname_len); + + brake = zend_hash_str_find_ptr(class_table, lcname, lcname_len); efree(lcname); } - return NULL; + return brake; } /* }}} */ static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_opline(phpdbg_opline_ptr_t opline TSRMLS_DC) /* {{{ */ { phpdbg_breakline_t *brake; - if (zend_hash_index_find(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], - (zend_ulong) opline, (void**)&brake) == SUCCESS) { - return (brake->base?(phpdbg_breakbase_t *)brake->base:(phpdbg_breakbase_t *)brake); + if ((brake = zend_hash_index_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (zend_ulong) opline)) && brake->base) { + return (phpdbg_breakbase_t *)brake->base; } - return NULL; + return (phpdbg_breakbase_t *) brake; } /* }}} */ static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_opcode(zend_uchar opcode TSRMLS_DC) /* {{{ */ { - phpdbg_breakbase_t *brake; const char *opname = phpdbg_decode_opcode(opcode); if (memcmp(opname, PHPDBG_STRL("UNKNOWN")) == 0) { return NULL; } - if (zend_hash_index_find(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], - zend_hash_func(opname, strlen(opname)), (void**)&brake) == SUCCESS) { - return brake; - } - return NULL; + return zend_hash_index_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], zend_hash_func(opname, strlen(opname))); } /* }}} */ static inline zend_bool phpdbg_find_breakpoint_param(phpdbg_param_t *param, zend_execute_data *execute_data TSRMLS_DC) /* {{{ */ { - zend_function *function = (zend_function*) execute_data->function_state.function; + zend_function *function = execute_data->func; switch (param->type) { case NUMERIC_FUNCTION_PARAM: @@ -905,8 +891,8 @@ static inline zend_bool phpdbg_find_breakpoint_param(phpdbg_param_t *param, zend const char *str = NULL; size_t len = 0L; zend_op_array *ops = (zend_op_array*)function; - str = ops->function_name ? ops->function_name : "main"; - len = strlen(str); + str = ops->function_name ? ops->function_name->val : "main"; + len = ops->function_name ? ops->function_name->len : strlen(str); if (len == param->len && memcmp(param->str, str, len) == SUCCESS) { return param->type == STR_PARAM || execute_data->opline - ops->opcodes == param->num; @@ -936,10 +922,10 @@ static inline zend_bool phpdbg_find_breakpoint_param(phpdbg_param_t *param, zend zend_op_array *ops = (zend_op_array*) function; if (ops->scope) { - size_t lengths[2] = {strlen(param->method.class), ops->scope->name_length}; + size_t lengths[2] = { strlen(param->method.class), ops->scope->name->len }; if (lengths[0] == lengths[1] && memcmp(param->method.class, ops->scope->name, lengths[0]) == SUCCESS) { lengths[0] = strlen(param->method.name); - lengths[1] = strlen(ops->function_name); + lengths[1] = ops->function_name->len; if (lengths[0] == lengths[1] && memcmp(param->method.name, ops->function_name, lengths[0]) == SUCCESS) { return param->type == METHOD_PARAM || (execute_data->opline - ops->opcodes) == param->num; @@ -963,16 +949,13 @@ static inline zend_bool phpdbg_find_breakpoint_param(phpdbg_param_t *param, zend static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */ { phpdbg_breakcond_t *bp; - HashPosition position; int breakpoint = FAILURE; - 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*)&bp, &position) == SUCCESS; - zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) { - zval *retval = NULL; - zval **orig_retval = EG(return_value_ptr_ptr); - zend_op_array *orig_ops = EG(active_op_array); - zend_op **orig_opline = EG(opline_ptr); + ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], bp) { + zval retval; + const zend_op *orig_opline = EG(current_execute_data)->opline; + zend_function *orig_func = EG(current_execute_data)->func; + zval *orig_retval = EG(current_execute_data)->return_value; if (((phpdbg_breakbase_t*)bp)->disabled) { continue; @@ -984,49 +967,37 @@ static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execut } } - ALLOC_INIT_ZVAL(retval); - - EG(return_value_ptr_ptr) = &retval; - EG(active_op_array) = bp->ops; EG(no_extensions) = 1; - if (!EG(active_symbol_table)) { - zend_rebuild_symbol_table(TSRMLS_C); - } + zend_rebuild_symbol_table(TSRMLS_C); zend_try { PHPDBG_G(flags) |= PHPDBG_IN_COND_BP; - zend_execute(EG(active_op_array) TSRMLS_CC); + zend_execute(bp->ops, &retval TSRMLS_CC); #if PHP_VERSION_ID >= 50700 - if (zend_is_true(retval TSRMLS_CC)) { + if (zend_is_true(&retval TSRMLS_CC)) { #else - if (zend_is_true(retval)) { + if (zend_is_true(&retval)) { #endif breakpoint = SUCCESS; } - } zend_catch { - EG(no_extensions)=1; - EG(return_value_ptr_ptr) = orig_retval; - EG(active_op_array) = orig_ops; - EG(opline_ptr) = orig_opline; - PHPDBG_G(flags) &= ~PHPDBG_IN_COND_BP; } zend_end_try(); - EG(no_extensions)=1; - EG(return_value_ptr_ptr) = orig_retval; - EG(active_op_array) = orig_ops; - EG(opline_ptr) = orig_opline; + EG(no_extensions) = 1; + EG(current_execute_data)->opline = orig_opline; + EG(current_execute_data)->func = orig_func; + EG(current_execute_data)->return_value = orig_retval; PHPDBG_G(flags) &= ~PHPDBG_IN_COND_BP; if (breakpoint == SUCCESS) { break; } - } + } ZEND_HASH_FOREACH_END(); - return (breakpoint == SUCCESS) ? ((phpdbg_breakbase_t*)bp) : NULL; + return (breakpoint == SUCCESS) ? ((phpdbg_breakbase_t *) bp) : NULL; } /* }}} */ -PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakpoint(zend_execute_data* execute_data TSRMLS_DC) /* {{{ */ +PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakpoint(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */ { phpdbg_breakbase_t *base = NULL; @@ -1041,28 +1012,24 @@ PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakpoint(zend_execute_data* execute goto result; } - if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_BP) && - (base = phpdbg_find_breakpoint_file(execute_data->op_array TSRMLS_CC))) { + if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_BP) && (base = phpdbg_find_breakpoint_file(&execute_data->func->op_array TSRMLS_CC))) { goto result; } if (PHPDBG_G(flags) & (PHPDBG_HAS_METHOD_BP|PHPDBG_HAS_SYM_BP)) { /* check we are at the beginning of the stack */ - if (execute_data->opline == EG(active_op_array)->opcodes) { - if ((base = phpdbg_find_breakpoint_symbol( - execute_data->function_state.function TSRMLS_CC))) { + if (execute_data->opline == execute_data->func->op_array.opcodes) { + if ((base = phpdbg_find_breakpoint_symbol(execute_data->func TSRMLS_CC))) { goto result; } } } - if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP) && - (base = phpdbg_find_breakpoint_opline(execute_data->opline TSRMLS_CC))) { + if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP) && (base = phpdbg_find_breakpoint_opline((phpdbg_opline_ptr_t) execute_data->opline TSRMLS_CC))) { goto result; } - if ((PHPDBG_G(flags) & PHPDBG_HAS_OPCODE_BP) && - (base = phpdbg_find_breakpoint_opcode(execute_data->opline->opcode TSRMLS_CC))) { + if ((PHPDBG_G(flags) & PHPDBG_HAS_OPCODE_BP) && (base = phpdbg_find_breakpoint_opcode(execute_data->opline->opcode TSRMLS_CC))) { goto result; } @@ -1079,14 +1046,12 @@ result: PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */ { - HashTable **table; - HashPosition position; + HashTable *table; phpdbg_breakbase_t *brake; + zend_string *strkey; + zend_ulong numkey; - if ((brake = phpdbg_find_breakbase_ex(num, &table, &position TSRMLS_CC))) { - char *key; - uint32_t klen; - zend_ulong idx; + if ((brake = phpdbg_find_breakbase_ex(num, &table, &numkey, &strkey TSRMLS_CC))) { int type = brake->type; char *name = NULL; size_t name_len = 0L; @@ -1094,7 +1059,7 @@ PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */ switch (type) { case PHPDBG_BREAK_FILE: case PHPDBG_BREAK_METHOD: - if (zend_hash_num_elements((*table)) == 1) { + 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) { @@ -1104,7 +1069,7 @@ PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */ break; default: { - if (zend_hash_num_elements((*table)) == 1) { + if (zend_hash_num_elements(table) == 1) { PHPDBG_G(flags) &= ~(1<<(brake->type+1)); } } @@ -1117,40 +1082,36 @@ PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */ if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]) == 1) { PHPDBG_G(flags) &= PHPDBG_HAS_OPLINE_BP; } - zend_hash_index_del(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], ((phpdbg_breakopline_t*)brake)->opline); + zend_hash_index_del(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], ((phpdbg_breakopline_t *) brake)->opline); } - 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); + if (strkey) { + zend_hash_del(table, strkey); + } else { + zend_hash_index_del(table, numkey); } switch (type) { case PHPDBG_BREAK_FILE: case PHPDBG_BREAK_METHOD: if (name) { - zend_hash_del(&PHPDBG_G(bp)[type], name, name_len); + zend_hash_str_del(&PHPDBG_G(bp)[type], name, name_len); efree(name); } break; } - phpdbg_notice("Deleted breakpoint #%ld", num); + phpdbg_notice("breakpoint", "deleted=\"success\" id=\"%ld\"", "Deleted breakpoint #%ld", num); PHPDBG_BREAK_UNMAPPING(num); } else { - phpdbg_error("Failed to find breakpoint #%ld", num); + phpdbg_error("breakpoint", "type=\"nobreakpoint\" deleted=\"fail\" id=\"%ld\"", "Failed to find breakpoint #%ld", num); } } /* }}} */ PHPDBG_API void phpdbg_clear_breakpoints(TSRMLS_D) /* {{{ */ { zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE]); + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING]); zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM]); zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]); zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE]); @@ -1182,7 +1143,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* switch (brake->type) { case PHPDBG_BREAK_FILE: { - phpdbg_notice("Breakpoint #%d at %s:%ld, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d at %s:%ld, hits: %lu", ((phpdbg_breakfile_t*)brake)->id, ((phpdbg_breakfile_t*)brake)->filename, ((phpdbg_breakfile_t*)brake)->line, @@ -1190,7 +1151,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* } break; case PHPDBG_BREAK_SYM: { - phpdbg_notice("Breakpoint #%d in %s() at %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" function=\"%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %s() at %s:%u, hits: %lu", ((phpdbg_breaksymbol_t*)brake)->id, ((phpdbg_breaksymbol_t*)brake)->symbol, zend_get_executed_filename(TSRMLS_C), @@ -1199,7 +1160,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* } break; case PHPDBG_BREAK_OPLINE: { - phpdbg_notice("Breakpoint #%d in %#lx at %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" opline=\"%#lx\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %#lx at %s:%u, hits: %lu", ((phpdbg_breakline_t*)brake)->id, ((phpdbg_breakline_t*)brake)->opline, zend_get_executed_filename(TSRMLS_C), @@ -1208,7 +1169,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* } break; case PHPDBG_BREAK_METHOD_OPLINE: { - phpdbg_notice("Breakpoint #%d in %s::%s()#%lu at %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" method=\"%s::%s\" num=\"%lu\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %s::%s()#%lu at %s:%u, hits: %lu", ((phpdbg_breakopline_t*)brake)->id, ((phpdbg_breakopline_t*)brake)->class_name, ((phpdbg_breakopline_t*)brake)->func_name, @@ -1219,7 +1180,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* } break; case PHPDBG_BREAK_FUNCTION_OPLINE: { - phpdbg_notice("Breakpoint #%d in %s()#%lu at %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" num=\"%lu\" function=\"%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %s()#%lu at %s:%u, hits: %lu", ((phpdbg_breakopline_t*)brake)->id, ((phpdbg_breakopline_t*)brake)->func_name, ((phpdbg_breakopline_t*)brake)->opline_num, @@ -1229,9 +1190,8 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* } break; case PHPDBG_BREAK_FILE_OPLINE: { - phpdbg_notice("Breakpoint #%d in %s:%lu at %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" num=\"%lu\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in #%lu at %s:%u, hits: %lu", ((phpdbg_breakopline_t*)brake)->id, - ((phpdbg_breakopline_t*)brake)->class_name, ((phpdbg_breakopline_t*)brake)->opline_num, zend_get_executed_filename(TSRMLS_C), zend_get_executed_lineno(TSRMLS_C), @@ -1239,7 +1199,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* } break; case PHPDBG_BREAK_OPCODE: { - phpdbg_notice("Breakpoint #%d in %s at %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" opcode=\"%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %s at %s:%u, hits: %lu", ((phpdbg_breakop_t*)brake)->id, ((phpdbg_breakop_t*)brake)->name, zend_get_executed_filename(TSRMLS_C), @@ -1248,7 +1208,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* } break; case PHPDBG_BREAK_METHOD: { - phpdbg_notice("Breakpoint #%d in %s::%s() at %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" method=\"%s::%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Breakpoint #%d in %s::%s() at %s:%u, hits: %lu", ((phpdbg_breakmethod_t*)brake)->id, ((phpdbg_breakmethod_t*)brake)->class_name, ((phpdbg_breakmethod_t*)brake)->func_name, @@ -1260,7 +1220,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* case PHPDBG_BREAK_COND: { if (((phpdbg_breakcond_t*)brake)->paramed) { char *param; - phpdbg_notice("Conditional breakpoint #%d: at %s if %s %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" location=\"%s\" eval=\"%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Conditional breakpoint #%d: at %s if %s at %s:%u, hits: %lu", ((phpdbg_breakcond_t*)brake)->id, phpdbg_param_tostring(&((phpdbg_breakcond_t*)brake)->param, ¶m TSRMLS_CC), ((phpdbg_breakcond_t*)brake)->code, @@ -1270,7 +1230,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* if (param) free(param); } else { - phpdbg_notice("Conditional breakpoint #%d: on %s == true %s:%u, hits: %lu", + phpdbg_notice("breakpoint", "id=\"%d\" eval=\"%s\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Conditional breakpoint #%d: on %s == true at %s:%u, hits: %lu", ((phpdbg_breakcond_t*)brake)->id, ((phpdbg_breakcond_t*)brake)->code, zend_get_executed_filename(TSRMLS_C), @@ -1282,7 +1242,7 @@ PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t *brake TSRMLS_DC) /* default: { unknown: - phpdbg_notice("Unknown breakpoint at %s:%u", + phpdbg_notice("breakpoint", "id=\"\" file=\"%s\" line=\"%ld\" hits=\"%lu\"", "Unknown breakpoint at %s:%u", zend_get_executed_filename(TSRMLS_C), zend_get_executed_lineno(TSRMLS_C)); } @@ -1318,313 +1278,249 @@ PHPDBG_API void phpdbg_disable_breakpoints(TSRMLS_D) { /* {{{ */ PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase(zend_ulong id TSRMLS_DC) /* {{{ */ { - HashTable **table; - HashPosition position; + HashTable *table; + zend_string *strkey; + zend_ulong numkey; - return phpdbg_find_breakbase_ex(id, &table, &position TSRMLS_CC); + return phpdbg_find_breakbase_ex(id, &table, &numkey, &strkey TSRMLS_CC); } /* }}} */ -PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable ***table, HashPosition *position TSRMLS_DC) /* {{{ */ +PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable **table, zend_ulong *numkey, zend_string **strkey TSRMLS_DC) /* {{{ */ { - if (zend_hash_index_find(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], id, (void**)table) == SUCCESS) { + if ((*table = zend_hash_index_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], id))) { 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)) { - + ZEND_HASH_FOREACH_KEY_PTR(*table, *numkey, *strkey, brake) { if (brake->id == id) { return brake; } - } + } ZEND_HASH_FOREACH_END(); } + return NULL; } /* }}} */ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ { + phpdbg_xml("<breakpoints %r>"); + switch (type) { case PHPDBG_BREAK_SYM: if ((PHPDBG_G(flags) & PHPDBG_HAS_SYM_BP)) { - HashPosition position; phpdbg_breaksymbol_t *brake; - phpdbg_writeln(SEPARATE); - phpdbg_writeln("Function Breakpoints:"); - 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)) { - phpdbg_writeln("#%d\t\t%s%s", + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Function Breakpoints:\n"); + ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], brake) { + phpdbg_writeln("function", "id=\"%d\" name=\"%s\" disabled=\"%s\"", "#%d\t\t%s%s", brake->id, brake->symbol, - ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); - } + ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : ""); + } ZEND_HASH_FOREACH_END(); } break; case PHPDBG_BREAK_METHOD: if ((PHPDBG_G(flags) & PHPDBG_HAS_METHOD_BP)) { - HashPosition position[2]; HashTable *class_table; - char *class_name = NULL; - uint32_t class_len = 0; - zend_ulong class_idx = 0L; - - phpdbg_writeln(SEPARATE); - phpdbg_writeln("Method Breakpoints:"); - 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])) { - - 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]); - zend_hash_get_current_data_ex(class_table, (void**)&brake, &position[1]) == SUCCESS; - zend_hash_move_forward_ex(class_table, &position[1])) { - phpdbg_writeln("#%d\t\t%s::%s%s", - brake->id, brake->class_name, brake->func_name, - ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); - } - } - } + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Method Breakpoints:\n"); + ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], class_table) { + phpdbg_breakmethod_t *brake; + + ZEND_HASH_FOREACH_PTR(class_table, brake) { + phpdbg_writeln("method", "id=\"%d\" name=\"%s::%s\" disabled=\"%s\"", "#%d\t\t%s::%s%s", + brake->id, brake->class_name, brake->func_name, + ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : ""); + } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); } break; case PHPDBG_BREAK_FILE: if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_BP)) { - 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[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_out(SEPARATE "\n"); + phpdbg_out("File Breakpoints:\n"); + ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], points) { phpdbg_breakfile_t *brake; - 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%s", + ZEND_HASH_FOREACH_PTR(points, brake) { + phpdbg_writeln("file", "id=\"%d\" name=\"%s\" line=\"%lu\" disabled=\"%s\"", "#%d\t\t%s:%lu%s", brake->id, brake->filename, brake->line, - ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); - } - } + ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : ""); + } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); + } if ((PHPDBG_G(flags) & PHPDBG_HAS_PENDING_FILE_BP)) { + HashTable *points; + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Pending File Breakpoints:\n"); + ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], points) { + phpdbg_breakfile_t *brake; + + ZEND_HASH_FOREACH_PTR(points, brake) { + phpdbg_writeln("file", "id=\"%d\" name=\"%s\" line=\"%lu\" disabled=\"%s\" pending=\"pending\"", "#%d\t\t%s:%lu%s", + brake->id, brake->filename, brake->line, + ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : ""); + } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); } break; case PHPDBG_BREAK_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP)) { - HashPosition position; phpdbg_breakline_t *brake; - phpdbg_writeln(SEPARATE); - phpdbg_writeln("Opline Breakpoints:"); - 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)) { + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Opline Breakpoints:\n"); + ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], brake) { + const char *type; switch (brake->type) { case PHPDBG_BREAK_METHOD_OPLINE: + type = "method"; + goto print_opline; case PHPDBG_BREAK_FUNCTION_OPLINE: + type = "function"; + goto print_opline; case PHPDBG_BREAK_FILE_OPLINE: - phpdbg_writeln("#%d\t\t%#lx\t\t(%s breakpoint)%s", brake->id, brake->opline, - brake->type == PHPDBG_BREAK_METHOD_OPLINE?"method": - brake->type == PHPDBG_BREAK_FUNCTION_OPLINE?"function": - brake->type == PHPDBG_BREAK_FILE_OPLINE?"file": - "--- error ---", - ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); - break; + type = "method"; + + print_opline: { + if (brake->type == PHPDBG_BREAK_METHOD_OPLINE) { + type = "method"; + } else if (brake->type == PHPDBG_BREAK_FUNCTION_OPLINE) { + type = "function"; + } else if (brake->type == PHPDBG_BREAK_FILE_OPLINE) { + type = "file"; + } + + phpdbg_writeln("opline", "id=\"%d\" num=\"%#lx\" type=\"%s\" disabled=\"%s\"", "#%d\t\t%#lx\t\t(%s breakpoint)%s", + brake->id, brake->opline, type, + ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : ""); + } break; default: - phpdbg_writeln("#%d\t\t%#lx", brake->id, brake->opline); + phpdbg_writeln("opline", "id=\"%d\" num=\"%#lx\" disabled=\"%s\"", "#%d\t\t%#lx%s", + brake->id, brake->opline, + ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : ""); break; } - } + } ZEND_HASH_FOREACH_END(); } break; case PHPDBG_BREAK_METHOD_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_METHOD_OPLINE_BP)) { - HashPosition position[3]; HashTable *class_table, *method_table; - char *class_name = NULL, *method_name = NULL; - uint32_t class_len = 0, method_len = 0; - zend_ulong class_idx = 0L, method_idx = 0L; - - phpdbg_writeln(SEPARATE); - phpdbg_writeln("Method opline Breakpoints:"); - for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], &position[0]); - zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], (void**) &class_table, &position[0]) == SUCCESS; - zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], &position[0])) { - - if (zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], - &class_name, &class_len, &class_idx, 0, &position[0]) == HASH_KEY_IS_STRING) { - - for (zend_hash_internal_pointer_reset_ex(class_table, &position[1]); - zend_hash_get_current_data_ex(class_table, (void**) &method_table, &position[1]) == SUCCESS; - zend_hash_move_forward_ex(class_table, &position[1])) { - - if (zend_hash_get_current_key_ex(class_table, - &method_name, &method_len, &method_idx, 0, &position[0]) == HASH_KEY_IS_STRING) { - - phpdbg_breakopline_t *brake; - - for (zend_hash_internal_pointer_reset_ex(method_table, &position[2]); - zend_hash_get_current_data_ex(method_table, (void**)&brake, &position[2]) == SUCCESS; - zend_hash_move_forward_ex(method_table, &position[2])) { - phpdbg_writeln("#%d\t\t%s::%s opline %ld%s", - brake->id, brake->class_name, brake->func_name, brake->opline_num, - ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); - } - } - } - } - } + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Method opline Breakpoints:\n"); + ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], class_table) { + ZEND_HASH_FOREACH_PTR(class_table, method_table) { + phpdbg_breakopline_t *brake; + + ZEND_HASH_FOREACH_PTR(method_table, brake) { + phpdbg_writeln("methodopline", "id=\"%d\" name=\"%s::%s\" num=\"%ld\" disabled=\"%s\"", "#%d\t\t%s::%s opline %ld%s", + brake->id, brake->class_name, brake->func_name, brake->opline_num, + ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : ""); + } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); } break; case PHPDBG_BREAK_FUNCTION_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_FUNCTION_OPLINE_BP)) { - HashPosition position[2]; HashTable *function_table; - char *function_name = NULL; - uint32_t function_len = 0; - zend_ulong function_idx = 0L; - - phpdbg_writeln(SEPARATE); - phpdbg_writeln("Function opline Breakpoints:"); - for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], &position[0]); - zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], (void**) &function_table, &position[0]) == SUCCESS; - zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], &position[0])) { - - if (zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], - &function_name, &function_len, &function_idx, 0, &position[0]) == HASH_KEY_IS_STRING) { - phpdbg_breakopline_t *brake; - - for (zend_hash_internal_pointer_reset_ex(function_table, &position[1]); - zend_hash_get_current_data_ex(function_table, (void**)&brake, &position[1]) == SUCCESS; - zend_hash_move_forward_ex(function_table, &position[1])) { - phpdbg_writeln("#%d\t\t%s opline %ld%s", - brake->id, brake->func_name, brake->opline_num, - ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); - } - } - - } + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Function opline Breakpoints:\n"); + ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], function_table) { + phpdbg_breakopline_t *brake; + + ZEND_HASH_FOREACH_PTR(function_table, brake) { + phpdbg_writeln("functionopline", "id=\"%d\" name=\"%s\" num=\"%ld\" disabled=\"%s\"", "#%d\t\t%s opline %ld%s", + brake->id, brake->func_name, brake->opline_num, + ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : ""); + } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); } break; case PHPDBG_BREAK_FILE_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_OPLINE_BP)) { - HashPosition position[2]; HashTable *file_table; - char *file_name = NULL; - uint32_t file_len = 0; - zend_ulong file_idx = 0L; - - phpdbg_writeln(SEPARATE); - phpdbg_writeln("File opline Breakpoints:"); - for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], &position[0]); - zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], (void**) &file_table, &position[0]) == SUCCESS; - zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], &position[0])) { - if (zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], - &file_name, &file_len, &file_idx, 0, &position[0]) == HASH_KEY_IS_STRING) { - - phpdbg_breakopline_t *brake; - - for (zend_hash_internal_pointer_reset_ex(file_table, &position[1]); - zend_hash_get_current_data_ex(file_table, (void**)&brake, &position[1]) == SUCCESS; - zend_hash_move_forward_ex(file_table, &position[1])) { - phpdbg_writeln("#%d\t\t%s opline %ld%s", - brake->id, brake->class_name, brake->opline_num, - ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); - } - } - } + phpdbg_out(SEPARATE "\n"); + phpdbg_out("File opline Breakpoints:\n"); + ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], file_table) { + phpdbg_breakopline_t *brake; + + ZEND_HASH_FOREACH_PTR(file_table, brake) { + phpdbg_writeln("fileopline", "id=\"%d\" name=\"%s\" num=\"%ld\" disabled=\"%s\"", "#%d\t\t%s opline %ld%s", + brake->id, brake->class_name, brake->opline_num, + ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : ""); + } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); } break; case PHPDBG_BREAK_COND: if ((PHPDBG_G(flags) & PHPDBG_HAS_COND_BP)) { - HashPosition position; phpdbg_breakcond_t *brake; - phpdbg_writeln(SEPARATE); - phpdbg_writeln("Conditional Breakpoints:"); - 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)) { + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Conditional Breakpoints:\n"); + ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], brake) { if (brake->paramed) { switch (brake->param.type) { case STR_PARAM: - phpdbg_writeln("#%d\t\tat %s if %s%s", - brake->id, - brake->param.str, - brake->code, - ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + phpdbg_writeln("evalfunction", "id=\"%d\" name=\"%s\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s if %s%s", + brake->id, brake->param.str, brake->code, + ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : ""); break; case NUMERIC_FUNCTION_PARAM: - phpdbg_writeln("#%d\t\tat %s#%ld if %s%s", - brake->id, - brake->param.str, - brake->param.num, - brake->code, - ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + phpdbg_writeln("evalfunctionopline", "id=\"%d\" name=\"%s\" num=\"%ld\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s#%ld if %s%s", + brake->id, brake->param.str, brake->param.num, brake->code, + ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : ""); break; case METHOD_PARAM: - phpdbg_writeln("#%d\t\tat %s::%s if %s%s", - brake->id, - brake->param.method.class, - brake->param.method.name, - brake->code, + phpdbg_writeln("evalmethod", "id=\"%d\" name=\"%s::%s\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s::%s if %s%s", + brake->id, brake->param.method.class, brake->param.method.name, brake->code, ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); break; case NUMERIC_METHOD_PARAM: - phpdbg_writeln("#%d\t\tat %s::%s#%ld if %s%s", - brake->id, - brake->param.method.class, - brake->param.method.name, - brake->param.num, - brake->code, - ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + phpdbg_writeln("evalmethodopline", "id=\"%d\" name=\"%s::%s\" num=\"%d\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s::%s#%ld if %s%s", + brake->id, brake->param.method.class, brake->param.method.name, brake->param.num, brake->code, + ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : ""); break; case FILE_PARAM: - phpdbg_writeln("#%d\t\tat %s:%lu if %s%s", - brake->id, - brake->param.file.name, - brake->param.file.line, - brake->code, - ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + phpdbg_writeln("evalfile", "id=\"%d\" name=\"%s\" line=\"%d\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s:%lu if %s%s", + brake->id, brake->param.file.name, brake->param.file.line, brake->code, + ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : ""); break; case ADDR_PARAM: - phpdbg_writeln("#%d\t\tat #%lx if %s%s", - brake->id, - brake->param.addr, - brake->code, - ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + phpdbg_writeln("evalopline", "id=\"%d\" opline=\"%#lx\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat #%lx if %s%s", + brake->id, brake->param.addr, brake->code, + ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : ""); break; default: - phpdbg_error("Invalid parameter type for conditional breakpoint"); + phpdbg_error("eval", "type=\"invalidparameter\"", "Invalid parameter type for conditional breakpoint"); return; } } else { - phpdbg_writeln("#%d\t\tif %s%s", + phpdbg_writeln("eval", "id=\"%d\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tif %s%s", brake->id, brake->code, - ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); + ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : ""); } - } + } ZEND_HASH_FOREACH_END(); } break; case PHPDBG_BREAK_OPCODE: if (PHPDBG_G(flags) & PHPDBG_HAS_OPCODE_BP) { - HashPosition position; phpdbg_breakop_t *brake; - phpdbg_writeln(SEPARATE); - phpdbg_writeln("Opcode Breakpoints:"); - 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_writeln("#%d\t\t%s%s", + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Opcode Breakpoints:\n"); + ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], brake) { + phpdbg_writeln("opcode", "id=\"%d\" name=\"%s\" disabled=\"%s\"", "#%d\t\t%s%s", brake->id, brake->name, - ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); - } + ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : ""); + } ZEND_HASH_FOREACH_END(); } break; } + + phpdbg_xml("</breakpoints>"); } /* }}} */ |