From e05b4977c5538f10c8cda6aba013116153262ac2 Mon Sep 17 00:00:00 2001 From: krakjoe Date: Mon, 2 Dec 2013 13:19:13 +0000 Subject: [PATCH] added set break [id] --- Changelog.md | 8 +++- phpdbg_bp.c | 130 ++++++++++++++++++++++++++++++++++++++------------- phpdbg_bp.h | 9 +++- phpdbg_set.c | 33 ++++++++++--- phpdbg_set.h | 2 +- 5 files changed, 138 insertions(+), 44 deletions(-) diff --git a/Changelog.md b/Changelog.md index adb4759ab0..8e817ca212 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,9 +1,13 @@ ChangeLog for phpdbg ==================== -Version 0.2.0 2013-00-00 +Version 0.3.0 2013-00-00 +------------------------ + +1. Added ability to disable an enable a single breakpoint + +Version 0.2.0 2013-11-31 ------------------------ -(this needs tidying before release) 1. Added "break delete " command 2. Added "break opcode " command diff --git a/phpdbg_bp.c b/phpdbg_bp.c index 7d962d437c..125ceaa519 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -49,6 +49,13 @@ static inline void _phpdbg_break_mapping(int id, HashTable *table TSRMLS_DC) #define PHPDBG_BREAK_MAPPING(id, table) _phpdbg_break_mapping(id, table TSRMLS_CC) #define PHPDBG_BREAK_UNMAPPING(id) \ zend_hash_index_del(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (id)) + +#define PHPDBG_BREAK_INIT(b, t) do {\ + b.id = PHPDBG_G(bp_count)++; \ + b.type = t; \ + b.disabled = 0;\ + b.hits = 0; \ +} while(0) static void phpdbg_file_breaks_dtor(void *data) /* {{{ */ { @@ -170,9 +177,7 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML if (!zend_hash_index_exists(broken, line_num)) { PHPDBG_G(flags) |= PHPDBG_HAS_FILE_BP; - new_break.id = PHPDBG_G(bp_count)++; - new_break.type = PHPDBG_BREAK_FILE; - new_break.hits = 0; + PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_FILE); new_break.filename = estrndup(path, path_len); new_break.line = line_num; @@ -202,9 +207,7 @@ PHPDBG_API void phpdbg_set_breakpoint_symbol(const char *name, size_t name_len T PHPDBG_G(flags) |= PHPDBG_HAS_SYM_BP; - new_break.id = PHPDBG_G(bp_count)++; - new_break.type = PHPDBG_BREAK_SYM; - new_break.hits = 0; + 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, @@ -240,9 +243,7 @@ PHPDBG_API void phpdbg_set_breakpoint_method(const char *class_name, const char PHPDBG_G(flags) |= PHPDBG_HAS_METHOD_BP; - new_break.id = PHPDBG_G(bp_count)++; - new_break.type = PHPDBG_BREAK_METHOD; - new_break.hits = 0; + PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_METHOD); new_break.class_name = estrndup(class_name, class_len); new_break.class_len = class_len; new_break.func_name = estrndup(func_name, func_len); @@ -269,13 +270,10 @@ PHPDBG_API void phpdbg_set_breakpoint_opline(zend_ulong opline TSRMLS_DC) /* {{{ PHPDBG_G(flags) |= PHPDBG_HAS_OPLINE_BP; - new_break.id = PHPDBG_G(bp_count)++; - new_break.type = PHPDBG_BREAK_OPLINE; - new_break.hits = 0; + PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_OPLINE); new_break.name = NULL; new_break.opline = opline; - zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline, &new_break, sizeof(phpdbg_breakline_t), NULL); @@ -298,9 +296,7 @@ PHPDBG_API void phpdbg_set_breakpoint_opcode(const char *name, size_t name_len T return; } - new_break.id = PHPDBG_G(bp_count)++; - new_break.type = PHPDBG_BREAK_OPCODE; - new_break.hits = 0; + PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_OPCODE); new_break.hash = hash; new_break.name = estrndup(name, name_len); @@ -320,9 +316,7 @@ PHPDBG_API void phpdbg_set_breakpoint_opline_ex(phpdbg_opline_ptr_t opline TSRML PHPDBG_G(flags) |= PHPDBG_HAS_OPLINE_BP; - new_break.id = PHPDBG_G(bp_count)++; - new_break.type = PHPDBG_BREAK_OPLINE; - new_break.hits = 0; + PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_OPLINE); new_break.opline = (zend_ulong) opline; zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], @@ -343,9 +337,7 @@ PHPDBG_API void phpdbg_set_breakpoint_expression(const char *expr, size_t expr_l zend_uint cops = CG(compiler_options); zval pv; - new_break.id = PHPDBG_G(bp_count)++; - new_break.type = PHPDBG_BREAK_COND; - new_break.hits = 0; + PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_COND); new_break.hash = hash; cops = CG(compiler_options); @@ -558,12 +550,12 @@ PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakpoint(zend_execute_data* execute if (!(PHPDBG_G(flags) & PHPDBG_IN_EVAL) && (PHPDBG_G(flags) & PHPDBG_HAS_COND_BP) && (base = phpdbg_find_conditional_breakpoint(TSRMLS_C))) { - return base; + goto result; } if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_BP) && (base = phpdbg_find_breakpoint_file(execute_data->op_array TSRMLS_CC))) { - return base; + goto result; } if (PHPDBG_G(flags) & (PHPDBG_HAS_METHOD_BP|PHPDBG_HAS_SYM_BP)) { @@ -571,22 +563,30 @@ PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakpoint(zend_execute_data* execute if (execute_data->opline == EG(active_op_array)->opcodes) { if ((base = phpdbg_find_breakpoint_symbol( execute_data->function_state.function TSRMLS_CC))) { - return base; + goto result; } } } if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP) && (base = phpdbg_find_breakpoint_opline(execute_data->opline TSRMLS_CC))) { - return base; + goto result; } if ((PHPDBG_G(flags) & PHPDBG_HAS_OPCODE_BP) && (base = phpdbg_find_breakpoint_opcode(execute_data->opline->opcode TSRMLS_CC))) { - return base; + goto result; } return NULL; + +result: + /* we return nothing for disable breakpoints */ + if (base->disabled) { + return NULL; + } + + return base; } /* }}} */ PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */ @@ -754,6 +754,58 @@ unknown: } } /* }}} */ +PHPDBG_API void phpdbg_enable_breakpoint(zend_ulong id TSRMLS_DC) /* {{{ */ +{ + phpdbg_breakbase_t *brake = phpdbg_find_breakbase(id TSRMLS_CC); + + if (brake) { + brake->disabled = 0; + } +} /* }}} */ + +PHPDBG_API void phpdbg_disable_breakpoint(zend_ulong id TSRMLS_DC) /* {{{ */ +{ + phpdbg_breakbase_t *brake = phpdbg_find_breakbase(id TSRMLS_CC); + + if (brake) { + brake->disabled = 1; + } +} /* }}} */ + +PHPDBG_API void phpdbg_enable_breakpoints(TSRMLS_D) /* {{{ */ +{ + PHPDBG_G(flags) |= PHPDBG_IS_BP_ENABLED; +} /* }}} */ + +PHPDBG_API void phpdbg_disable_breakpoints(TSRMLS_D) { /* {{{ */ + PHPDBG_G(flags) &= ~PHPDBG_IS_BP_ENABLED; +} /* }}} */ + +PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase(zend_ulong id TSRMLS_DC) /* {{{ */ +{ + HashTable **table; + HashPosition position; + + return phpdbg_find_breakbase_ex(id, &table, &position TSRMLS_CC); +} /* }}} */ + +PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable ***table, HashPosition *position TSRMLS_DC) /* {{{ */ +{ + if (zend_hash_index_find(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], id, (void**)table) == SUCCESS) { + 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)) { + + if (brake->id == id) { + return brake; + } + } + } + return NULL; +} /* }}} */ + PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ { switch (type) { @@ -766,7 +818,9 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ 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", brake->id, brake->symbol); + phpdbg_writeln("#%d\t\t%s%s", + brake->id, brake->symbol, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); } } break; @@ -790,7 +844,9 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ 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", brake->id, brake->class_name, brake->func_name); + phpdbg_writeln("#%d\t\t%s::%s%s", + brake->id, brake->class_name, brake->func_name, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); } } @@ -811,7 +867,9 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ 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", brake->id, brake->filename, brake->line); + phpdbg_writeln("#%d\t\t%s:%lu%s", + brake->id, brake->filename, brake->line, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); } } @@ -826,7 +884,9 @@ 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); + phpdbg_writeln("#%d\t\t%#lx%s", + brake->id, brake->opline, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); } } break; @@ -839,7 +899,9 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ 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_writeln("#%d\t\t%s", brake->id, brake->code); + phpdbg_writeln("#%d\t\t%s%s", + brake->id, brake->code, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); } } break; @@ -852,7 +914,9 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ 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", brake->id, brake->name); + phpdbg_writeln("#%d\t\t%s%s", + brake->id, brake->name, + ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : ""); } } break; } diff --git a/phpdbg_bp.h b/phpdbg_bp.h index cf90330083..55ffa7458d 100644 --- a/phpdbg_bp.h +++ b/phpdbg_bp.h @@ -28,6 +28,7 @@ typedef struct _zend_op *phpdbg_opline_ptr_t; /* }}} */ int id; \ zend_uchar type; \ zend_ulong hits; \ + zend_bool disabled; \ const char *name /* }}} */ /* {{{ breakpoint base */ @@ -99,12 +100,18 @@ PHPDBG_API void phpdbg_set_breakpoint_expression(const char* expression, size_t PHPDBG_API phpdbg_breakbase_t* phpdbg_find_breakpoint(zend_execute_data* TSRMLS_DC); /* }}} */ /* {{{ Misc Breakpoint API */ +PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase(zend_ulong id TSRMLS_DC); +PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable ***table, HashPosition *position TSRMLS_DC); PHPDBG_API void phpdbg_hit_breakpoint(phpdbg_breakbase_t* brake, zend_bool output TSRMLS_DC); PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC); PHPDBG_API void phpdbg_print_breakpoint(phpdbg_breakbase_t* brake TSRMLS_DC); PHPDBG_API void phpdbg_reset_breakpoints(TSRMLS_D); PHPDBG_API void phpdbg_clear_breakpoints(TSRMLS_D); -PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC); /* }}} */ +PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC); +PHPDBG_API void phpdbg_enable_breakpoints(TSRMLS_D); +PHPDBG_API void phpdbg_enable_breakpoint(zend_ulong id TSRMLS_DC); +PHPDBG_API void phpdbg_disable_breakpoint(zend_ulong id TSRMLS_DC); +PHPDBG_API void phpdbg_disable_breakpoints(TSRMLS_D); /* }}} */ /* {{{ Breakpoint Exportation API */ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC); /* }}} */ diff --git a/phpdbg_set.c b/phpdbg_set.c index be8624ef97..0c046eeaa1 100644 --- a/phpdbg_set.c +++ b/phpdbg_set.c @@ -21,6 +21,7 @@ #include "phpdbg_cmd.h" #include "phpdbg_set.h" #include "phpdbg_utils.h" +#include "phpdbg_bp.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); @@ -51,15 +52,33 @@ PHPDBG_SET(break) /* {{{ */ case STR_PARAM: if (strncasecmp(param->str, PHPDBG_STRL("on")) == 0) { - PHPDBG_G(flags) |= PHPDBG_IS_BP_ENABLED; + phpdbg_enable_breakpoints(TSRMLS_C); } else if (strncasecmp(param->str, PHPDBG_STRL("off")) == 0) { - PHPDBG_G(flags) &= ~PHPDBG_IS_BP_ENABLED; + phpdbg_disable_breakpoints(TSRMLS_C); } break; + + case NUMERIC_PARAM: { + if (input->argc > 2) { + if (phpdbg_argv_is(2, "on")) { + phpdbg_enable_breakpoint(param->num TSRMLS_CC); + } else if (phpdbg_argv_is(2, "off")) { + phpdbg_disable_breakpoint(param->num TSRMLS_CC); + } + } else { + phpdbg_breakbase_t *brake = phpdbg_find_breakbase(param->num TSRMLS_CC); + if (brake) { + phpdbg_writeln( + "%s", brake->disabled ? "off" : "on"); + } else { + phpdbg_error("Failed to find breakpoint #%lx", param->num); + } + } + } break; default: phpdbg_error( - "set break used incorrectly: set break "); + "set break used incorrectly: set break [id] "); } return SUCCESS; @@ -127,12 +146,12 @@ PHPDBG_SET(colors) /* {{{ */ goto done; } } + + default: + phpdbg_error( + "set colors used incorrectly: set colors "); } -usage: - phpdbg_error( - "set colors used incorrectly: set colors "); - done: return SUCCESS; } /* }}} */ diff --git a/phpdbg_set.h b/phpdbg_set.h index 35b61d4e61..9f977b64a3 100644 --- a/phpdbg_set.h +++ b/phpdbg_set.h @@ -39,7 +39,7 @@ static const phpdbg_command_t phpdbg_set_commands[] = { PHPDBG_COMMAND_D_EX(colors, "usage: set colors ", 'C', set_colors, NULL, 1), #endif PHPDBG_COMMAND_D_EX(oplog, "usage: set oplog ", 'O', set_oplog, NULL, 0), - PHPDBG_COMMAND_D_EX(break, "usage: set break ", 'b', set_break, NULL, 0), + PHPDBG_COMMAND_D_EX(break, "usage: set break [id] ", 'b', set_break, NULL, 0), PHPDBG_END_COMMAND }; -- 2.40.0