static void php_phpdbg_destroy_bp_condition(void *data) /* {{{ */
{
phpdbg_breakcond_t *brake = (phpdbg_breakcond_t*) data;
-
+
if (brake) {
if (brake->ops) {
TSRMLS_FETCH();
-
+
destroy_op_array(
brake->ops TSRMLS_CC);
efree(brake->ops);
zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], 8, NULL, NULL, 0);
zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], 8, NULL, php_phpdbg_destroy_bp_methods, 0);
zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], 8, NULL, php_phpdbg_destroy_bp_condition, 0);
-
+
return SUCCESS;
} /* }}} */
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD]);
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]);
-
+
if (PHPDBG_G(exec)) {
efree(PHPDBG_G(exec));
}
case 'e': /* set execution context */
exec_len = strlen(php_optarg);
if (exec_len) {
- exec = strdup(php_optarg);
+ exec = phpdbg_resolve_path(php_optarg TSRMLS_CC);
}
break;
PG(modules_activated) = 0;
if (exec) { /* set execution context */
- PHPDBG_G(exec) = estrndup(exec, exec_len);
+ PHPDBG_G(exec) = exec;
PHPDBG_G(exec_len) = exec_len;
free(exec);
zend_try {
zend_activate_modules(TSRMLS_C);
} zend_end_try();
-
+
zend_try {
zend_activate_auto_globals(TSRMLS_C);
} zend_end_try();
zend_try {
phpdbg_interactive(TSRMLS_C);
} zend_catch {
-
+
} zend_end_try();
} while(!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING));
void phpdbg_set_breakpoint_expression(const char* expr, size_t expr_len TSRMLS_DC) /* {{{ */
{
zend_ulong hash = zend_inline_hash_func(expr, expr_len);
-
+
if (!zend_hash_index_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], hash)) {
phpdbg_breakcond_t new_break;
-
+
zend_op_array *ops = NULL;
zend_uint cops = CG(compiler_options);
ZVAL_STRINGL(&new_break.code, expr, expr_len, 1);
-
+
new_break.id = PHPDBG_G(bp_count)++;
-
+
cops = CG(compiler_options);
-
+
CG(compiler_options) = ZEND_COMPILE_DEFAULT_FOR_EVAL;
- {
+ {
zval pv;
-
+
Z_STRLEN(pv) = expr_len + sizeof("return ;") - 1;
Z_STRVAL(pv) = emalloc(Z_STRLEN(pv) + 1);
memcpy(Z_STRVAL(pv), "return ", sizeof("return ") - 1);
Z_STRVAL(pv)[Z_STRLEN(pv) - 1] = ';';
Z_STRVAL(pv)[Z_STRLEN(pv)] = '\0';
Z_TYPE(pv) = IS_STRING;
-
+
new_break.ops = zend_compile_string(
&pv, "Conditional Breakpoint Code" TSRMLS_CC);
if (new_break.ops) {
phpdbg_breakcond_t *broken;
-
+
zend_hash_index_update(
&PHPDBG_G(bp)[PHPDBG_BREAK_COND], hash, &new_break, sizeof(phpdbg_breakcond_t), (void**)&broken);
phpdbg_notice(
"Conditional breakpoint #%d added %s/%p", broken->id, Z_STRVAL(broken->code), broken->ops);
PHPDBG_G(flags) |= PHPDBG_HAS_COND_BP;
-
+
} else {
phpdbg_error(
"Failed to compile code for expression %s", expr);
phpdbg_breakcond_t *bp;
HashPosition position;
int breakpoint = FAILURE;
-
+
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*)&bp, &position) == SUCCESS;
zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) {
-
+
zval *retval = NULL;
int orig_interactive = CG(interactive);
zval **orig_retval = EG(return_value_ptr_ptr);
zend_op_array *orig_ops = EG(active_op_array);
zend_op **orig_opline = EG(opline_ptr);
-
+
ALLOC_INIT_ZVAL(retval);
-
+
EG(return_value_ptr_ptr) = &retval;
EG(active_op_array) = bp->ops;
EG(no_extensions) = 1;
-
+
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
}
-
+
CG(interactive) = 0;
-
+
zend_try {
PHPDBG_G(flags) |= PHPDBG_IN_COND_BP;
- zend_execute(
+ zend_execute(
EG(active_op_array) TSRMLS_CC);
if (i_zend_is_true(retval)) {
breakpoint = SUCCESS;
phpdbg_error(
"Error detected while evaluating expression %s", Z_STRVAL(bp->code));
CG(interactive) = orig_interactive;
-
+
EG(no_extensions)=1;
EG(return_value_ptr_ptr) = orig_retval;
EG(active_op_array) = orig_ops;
EG(opline_ptr) = orig_opline;
PHPDBG_G(flags) &= ~PHPDBG_IN_COND_BP;
} zend_end_try();
-
+
CG(interactive) = orig_interactive;
-
+
EG(no_extensions)=1;
EG(return_value_ptr_ptr) = orig_retval;
EG(active_op_array) = orig_ops;
EG(opline_ptr) = orig_opline;
PHPDBG_G(flags) &= ~PHPDBG_IN_COND_BP;
-
+
if (breakpoint == SUCCESS) {
break;
}
}
-
+
if (breakpoint == SUCCESS) {
phpdbg_notice("Conditional breakpoint #%d: (%s) %s:%u",
bp->id, Z_STRVAL(bp->code),
zend_get_executed_filename(TSRMLS_C),
zend_get_executed_lineno(TSRMLS_C));
}
-
+
return breakpoint;
} /* }}} */
zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD]);
zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]);
-
+
PHPDBG_G(flags) &= ~PHPDBG_BP_MASK;
PHPDBG_G(bp_count) = 0;
return 1;
} /* }}} */
-const char *phpdbg_current_file(TSRMLS_D)
+char *phpdbg_resolve_path(const char *path TSRMLS_DC) /* {{{ */
{
- const char *file = PHPDBG_G(exec);
+ char resolved_name[MAXPATHLEN];
- if (!file) {
- file = zend_get_executed_filename(TSRMLS_C);
+ if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) {
+ return NULL;
}
- return file;
-}
+
+ return estrdup(resolved_name);
+} /* }}} */
+
+const char *phpdbg_current_file(TSRMLS_D) /* {{{ */
+{
+ return PHPDBG_G(exec) ? PHPDBG_G(exec) : zend_get_executed_filename(TSRMLS_C);
+} /* }}} */
int phpdbg_parse_param(const char *str, size_t len, phpdbg_param_t *param TSRMLS_DC) /* {{{ */
{
const char *line_pos = strchr(str, ':');
if (line_pos && phpdbg_is_numeric(line_pos+1)) {
- char path[MAXPATHLEN], resolved_name[MAXPATHLEN];
+ char path[MAXPATHLEN];
memcpy(path, str, line_pos - str);
path[line_pos - str] = 0;
- if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) {
- goto out;
- }
-
- param->file.name = estrndup(resolved_name, line_pos - str);
+ param->file.name = phpdbg_resolve_path(path TSRMLS_CC);
param->file.line = strtol(line_pos+1, NULL, 0);
return FILE_PARAM;
}
}
-out:
+
param->str = estrndup(str, len);
return STR_PARAM;
} /* }}} */