- Added catch command

This commit is contained in:
Felipe Pena 2013-11-23 20:03:17 -02:00
parent 1c6e54ecdf
commit f5c07f61e1
6 changed files with 69 additions and 6 deletions

View file

@ -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_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(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(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); zend_hash_init(&PHPDBG_G(registered), 8, NULL, php_phpdbg_destroy_registered, 0);
return SUCCESS; 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_METHOD]);
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]); zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]);
zend_hash_destroy(&PHPDBG_G(seek)); zend_hash_destroy(&PHPDBG_G(seek));
zend_hash_destroy(&PHPDBG_G(catch));
zend_hash_destroy(&PHPDBG_G(registered)); zend_hash_destroy(&PHPDBG_G(registered));
if (PHPDBG_G(exec)) { if (PHPDBG_G(exec)) {

View file

@ -110,6 +110,8 @@
#define PHPDBG_IS_SIGNALED (1<<19) #define PHPDBG_IS_SIGNALED (1<<19)
#define PHPDBG_IS_INTERACTIVE (1<<20) #define PHPDBG_IS_INTERACTIVE (1<<20)
#define PHPDBG_HAS_CATCH (1<<21)
#ifndef _WIN32 #ifndef _WIN32
# define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET|PHPDBG_IS_COLOURED) # define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET|PHPDBG_IS_COLOURED)
#else #else
@ -138,6 +140,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
phpdbg_param_t lparam; /* last param */ phpdbg_param_t lparam; /* last param */
FILE *oplog; /* opline log */ FILE *oplog; /* opline log */
HashTable seek; /* seek oplines */ HashTable seek; /* seek oplines */
HashTable catch; /* seek opcodes */
zend_ulong flags; /* phpdbg flags */ zend_ulong flags; /* phpdbg flags */
HashTable registered; /* registered */ HashTable registered; /* registered */
phpdbg_frame_t frame; /* frame */ phpdbg_frame_t frame; /* frame */

View file

@ -341,6 +341,19 @@ PHPDBG_HELP(back) /* {{{ */
return SUCCESS; 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(frame) /* {{{ */
{ {
phpdbg_help_header(); 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_writeln("Note: upon failure to open a new oplog, the last oplog is held open");
phpdbg_help_footer(); phpdbg_help_footer();
return SUCCESS; return SUCCESS;
} }
PHPDBG_HELP(register) /* {{{ */ PHPDBG_HELP(register) /* {{{ */
{ {
@ -439,7 +452,7 @@ PHPDBG_HELP(register) /* {{{ */
HashPosition position; HashPosition position;
char *name = NULL; char *name = NULL;
zend_uint name_len = 0; zend_uint name_len = 0;
phpdbg_notice("Registered Functions (%d)", zend_hash_num_elements(&PHPDBG_G(registered))); phpdbg_notice("Registered Functions (%d)", zend_hash_num_elements(&PHPDBG_G(registered)));
for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(registered), &position); 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; 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); efree(name);
} }
} }
phpdbg_help_footer(); phpdbg_help_footer();
return SUCCESS; return SUCCESS;
} /* }}} */ } /* }}} */

View file

@ -44,6 +44,7 @@ PHPDBG_HELP(clean);
PHPDBG_HELP(clear); PHPDBG_HELP(clear);
PHPDBG_HELP(info); PHPDBG_HELP(info);
PHPDBG_HELP(back); PHPDBG_HELP(back);
PHPDBG_HELP(catch);
PHPDBG_HELP(frame); PHPDBG_HELP(frame);
PHPDBG_HELP(quiet); PHPDBG_HELP(quiet);
PHPDBG_HELP(list); 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(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(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(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(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(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), PHPDBG_COMMAND_D_EX(list, "list code gives you quick access to code", 'l', help_list, NULL, 0),

View file

@ -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(print, "print something", 'p', phpdbg_print_commands, 2),
PHPDBG_COMMAND_D(break, "set breakpoint", 'b', phpdbg_break_commands, 1), PHPDBG_COMMAND_D(break, "set breakpoint", 'b', phpdbg_break_commands, 1),
PHPDBG_COMMAND_D(back, "show trace", 't', NULL, 0), 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(frame, "switch to a frame", 'f', NULL, 1),
PHPDBG_COMMAND_D(list, "lists some code", 'l', phpdbg_list_commands, 2), PHPDBG_COMMAND_D(list, "lists some code", 'l', phpdbg_list_commands, 2),
PHPDBG_COMMAND_D(info, "displays some informations", 'i', phpdbg_info_commands, 1), 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) /* {{{ */ PHPDBG_COMMAND(exec) /* {{{ */
{ {
switch (param->type) { switch (param->type) {
@ -558,7 +591,7 @@ PHPDBG_COMMAND(run) /* {{{ */
EG(active_op_array) = orig_op_array; EG(active_op_array) = orig_op_array;
EG(opline_ptr) = orig_opline; EG(opline_ptr) = orig_opline;
EG(return_value_ptr_ptr) = orig_retval_ptr; EG(return_value_ptr_ptr) = orig_retval_ptr;
if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
phpdbg_error("Caught exit/error from VM"); phpdbg_error("Caught exit/error from VM");
goto out; 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) { && phpdbg_find_breakpoint_opline(execute_data->opline TSRMLS_CC) == SUCCESS) {
DO_INTERACTIVE(); 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(); DO_INTERACTIVE();
} }

View file

@ -40,6 +40,7 @@ PHPDBG_COMMAND(frame);
PHPDBG_COMMAND(print); PHPDBG_COMMAND(print);
PHPDBG_COMMAND(break); PHPDBG_COMMAND(break);
PHPDBG_COMMAND(back); PHPDBG_COMMAND(back);
PHPDBG_COMMAND(catch);
PHPDBG_COMMAND(list); PHPDBG_COMMAND(list);
PHPDBG_COMMAND(info); PHPDBG_COMMAND(info);
PHPDBG_COMMAND(clean); PHPDBG_COMMAND(clean);