mirror of
https://github.com/php/php-src.git
synced 2025-08-19 08:49:28 +02:00
- Added catch command
This commit is contained in:
parent
1c6e54ecdf
commit
f5c07f61e1
6 changed files with 69 additions and 6 deletions
2
phpdbg.c
2
phpdbg.c
|
@ -119,6 +119,7 @@ static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */
|
|||
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);
|
||||
zend_hash_init(&PHPDBG_G(seek), 8, NULL, NULL, 0);
|
||||
zend_hash_init(&PHPDBG_G(catch), 8, NULL, NULL, 0);
|
||||
zend_hash_init(&PHPDBG_G(registered), 8, NULL, php_phpdbg_destroy_registered, 0);
|
||||
|
||||
return SUCCESS;
|
||||
|
@ -132,6 +133,7 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
|
|||
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD]);
|
||||
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]);
|
||||
zend_hash_destroy(&PHPDBG_G(seek));
|
||||
zend_hash_destroy(&PHPDBG_G(catch));
|
||||
zend_hash_destroy(&PHPDBG_G(registered));
|
||||
|
||||
if (PHPDBG_G(exec)) {
|
||||
|
|
3
phpdbg.h
3
phpdbg.h
|
@ -110,6 +110,8 @@
|
|||
#define PHPDBG_IS_SIGNALED (1<<19)
|
||||
#define PHPDBG_IS_INTERACTIVE (1<<20)
|
||||
|
||||
#define PHPDBG_HAS_CATCH (1<<21)
|
||||
|
||||
#ifndef _WIN32
|
||||
# define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET|PHPDBG_IS_COLOURED)
|
||||
#else
|
||||
|
@ -138,6 +140,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
|
|||
phpdbg_param_t lparam; /* last param */
|
||||
FILE *oplog; /* opline log */
|
||||
HashTable seek; /* seek oplines */
|
||||
HashTable catch; /* seek opcodes */
|
||||
zend_ulong flags; /* phpdbg flags */
|
||||
HashTable registered; /* registered */
|
||||
phpdbg_frame_t frame; /* frame */
|
||||
|
|
|
@ -341,6 +341,19 @@ PHPDBG_HELP(back) /* {{{ */
|
|||
return SUCCESS;
|
||||
} /* }}} */
|
||||
|
||||
PHPDBG_HELP(catch) /* {{{ */
|
||||
{
|
||||
phpdbg_help_header();
|
||||
phpdbg_writeln("Catch a VM opcode before its execution");
|
||||
phpdbg_writeln(EMPTY);
|
||||
phpdbg_notice("Examples");
|
||||
phpdbg_writeln("\t%scatch ZEND_ADD", PROMPT);
|
||||
phpdbg_writeln("\t%so ZEND_ADD", PROMPT);
|
||||
phpdbg_writeln("\tWill break the execution before the specified opcode is reached");
|
||||
phpdbg_help_footer();
|
||||
return SUCCESS;
|
||||
} /* }}} */
|
||||
|
||||
PHPDBG_HELP(frame) /* {{{ */
|
||||
{
|
||||
phpdbg_help_header();
|
||||
|
@ -422,7 +435,7 @@ PHPDBG_HELP(oplog) /* {{{ */
|
|||
phpdbg_writeln("Note: upon failure to open a new oplog, the last oplog is held open");
|
||||
phpdbg_help_footer();
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
PHPDBG_HELP(register) /* {{{ */
|
||||
{
|
||||
|
@ -439,7 +452,7 @@ PHPDBG_HELP(register) /* {{{ */
|
|||
HashPosition position;
|
||||
char *name = NULL;
|
||||
zend_uint name_len = 0;
|
||||
|
||||
|
||||
phpdbg_notice("Registered Functions (%d)", zend_hash_num_elements(&PHPDBG_G(registered)));
|
||||
for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(registered), &position);
|
||||
zend_hash_get_current_key_ex(&PHPDBG_G(registered), &name, &name_len, NULL, 1, &position) == HASH_KEY_IS_STRING;
|
||||
|
@ -448,7 +461,7 @@ PHPDBG_HELP(register) /* {{{ */
|
|||
efree(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
phpdbg_help_footer();
|
||||
return SUCCESS;
|
||||
} /* }}} */
|
||||
|
|
|
@ -44,6 +44,7 @@ PHPDBG_HELP(clean);
|
|||
PHPDBG_HELP(clear);
|
||||
PHPDBG_HELP(info);
|
||||
PHPDBG_HELP(back);
|
||||
PHPDBG_HELP(catch);
|
||||
PHPDBG_HELP(frame);
|
||||
PHPDBG_HELP(quiet);
|
||||
PHPDBG_HELP(list);
|
||||
|
@ -71,6 +72,7 @@ static const phpdbg_command_t phpdbg_help_commands[] = {
|
|||
PHPDBG_COMMAND_D_EX(clear, "reset breakpoints to execute without interruption", 'c', help_clear, NULL, 0),
|
||||
PHPDBG_COMMAND_D_EX(info, "quick access to useful information on the console", 'i', help_info, NULL, 0),
|
||||
PHPDBG_COMMAND_D_EX(back, "show debug backtrace information during execution", 't', help_back, NULL, 0),
|
||||
PHPDBG_COMMAND_D_EX(catch, "catch an opcode before its execution", 'o', help_catch, NULL, 0),
|
||||
PHPDBG_COMMAND_D_EX(frame, "switch to a frame in the current stack for inspection", 'f', help_frame, NULL, 0),
|
||||
PHPDBG_COMMAND_D_EX(quiet, "be quiet during execution", 'Q', help_quiet, NULL, 0),
|
||||
PHPDBG_COMMAND_D_EX(list, "list code gives you quick access to code", 'l', help_list, NULL, 0),
|
||||
|
|
|
@ -48,6 +48,7 @@ const phpdbg_command_t phpdbg_prompt_commands[] = {
|
|||
PHPDBG_COMMAND_D(print, "print something", 'p', phpdbg_print_commands, 2),
|
||||
PHPDBG_COMMAND_D(break, "set breakpoint", 'b', phpdbg_break_commands, 1),
|
||||
PHPDBG_COMMAND_D(back, "show trace", 't', NULL, 0),
|
||||
PHPDBG_COMMAND_D(catch, "catch an opcode", 'o', NULL, 1),
|
||||
PHPDBG_COMMAND_D(frame, "switch to a frame", 'f', NULL, 1),
|
||||
PHPDBG_COMMAND_D(list, "lists some code", 'l', phpdbg_list_commands, 2),
|
||||
PHPDBG_COMMAND_D(info, "displays some informations", 'i', phpdbg_info_commands, 1),
|
||||
|
@ -163,6 +164,38 @@ next_line:
|
|||
}
|
||||
} /* }}} */
|
||||
|
||||
int phpdbg_find_catch(zend_uchar opcode TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
const char *opname = phpdbg_decode_opcode(opcode);
|
||||
|
||||
if (memcmp(opname, PHPDBG_STRL("UNKNOWN")) == 0) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return zend_hash_index_exists(&PHPDBG_G(catch),
|
||||
zend_hash_func(opname, strlen(opname))) ? SUCCESS : FAILURE;
|
||||
} /* }}} */
|
||||
|
||||
PHPDBG_COMMAND(catch) /* {{{ */
|
||||
{
|
||||
switch (param->type) {
|
||||
case STR_PARAM: {
|
||||
int tmp = 0;
|
||||
|
||||
zend_hash_index_update(&PHPDBG_G(catch),
|
||||
zend_hash_func(param->str, param->len),
|
||||
&tmp, sizeof(int), NULL);
|
||||
|
||||
PHPDBG_G(flags) |= PHPDBG_HAS_CATCH;
|
||||
}
|
||||
break;
|
||||
|
||||
phpdbg_default_switch_case();
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
} /* }}} */
|
||||
|
||||
PHPDBG_COMMAND(exec) /* {{{ */
|
||||
{
|
||||
switch (param->type) {
|
||||
|
@ -558,7 +591,7 @@ PHPDBG_COMMAND(run) /* {{{ */
|
|||
EG(active_op_array) = orig_op_array;
|
||||
EG(opline_ptr) = orig_opline;
|
||||
EG(return_value_ptr_ptr) = orig_retval_ptr;
|
||||
|
||||
|
||||
if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
|
||||
phpdbg_error("Caught exit/error from VM");
|
||||
goto out;
|
||||
|
@ -1385,12 +1418,21 @@ zend_vm_enter:
|
|||
}
|
||||
}
|
||||
|
||||
if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP)
|
||||
if (PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP
|
||||
&& phpdbg_find_breakpoint_opline(execute_data->opline TSRMLS_CC) == SUCCESS) {
|
||||
DO_INTERACTIVE();
|
||||
}
|
||||
|
||||
if ((PHPDBG_G(flags) & PHPDBG_IS_STEPPING)) {
|
||||
if (PHPDBG_G(flags) & PHPDBG_HAS_CATCH
|
||||
&& phpdbg_find_catch(execute_data->opline->opcode TSRMLS_CC) == SUCCESS) {
|
||||
phpdbg_notice("Catched opcode %s at %s:%u",
|
||||
phpdbg_decode_opcode(execute_data->opline->opcode),
|
||||
zend_get_executed_filename(TSRMLS_C),
|
||||
zend_get_executed_lineno(TSRMLS_C));
|
||||
DO_INTERACTIVE();
|
||||
}
|
||||
|
||||
if (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) {
|
||||
DO_INTERACTIVE();
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ PHPDBG_COMMAND(frame);
|
|||
PHPDBG_COMMAND(print);
|
||||
PHPDBG_COMMAND(break);
|
||||
PHPDBG_COMMAND(back);
|
||||
PHPDBG_COMMAND(catch);
|
||||
PHPDBG_COMMAND(list);
|
||||
PHPDBG_COMMAND(info);
|
||||
PHPDBG_COMMAND(clean);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue