Browse Source

Added deleting and printing

pull/550/head
Bob Weinand 13 years ago
parent
commit
0a72ee087d
  1. 260
      phpdbg_bp.c
  2. 1
      phpdbg_bp.h
  3. 3
      phpdbg_info.c

260
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;
}
} /* }}} */

1
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);

3
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);

Loading…
Cancel
Save