PHPDBG_API void phpdbg_save_oplines(zend_op_array *op_array TSRMLS_DC) {
phpdbg_btree **branch = &PHPDBG_G(opline_btree);
- int i = sizeof(zend_ulong) * 8 - 1;
+ int i = sizeof(void *) * 8 - 1;
do {
if (*branch == NULL) {
} while (i--);
if (*branch == NULL) {
- phpdbg_btree *memory = *branch = emalloc(i * sizeof(phpdbg_btree));
- while (i--) {
+ phpdbg_btree *memory = *branch = emalloc((i + 2) * sizeof(phpdbg_btree));
+ do {
+ (*branch)->branches[!(((zend_ulong)op_array->opcodes >> i) % 2)] = NULL;
branch = &(*branch)->branches[((zend_ulong)op_array->opcodes >> i) % 2];
*branch = ++memory;
- }
+ } while (i--);
}
(*branch)->op_array = op_array;
PHPDBG_API void phpdbg_set_breakpoint_opline(zend_ulong opline TSRMLS_DC) /* {{{ */
{
+ if (PHPDBG_G(opline_btree) == NULL) {
+ phpdbg_error("No oplines initialized yet");
+ return;
+ }
+
if (!zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline)) {
phpdbg_breakline_t new_break;
phpdbg_breakopline_t opline_break;
- int i = sizeof(zend_ulong) * 8 - 1, last_superior_i = -1;
+ int i = sizeof(void *) * 8 - 1, last_superior_i = -1;
phpdbg_btree *branch = PHPDBG_G(opline_btree);
HashTable *insert = &PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE];
HashTable func_breaks, *func_table;
do {
if ((opline >> i) % 2 == 0 && !branch->branches[0]) {
- if (last_superior_i != -1) {
- i = sizeof(zend_ulong) * 8 - 1;
- do {
- branch = branch->branches[(opline >> i) % 2 == 1 && branch->branches[1]];
- } while (i-- > last_superior_i);
- do {
- branch = branch->branches[!!branch->branches[1]];
- } while (i--);
+ if (last_superior_i == -1) {
+ goto error;
+ }
+ branch = PHPDBG_G(opline_btree);
+ i = sizeof(void *) * 8 - 1;
+ do {
+ branch = branch->branches[(opline >> i) % 2 == 1 && branch->branches[1]];
+ } while (i-- > last_superior_i);
+ branch = branch->branches[0];
+ while (i--) {
+ branch = branch->branches[branch->branches[1] != NULL];
}
break;
}
} else {
branch = branch->branches[0];
}
- } while (--i);
+ } while (i--);
- if (i ||
- (zend_ulong)(branch->op_array + branch->op_array->last) <= opline ||
- (opline - (zend_ulong)branch->op_array) % sizeof(zend_op) > 0) {
+ if ((zend_ulong)(branch->op_array->opcodes + branch->op_array->last) <= opline ||
+ (opline - (zend_ulong)branch->op_array->opcodes) % sizeof(zend_op) > 0) {
+error:
phpdbg_error("No opline could be found at 0x%lx", opline);
return;
}
for (zend_hash_internal_pointer_reset_ex(oplines_table, &position);
zend_hash_get_current_data_ex(oplines_table, (void**) &brake, &position) == SUCCESS;
zend_hash_move_forward_ex(oplines_table, &position)) {
- phpdbg_resolve_op_array_break(brake, op_array TSRMLS_CC);
+ if (phpdbg_resolve_op_array_break(brake, op_array TSRMLS_CC) == SUCCESS) {
+ phpdbg_breakline_t *opline_break;
+
+ 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);
+ }
}
}