#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) /* {{{ */
{
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;
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,
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);
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);
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);
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],
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);
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)) {
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) /* {{{ */
}
} /* }}} */
+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) {
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;
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]" : "");
}
}
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]" : "");
}
}
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;
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;
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;
}