From: Bob Weinand Date: Tue, 3 Dec 2013 11:31:25 +0000 (+0100) Subject: Nearly finished opline num support patch X-Git-Tag: php-5.6.0alpha1~110^2~32 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=76f889569f029c9fe15d87a0b80db07e483b0cf1;p=php Nearly finished opline num support patch --- diff --git a/phpdbg_bp.c b/phpdbg_bp.c index 24fdb93676..a7be7eb5d4 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -128,8 +128,95 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ noted = 1; } - fprintf( - handle, "break %s::%s\n", brake->class_name, brake->func_name); + fprintf(handle, "break %s::%s\n", brake->class_name, brake->func_name); + } + } + } + + if (PHPDBG_G(flags) & PHPDBG_HAS_METHOD_OPLINE_BP) { + HashTable *class, *method; + phpdbg_breakopline_t *brake; + HashPosition mposition[2]; + zend_bool noted = 0; + + table = &PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE]; + + 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)) { + for (zend_hash_internal_pointer_reset_ex(class, &mposition[0]); + zend_hash_get_current_data_ex(class, (void**) &method, &mposition[0]) == SUCCESS; + zend_hash_move_forward_ex(class, &mposition[0])) { + noted = 0; + + for (zend_hash_internal_pointer_reset_ex(method, &mposition[1]); + zend_hash_get_current_data_ex(method, (void**) &brake, &mposition[1]) == SUCCESS; + zend_hash_move_forward_ex(method, &mposition[1])) { + if (!noted) { + phpdbg_notice( + "Exporting method opline breakpoints in %s::%s (%d)", + brake->class_name, brake->func_name, zend_hash_num_elements(method)); + noted = 1; + } + + fprintf(handle, "break %s::%s#%d\n", brake->class_name, brake->func_name, brake->opline); + } + } + } + } + + if (PHPDBG_G(flags) & PHPDBG_HAS_FUNCTION_OPLINE_BP) { + HashTable *function; + phpdbg_breakopline_t *brake; + HashPosition fposition; + zend_bool noted = 0; + + table = &PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE]; + + for (zend_hash_internal_pointer_reset_ex(table, &position); + zend_hash_get_current_data_ex(table, (void**) &function, &position) == SUCCESS; + zend_hash_move_forward_ex(table, &position)) { + noted = 0; + + for (zend_hash_internal_pointer_reset_ex(function, &fposition); + zend_hash_get_current_data_ex(function, (void**) &brake, &fposition) == SUCCESS; + zend_hash_move_forward_ex(function, &fposition)) { + if (!noted) { + phpdbg_notice( + "Exporting function opline breakpoints in %s (%d)", + brake->func_name, zend_hash_num_elements(function)); + noted = 1; + } + + fprintf(handle, "break %s#%d\n", brake->func_name, brake->opline); + } + } + } + + if (PHPDBG_G(flags) & PHPDBG_HAS_FILE_OPLINE_BP) { + HashTable *file; + phpdbg_breakopline_t *brake; + HashPosition fposition; + zend_bool noted = 0; + + table = &PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE]; + + for (zend_hash_internal_pointer_reset_ex(table, &position); + zend_hash_get_current_data_ex(table, (void**) &file, &position) == SUCCESS; + zend_hash_move_forward_ex(table, &position)) { + noted = 0; + + for (zend_hash_internal_pointer_reset_ex(file, &fposition); + zend_hash_get_current_data_ex(file, (void**) &brake, &fposition) == SUCCESS; + zend_hash_move_forward_ex(file, &fposition)) { + if (!noted) { + phpdbg_notice( + "Exporting file opline breakpoints in %s (%d)", + brake->class_name, zend_hash_num_elements(file)); + noted = 1; + } + + fprintf(handle, "break a %s#%d\n", brake->func_name, brake->opline); } } } @@ -146,8 +233,7 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ 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); + fprintf(handle, "break op %s\n", brake->name); } } @@ -163,8 +249,7 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */ 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)); + fprintf(handle, "break on %s\n", Z_STRVAL(brake->code)); } } } /* }}} */ @@ -333,7 +418,11 @@ PHPDBG_API void phpdbg_resolve_op_array_breaks(zend_op_array *op_array TSRMLS_DC return; } - 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) { + 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) { + 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) { return; } @@ -346,7 +435,7 @@ PHPDBG_API void phpdbg_resolve_op_array_breaks(zend_op_array *op_array TSRMLS_DC 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); - phpdbg_notice("Breakpoint #%d resolved at %s%s%s:%d (opline %#lx)", brake->id, brake->class_name?brake->class_name:"", brake->class_name?"::":"", brake->func_name, brake->opline, opline_break->opline); + phpdbg_notice("Breakpoint #%d resolved at %s%s%s#%d (opline %#lx)", brake->id, brake->class_name?brake->class_name:"", brake->class_name&&brake->func_name?"::":"", brake->func_name?brake->func_name:"", brake->opline, opline_break->opline); } } } @@ -406,11 +495,11 @@ 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:%d", new_break.id, new_break.class_name, new_break.func_name, opline); + phpdbg_notice("Pending breakpoint #%d at %s::%s#%d", new_break.id, new_break.class_name, new_break.func_name, opline); break; case SUCCESS: - phpdbg_notice("Breakpoint #%d added at %s::%s:%d", new_break.id, new_break.class_name, new_break.func_name, opline); + phpdbg_notice("Breakpoint #%d added at %s::%s#%d", new_break.id, new_break.class_name, new_break.func_name, opline); break; case 2: @@ -436,7 +525,7 @@ PHPDBG_API void phpdbg_set_breakpoint_method_opline(const char *class, const cha } if (zend_hash_index_exists(method_table, opline)) { - phpdbg_notice("Breakpoint already exists for %s::%s:%d", new_break.class_name, new_break.func_name, opline); + phpdbg_notice("Breakpoint already exists for %s::%s#%d", new_break.class_name, new_break.func_name, opline); efree(new_break.func_name); efree(new_break.class_name); PHPDBG_G(bp_count)--; @@ -462,11 +551,11 @@ PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, int switch (phpdbg_resolve_opline_break(&new_break TSRMLS_CC)) { case FAILURE: - phpdbg_notice("Pending breakpoint #%d at %s:%d", new_break.id, new_break.func_name, new_break.opline); + phpdbg_notice("Pending breakpoint #%d at %s#%d", new_break.id, new_break.func_name, new_break.opline); break; case SUCCESS: - phpdbg_notice("Breakpoint #%d added at %s:%d", new_break.id, new_break.func_name, new_break.opline); + phpdbg_notice("Breakpoint #%d added at %s#%d", new_break.id, new_break.func_name, new_break.opline); break; case 2: @@ -483,7 +572,7 @@ PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, int } if (zend_hash_index_exists(func_table, opline)) { - phpdbg_notice("Breakpoint already exists for %s:%d", new_break.func_name, opline); + phpdbg_notice("Breakpoint already exists for %s#%d", new_break.func_name, opline); efree(new_break.func_name); PHPDBG_G(bp_count)--; return; diff --git a/phpdbg_break.c b/phpdbg_break.c index cb2a01b5bd..e2dc95d971 100644 --- a/phpdbg_break.c +++ b/phpdbg_break.c @@ -63,9 +63,12 @@ PHPDBG_BREAK(address) /* {{{ */ phpdbg_set_breakpoint_method_opline(param->method.class, param->method.name, param->num TSRMLS_CC); break; - case NUMERIC_PARAM: - case FILE_PARAM: + case NUMERIC_FUNCTION_PARAM: phpdbg_set_breakpoint_function_opline(param->str, param->num TSRMLS_CC); + break; + + case FILE_PARAM: + phpdbg_set_breakpoint_file_opline(param->file.name, param->file.line TSRMLS_CC); break; phpdbg_default_switch_case(); diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 4f3fe71eed..30ce0dc0d6 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -35,10 +35,12 @@ PHPDBG_API const char *phpdbg_get_param_type(const phpdbg_param_t *param TSRMLS_ return "numeric"; case METHOD_PARAM: return "method"; + case NUMERIC_FUNCTION_PARAM: + return "function opline"; case NUMERIC_METHOD_PARAM: return "method opline"; case FILE_PARAM: - return "file or function opline"; + return "file or file opline"; case STR_PARAM: return "string"; default: /* this is bad */ @@ -74,27 +76,39 @@ PHPDBG_API phpdbg_param_type phpdbg_parse_param(const char *str, size_t len, php char *line_pos = strrchr(str, ':'); if (line_pos && phpdbg_is_numeric(line_pos+1)) { - param->len = line_pos - str; - param->str = estrndup(str, param->len); - if (strchr(str, ':') == line_pos) { + char path[MAXPATHLEN]; + + memcpy(path, str, line_pos - str); + path[line_pos - str] = 0; *line_pos = 0; - param->file.name = phpdbg_resolve_path(param->str TSRMLS_CC); - param->num = param->file.line = strtol(line_pos+1, NULL, 0); + param->file.name = phpdbg_resolve_path(path TSRMLS_CC); + param->file.line = strtol(line_pos+1, NULL, 0); param->type = FILE_PARAM; - } else { + + goto parsed; + } + } + + line_pos = strrchr(str, '#'); + + if (line_pos && phpdbg_is_numeric(line_pos+1)) { + if (strchr(str, '#') == line_pos) { *line_pos = 0; - if (phpdbg_is_class_method(str, line_pos - str, &class_name, &func_name)) { - param->num = strtol(str, NULL, 0); + param->num = strtol(line_pos + 1, NULL, 0); + + if (phpdbg_is_class_method(str, line_pos - str, &class_name, &func_name)) { param->method.class = class_name; param->method.name = func_name; param->type = NUMERIC_METHOD_PARAM; } else { - phpdbg_error("Impossible to parse %s", str); + param->len = line_pos - str; + param->str = estrndup(str, param->len); + param->type = NUMERIC_FUNCTION_PARAM; } - } - goto parsed; + goto parsed; + } } } diff --git a/phpdbg_cmd.h b/phpdbg_cmd.h index 69d36828c3..aef9fe2653 100644 --- a/phpdbg_cmd.h +++ b/phpdbg_cmd.h @@ -38,6 +38,7 @@ typedef enum { METHOD_PARAM, STR_PARAM, NUMERIC_PARAM, + NUMERIC_FUNCTION_PARAM, NUMERIC_METHOD_PARAM } phpdbg_param_type; diff --git a/phpdbg_help.c b/phpdbg_help.c index eaf5f649d8..12bff5ce0b 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -238,6 +238,18 @@ PHPDBG_HELP(break) /* {{{ */ phpdbg_writeln("\t%sb [a] 0x7ff68f570e08", phpdbg_get_prompt(TSRMLS_C)); phpdbg_writeln("\tWill break at the opline with the address provided"); phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sbreak [address] my_function#1", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sb [a] my_function#1", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill break at the opline number 1 of the function my_function"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sbreak [address] \\my\\class::method#2", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sb [a] \\my\\class::method#2", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill break at the opline number 2 of the method \\my\\class::method"); + phpdbg_writeln(EMPTY); + phpdbg_writeln("\t%sbreak address test.php:3", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\t%sb a test.php:3", phpdbg_get_prompt(TSRMLS_C)); + phpdbg_writeln("\tWill break at the opline number 3 of test.php"); + phpdbg_writeln(EMPTY); phpdbg_writeln("\t%sbreak [lineno] 200", phpdbg_get_prompt(TSRMLS_C)); phpdbg_writeln("\t%sb [l] 200", phpdbg_get_prompt(TSRMLS_C)); phpdbg_writeln("\tWill break at line 200 of the currently executing file"); diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 009d19c8d0..390aaa556b 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -817,6 +817,12 @@ PHPDBG_COMMAND(break) /* {{{ */ case METHOD_PARAM: phpdbg_set_breakpoint_method(param->method.class, param->method.name TSRMLS_CC); break; + case NUMERIC_METHOD_PARAM: + phpdbg_set_breakpoint_method_opline(param->method.class, param->method.name, param->num TSRMLS_CC); + break; + case NUMERIC_FUNCTION_PARAM: + phpdbg_set_breakpoint_function_opline(param->str, param->num TSRMLS_CC); + break; case FILE_PARAM: phpdbg_set_breakpoint_file(param->file.name, param->file.line TSRMLS_CC); break;