From: Bob Weinand Date: Mon, 2 Dec 2013 20:56:25 +0000 (+0100) Subject: Added deleting and printing X-Git-Tag: php-5.6.0alpha1~110^2~33 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0a72ee087df8186b4da3db0b2750d53f46d0b1d9;p=php Added deleting and printing --- diff --git a/phpdbg_bp.c b/phpdbg_bp.c index 0ecd796e5e..24fdb93676 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -278,6 +278,7 @@ 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 = 0; /* no special type */ zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline, &new_break, sizeof(phpdbg_breakline_t), NULL); @@ -294,6 +295,8 @@ PHPDBG_API int phpdbg_resolve_op_array_break(phpdbg_breakopline_t *brake, zend_o if (op_array->last < brake->opline) { if (brake->class_name == NULL) { phpdbg_error("There are only %d oplines in function %s (breaking at opline %d impossible)", op_array->last, brake->func_name, brake->opline); + } else if (brake->func_name == NULL) { + phpdbg_error("There are only %d oplines in file %s (breaking at opline %d impossible)", op_array->last, brake->class_name, brake->opline); } else { phpdbg_error("There are only %d oplines in method %s::%s (breaking at opline %d impossible)", op_array->last, brake->class_name, brake->func_name, brake->opline); } @@ -304,6 +307,13 @@ PHPDBG_API int phpdbg_resolve_op_array_break(phpdbg_breakopline_t *brake, zend_o opline_break.id = brake->id; opline_break.opline = (zend_ulong)(op_array->opcodes + brake->opline); opline_break.name = NULL; + if (op_array->scope) { + opline_break.type = PHPDBG_BREAK_METHOD_OPLINE; + } else if (op_array->function_name) { + opline_break.type = PHPDBG_BREAK_FUNCTION_OPLINE; + } else { + opline_break.type = PHPDBG_BREAK_FILE_OPLINE; + } PHPDBG_G(flags) |= PHPDBG_HAS_OPLINE_BP; @@ -345,6 +355,11 @@ PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRML HashTable *func_table = EG(function_table); zend_function *func; + if (new_break->func_name == NULL) { + /* no idea yet ...; currently only settable before including of file */ + return FAILURE; + } + if (new_break->class_name != NULL) { zend_class_entry **ce; if (zend_hash_find(EG(class_table), new_break->class_name, new_break->class_len + 1, (void **)&ce) == FAILURE) { @@ -354,7 +369,7 @@ PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRML } if (zend_hash_find(func_table, new_break->func_name, new_break->func_len + 1, (void **)&func) == FAILURE) { - if (new_break->class_name != NULL) { + 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); } return FAILURE; @@ -479,6 +494,52 @@ PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, int zend_hash_index_update(func_table, new_break.opline, &new_break, sizeof(phpdbg_breakopline_t), NULL); } +PHPDBG_API void phpdbg_set_breakpoint_file_opline(const char *file, int opline TSRMLS_DC) /* {{{ */ +{ + phpdbg_breakopline_t new_break; + HashTable file_breaks, *file_table; + + new_break.func_len = 0; + new_break.func_name = NULL; + new_break.class_len = strlen(file); + new_break.class_name = estrndup(file, new_break.class_len); + new_break.opline = opline; + new_break.id = PHPDBG_G(bp_count)++; + + switch (phpdbg_resolve_opline_break(&new_break TSRMLS_CC)) { + case FAILURE: + phpdbg_notice("Pending breakpoint #%d at %s:%d", new_break.id, new_break.class_name, new_break.opline); + break; + + case SUCCESS: + phpdbg_notice("Breakpoint #%d added at %s:%d", new_break.id, new_break.class_name, new_break.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) { + 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); + } + + if (zend_hash_index_exists(file_table, opline)) { + phpdbg_notice("Breakpoint already exists for %s:%d", new_break.class_name, opline); + efree(new_break.class_name); + PHPDBG_G(bp_count)--; + return; + } + + PHPDBG_G(flags) |= PHPDBG_HAS_FUNCTION_OPLINE_BP; + + zend_hash_index_update(file_table, new_break.opline, &new_break, sizeof(phpdbg_breakopline_t), NULL); +} + PHPDBG_API void phpdbg_set_breakpoint_opcode(const char *name, size_t name_len TSRMLS_DC) /* {{{ */ { phpdbg_breakop_t new_break; @@ -812,6 +873,78 @@ int phpdbg_delete_breakpoint_from_file_llist(void *brake) { /* {{{ */ PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */ { + if (PHPDBG_G(flags) & PHPDBG_HAS_METHOD_OPLINE_BP) { + HashPosition position[3]; + phpdbg_breakopline_t *brake; + HashTable *class_table, *method_table; + + 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])) { + 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])) { + 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])) { + if (brake->id == num) { + zend_hash_index_del(method_table, brake->opline); + } + } + } + } + } + + if (PHPDBG_G(flags) & PHPDBG_HAS_FUNCTION_OPLINE_BP) { + HashPosition position[2]; + phpdbg_breakopline_t *brake; + HashTable *function_table; + + 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])) { + 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])) { + if (brake->id == num) { + zend_hash_index_del(function_table, brake->opline); + } + } + } + } + + if (PHPDBG_G(flags) & PHPDBG_HAS_FILE_OPLINE_BP) { + HashPosition position[2]; + phpdbg_breakopline_t *brake; + HashTable *file_table; + + 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])) { + 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])) { + if (brake->id == num) { + zend_hash_index_del(file_table, brake->opline); + } + } + } + } + + if (PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP) { + HashPosition position; + phpdbg_breakline_t *brake; + + for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position); + zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (void**) &brake, &position) == SUCCESS; + zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position)) { + if (brake->id == num) { + zend_hash_index_del(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], brake->opline); + return; + } + } + } + if (PHPDBG_G(flags) & PHPDBG_HAS_SYM_BP) { HashPosition position; phpdbg_breaksymbol_t *brake; @@ -861,20 +994,6 @@ PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */ } } - if (PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP) { - HashPosition position; - phpdbg_breakline_t *brake; - - for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position); - zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (void**) &brake, &position) == SUCCESS; - zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position)) { - if (brake->id == num) { - zend_hash_index_del(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], brake->opline); - return; - } - } - } - if (PHPDBG_G(flags) & PHPDBG_HAS_COND_BP) { HashPosition position; phpdbg_breakcond_t *brake; @@ -991,7 +1110,115 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ 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_writeln("#%d\t\t%#lx", brake->id, brake->opline); + switch (brake->type) { + case PHPDBG_BREAK_METHOD_OPLINE: + case PHPDBG_BREAK_FUNCTION_OPLINE: + case PHPDBG_BREAK_FILE_OPLINE: + phpdbg_writeln("#%d\t\t%#lx\t\t(%s breakpoint)", 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 ---" + ); + break; + + default: + phpdbg_writeln("#%d\t\t%#lx", brake->id, brake->opline); + break; + } + } + } 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; + zend_uint 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 %d", brake->id, brake->class_name, brake->func_name, brake->opline); + } + } + } + } + + } + } 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; + zend_uint 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 %d", brake->id, brake->func_name, brake->opline); + } + } + + } + } 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; + zend_uint 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 %d", brake->id, brake->class_name, brake->opline); + } + } + } } break; @@ -1022,4 +1249,3 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ } break; } } /* }}} */ - diff --git a/phpdbg_bp.h b/phpdbg_bp.h index 1aec77b545..31f739338c 100644 --- a/phpdbg_bp.h +++ b/phpdbg_bp.h @@ -104,6 +104,7 @@ PHPDBG_API void phpdbg_set_breakpoint_opline(zend_ulong TSRMLS_DC); PHPDBG_API void phpdbg_set_breakpoint_opline_ex(phpdbg_opline_ptr_t TSRMLS_DC); PHPDBG_API void phpdbg_set_breakpoint_method_opline(const char *class, const char *method, int opline TSRMLS_DC); PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, int opline TSRMLS_DC); +PHPDBG_API void phpdbg_set_breakpoint_file_opline(const char *file, int opline TSRMLS_DC); PHPDBG_API void phpdbg_set_breakpoint_expression(const char*, size_t TSRMLS_DC); int phpdbg_find_breakpoint_file(zend_op_array* TSRMLS_DC); diff --git a/phpdbg_info.c b/phpdbg_info.c index 727e676778..492063af7c 100644 --- a/phpdbg_info.c +++ b/phpdbg_info.c @@ -31,6 +31,9 @@ PHPDBG_INFO(break) /* {{{ */ phpdbg_print_breakpoints(PHPDBG_BREAK_SYM TSRMLS_CC); phpdbg_print_breakpoints(PHPDBG_BREAK_METHOD TSRMLS_CC); phpdbg_print_breakpoints(PHPDBG_BREAK_OPLINE TSRMLS_CC); + phpdbg_print_breakpoints(PHPDBG_BREAK_FILE_OPLINE TSRMLS_CC); + phpdbg_print_breakpoints(PHPDBG_BREAK_FUNCTION_OPLINE TSRMLS_CC); + phpdbg_print_breakpoints(PHPDBG_BREAK_METHOD_OPLINE TSRMLS_CC); phpdbg_print_breakpoints(PHPDBG_BREAK_COND TSRMLS_CC); phpdbg_print_breakpoints(PHPDBG_BREAK_OPCODE TSRMLS_CC);