Nearly finished opline num support patch

This commit is contained in:
Bob Weinand 2013-12-03 12:31:25 +01:00
parent 0a72ee087d
commit 76f889569f
6 changed files with 153 additions and 28 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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;
}
}
}

View File

@ -38,6 +38,7 @@ typedef enum {
METHOD_PARAM,
STR_PARAM,
NUMERIC_PARAM,
NUMERIC_FUNCTION_PARAM,
NUMERIC_METHOD_PARAM
} phpdbg_param_type;

View File

@ -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");

View File

@ -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;