diff --git a/config.m4 b/config.m4 index 4f98bb92bf7..f3671f4b10d 100644 --- a/config.m4 +++ b/config.m4 @@ -9,7 +9,7 @@ if test "$PHP_PHPDBG" != "no"; then AC_DEFINE(HAVE_PHPDBG, 1, [ ]) PHP_PHPDBG_CFLAGS=-I$abs_srcdir/sapi/phpdbg - PHP_PHPDBG_FILES="phpdbg.c phpdbg_prompt.c phpdbg_help.c phpdbg_bp.c" + PHP_PHPDBG_FILES="phpdbg.c phpdbg_prompt.c phpdbg_help.c phpdbg_bp.c phpdbg_opcode.c" PHP_ADD_MAKEFILE_FRAGMENT([$abs_srcdir/sapi/phpdbg/Makefile.frag]) PHP_SELECT_SAPI(phpdbg, program, $PHP_PHPDBG_FILES, $PHP_PHPDBG_CFLAGS, [$(SAPI_PHPDBG_PATH)]) diff --git a/phpdbg.c b/phpdbg.c index 48b5728d77a..feed5ecd398 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -17,6 +17,7 @@ */ #include "phpdbg.h" +#include "phpdbg_prompt.h" ZEND_DECLARE_MODULE_GLOBALS(phpdbg); @@ -30,6 +31,7 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */ pg->stepping = 0; pg->vmret = 0; pg->quitting = 0; + pg->bp_count = 0; } /* }}} */ static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */ diff --git a/phpdbg.h b/phpdbg.h index 437fe8a2441..c5f6104cefb 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -51,6 +51,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) size_t exec_len; /* size of exec */ zend_op_array *ops; /* op_array */ zval *retval; /* return value */ + int bp_count; /* breakpoint count */ int stepping; /* stepping */ int vmret; /* return from last opcode handler execution */ zend_bool has_file_bp; /* file-based breakpoint has been set */ diff --git a/phpdbg_bp.c b/phpdbg_bp.c index 52f0a243fda..ea9d94175d9 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -19,6 +19,7 @@ #include "zend.h" #include "zend_hash.h" +#include "zend_llist.h" #include "phpdbg.h" #include "phpdbg_bp.h" @@ -70,6 +71,8 @@ void phpdbg_set_breakpoint_file(const char *expr, const char *line_pos TSRMLS_DC new_break.filename, name_len, &break_files, sizeof(zend_llist), (void**)&break_files_ptr); } + + new_break.id = PHPDBG_G(bp_count)++; zend_llist_add_element(break_files_ptr, &new_break); } /* }}} */ @@ -96,32 +99,35 @@ void phpdbg_set_breakpoint_symbol(const char *expr, const char *opline_num_pos T new_break.symbol, name_len, &break_syms, sizeof(zend_llist), (void**)&break_sym_ptr); } + + new_break.id = PHPDBG_G(bp_count)++; zend_llist_add_element(break_sym_ptr, &new_break); } /* }}} */ -int phpdbg_breakpoint_file(zend_op_array *op_array TSRMLS_DC) /* {{{ */ +int phpdbg_find_breakpoint_file(zend_op_array *op_array TSRMLS_DC) /* {{{ */ { size_t name_len = strlen(op_array->filename); zend_llist *break_list; + zend_llist_element *le; if (zend_hash_find(&PHPDBG_G(bp_files), op_array->filename, name_len, - (void**)&break_list) == SUCCESS) { - zend_llist_element *le; + (void**)&break_list) == FAILURE) { + return FAILURE; + } - for (le = break_list->head; le; le = le->next) { - phpdbg_breakfile_t *bp = (phpdbg_breakfile_t*) le->data; + for (le = break_list->head; le; le = le->next) { + const phpdbg_breakfile_t *bp = (phpdbg_breakfile_t*)le->data; - if (bp->line == (*EG(opline_ptr))->lineno) { - printf("breakpoint reached!\n"); - return SUCCESS; - } + if (bp->line == (*EG(opline_ptr))->lineno) { + printf("Breakpoint #%d at %s:%ld\n", bp->id, bp->filename, bp->line); + return SUCCESS; } } return FAILURE; } /* }}} */ -int phpdbg_breakpoint_symbol(zend_function *fbc TSRMLS_DC) /* {{{ */ +int phpdbg_find_breakpoint_symbol(zend_function *fbc TSRMLS_DC) /* {{{ */ { const char *fname; zend_llist *break_list; diff --git a/phpdbg_bp.h b/phpdbg_bp.h index 78909d2ae36..38b9c6174c6 100644 --- a/phpdbg_bp.h +++ b/phpdbg_bp.h @@ -26,6 +26,7 @@ typedef struct _phpdbg_breakfile_t { const char *filename; long line; + int id; } phpdbg_breakfile_t; /** @@ -34,9 +35,13 @@ typedef struct _phpdbg_breakfile_t { typedef struct _phpdbg_breaksymbol_t { const char *symbol; long opline_num; + int id; } phpdbg_breaksymbol_t; void phpdbg_set_breakpoint_file(const char*, const char* TSRMLS_DC); void phpdbg_set_breakpoint_symbol(const char*, const char* TSRMLS_DC); +int phpdbg_find_breakpoint_file(zend_op_array* TSRMLS_DC); +int phpdbg_find_breakpoint_symbol(zend_function* TSRMLS_DC); + #endif /* PHPDBG_BP_H */ diff --git a/phpdbg_opcode.c b/phpdbg_opcode.c new file mode 100644 index 00000000000..60d40756254 --- /dev/null +++ b/phpdbg_opcode.c @@ -0,0 +1,195 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + +----------------------------------------------------------------------+ +*/ + +#include "zend_vm_opcodes.h" +#include "phpdbg_opcode.h" + +const char *phpdbg_decode_opcode(zend_uchar opcode) /* {{{ */ +{ +#define CASE(s) return #s + switch (opcode) { + CASE(ZEND_NOP); + CASE(ZEND_ADD); + CASE(ZEND_SUB); + CASE(ZEND_MUL); + CASE(ZEND_DIV); + CASE(ZEND_MOD); + CASE(ZEND_SL); + CASE(ZEND_SR); + CASE(ZEND_CONCAT); + CASE(ZEND_BW_OR); + CASE(ZEND_BW_AND); + CASE(ZEND_BW_XOR); + CASE(ZEND_BW_NOT); + CASE(ZEND_BOOL_NOT); + CASE(ZEND_BOOL_XOR); + CASE(ZEND_IS_IDENTICAL); + CASE(ZEND_IS_NOT_IDENTICAL); + CASE(ZEND_IS_EQUAL); + CASE(ZEND_IS_NOT_EQUAL); + CASE(ZEND_IS_SMALLER); + CASE(ZEND_IS_SMALLER_OR_EQUAL); + CASE(ZEND_CAST); + CASE(ZEND_QM_ASSIGN); + CASE(ZEND_ASSIGN_ADD); + CASE(ZEND_ASSIGN_SUB); + CASE(ZEND_ASSIGN_MUL); + CASE(ZEND_ASSIGN_DIV); + CASE(ZEND_ASSIGN_MOD); + CASE(ZEND_ASSIGN_SL); + CASE(ZEND_ASSIGN_SR); + CASE(ZEND_ASSIGN_CONCAT); + CASE(ZEND_ASSIGN_BW_OR); + CASE(ZEND_ASSIGN_BW_AND); + CASE(ZEND_ASSIGN_BW_XOR); + CASE(ZEND_PRE_INC); + CASE(ZEND_PRE_DEC); + CASE(ZEND_POST_INC); + CASE(ZEND_POST_DEC); + CASE(ZEND_ASSIGN); + CASE(ZEND_ASSIGN_REF); + CASE(ZEND_ECHO); + CASE(ZEND_PRINT); + CASE(ZEND_JMP); + CASE(ZEND_JMPZ); + CASE(ZEND_JMPNZ); + CASE(ZEND_JMPZNZ); + CASE(ZEND_JMPZ_EX); + CASE(ZEND_JMPNZ_EX); + CASE(ZEND_CASE); + CASE(ZEND_SWITCH_FREE); + CASE(ZEND_BRK); + CASE(ZEND_CONT); + CASE(ZEND_BOOL); + CASE(ZEND_INIT_STRING); + CASE(ZEND_ADD_CHAR); + CASE(ZEND_ADD_STRING); + CASE(ZEND_ADD_VAR); + CASE(ZEND_BEGIN_SILENCE); + CASE(ZEND_END_SILENCE); + CASE(ZEND_INIT_FCALL_BY_NAME); + CASE(ZEND_DO_FCALL); + CASE(ZEND_DO_FCALL_BY_NAME); + CASE(ZEND_RETURN); + CASE(ZEND_RECV); + CASE(ZEND_RECV_INIT); + CASE(ZEND_SEND_VAL); + CASE(ZEND_SEND_VAR); + CASE(ZEND_SEND_REF); + CASE(ZEND_NEW); + CASE(ZEND_INIT_NS_FCALL_BY_NAME); + CASE(ZEND_FREE); + CASE(ZEND_INIT_ARRAY); + CASE(ZEND_ADD_ARRAY_ELEMENT); + CASE(ZEND_INCLUDE_OR_EVAL); + CASE(ZEND_UNSET_VAR); + CASE(ZEND_UNSET_DIM); + CASE(ZEND_UNSET_OBJ); + CASE(ZEND_FE_RESET); + CASE(ZEND_FE_FETCH); + CASE(ZEND_EXIT); + CASE(ZEND_FETCH_R); + CASE(ZEND_FETCH_DIM_R); + CASE(ZEND_FETCH_OBJ_R); + CASE(ZEND_FETCH_W); + CASE(ZEND_FETCH_DIM_W); + CASE(ZEND_FETCH_OBJ_W); + CASE(ZEND_FETCH_RW); + CASE(ZEND_FETCH_DIM_RW); + CASE(ZEND_FETCH_OBJ_RW); + CASE(ZEND_FETCH_IS); + CASE(ZEND_FETCH_DIM_IS); + CASE(ZEND_FETCH_OBJ_IS); + CASE(ZEND_FETCH_FUNC_ARG); + CASE(ZEND_FETCH_DIM_FUNC_ARG); + CASE(ZEND_FETCH_OBJ_FUNC_ARG); + CASE(ZEND_FETCH_UNSET); + CASE(ZEND_FETCH_DIM_UNSET); + CASE(ZEND_FETCH_OBJ_UNSET); + CASE(ZEND_FETCH_DIM_TMP_VAR); + CASE(ZEND_FETCH_CONSTANT); + CASE(ZEND_GOTO); + CASE(ZEND_EXT_STMT); + CASE(ZEND_EXT_FCALL_BEGIN); + CASE(ZEND_EXT_FCALL_END); + CASE(ZEND_EXT_NOP); + CASE(ZEND_TICKS); + CASE(ZEND_SEND_VAR_NO_REF); + CASE(ZEND_CATCH); + CASE(ZEND_THROW); + CASE(ZEND_FETCH_CLASS); + CASE(ZEND_CLONE); + CASE(ZEND_RETURN_BY_REF); + CASE(ZEND_INIT_METHOD_CALL); + CASE(ZEND_INIT_STATIC_METHOD_CALL); + CASE(ZEND_ISSET_ISEMPTY_VAR); + CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ); + CASE(ZEND_PRE_INC_OBJ); + CASE(ZEND_PRE_DEC_OBJ); + CASE(ZEND_POST_INC_OBJ); + CASE(ZEND_POST_DEC_OBJ); + CASE(ZEND_ASSIGN_OBJ); + CASE(ZEND_INSTANCEOF); + CASE(ZEND_DECLARE_CLASS); + CASE(ZEND_DECLARE_INHERITED_CLASS); + CASE(ZEND_DECLARE_FUNCTION); + CASE(ZEND_RAISE_ABSTRACT_ERROR); + CASE(ZEND_DECLARE_CONST); + CASE(ZEND_ADD_INTERFACE); + CASE(ZEND_DECLARE_INHERITED_CLASS_DELAYED); + CASE(ZEND_VERIFY_ABSTRACT_CLASS); + CASE(ZEND_ASSIGN_DIM); + CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ); + CASE(ZEND_HANDLE_EXCEPTION); + CASE(ZEND_USER_OPCODE); +#ifdef ZEND_JMP_SET + CASE(ZEND_JMP_SET); +#endif + CASE(ZEND_DECLARE_LAMBDA_FUNCTION); +#ifdef ZEND_ADD_TRAIT + CASE(ZEND_ADD_TRAIT); +#endif +#ifdef ZEND_BIND_TRAITS + CASE(ZEND_BIND_TRAITS); +#endif +#ifdef ZEND_SEPARATE + CASE(ZEND_SEPARATE); +#endif +#ifdef ZEND_QM_ASSIGN_VAR + CASE(ZEND_QM_ASSIGN_VAR); +#endif +#ifdef ZEND_JMP_SET_VAR + CASE(ZEND_JMP_SET_VAR); +#endif + CASE(ZEND_DISCARD_EXCEPTION); + CASE(ZEND_YIELD); + CASE(ZEND_GENERATOR_RETURN); +#ifdef ZEND_FAST_CALL + CASE(ZEND_FAST_CALL); +#endif +#ifdef ZEND_FAST_RET + CASE(ZEND_FAST_RET); +#endif +#ifdef ZEND_RECV_VARIADIC + CASE(ZEND_RECV_VARIADIC); +#endif + CASE(ZEND_OP_DATA); + default: return "UNKNOWN"; + } +} /* }}} */ diff --git a/phpdbg_opcode.h b/phpdbg_opcode.h new file mode 100644 index 00000000000..28fc806c1c0 --- /dev/null +++ b/phpdbg_opcode.h @@ -0,0 +1,27 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Felipe Pena | + | Authors: Joe Watkins | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_OPCODE_H +#define PHPDBG_OPCODE_H + +#include "zend_types.h" + +const char *phpdbg_decode_opcode(zend_uchar); + +#endif /* PHPDBG_OPCODE_H */ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index a5fa359290d..3f88675357c 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -24,6 +24,7 @@ #include "phpdbg.h" #include "phpdbg_help.h" #include "phpdbg_bp.h" +#include "phpdbg_opcode.h" static const phpdbg_command_t phpdbg_prompt_commands[]; @@ -253,7 +254,7 @@ static PHPDBG_COMMAND(help) /* {{{ */ ++help_command; } } else { - if (phpdbg_do_cmd(phpdbg_help_commands, expr, expr_len TSRMLS_CC) == FAILURE) { + if (phpdbg_do_cmd(phpdbg_help_commands, (char*)expr, expr_len TSRMLS_CC) == FAILURE) { printf("failed to find help command: %s\n", expr); } } @@ -333,184 +334,11 @@ int phpdbg_interactive(int argc, char **argv TSRMLS_DC) /* {{{ */ return SUCCESS; } /* }}} */ -static const char *phpdbg_decode_opcode(zend_uchar opcode TSRMLS_DC) { /* {{{ */ - switch (opcode) { - case ZEND_NOP: return "ZEND_NOP"; - case ZEND_ADD: return "ZEND_ADD"; - case ZEND_SUB: return "ZEND_SUB"; - case ZEND_MUL: return "ZEND_MUL"; - case ZEND_DIV: return "ZEND_DIV"; - case ZEND_MOD: return "ZEND_MOD"; - case ZEND_SL: return "ZEND_SL"; - case ZEND_SR: return "ZEND_SR"; - case ZEND_CONCAT: return "ZEND_CONCAT"; - case ZEND_BW_OR: return "ZEND_BW_OR"; - case ZEND_BW_AND: return "ZEND_BW_AND"; - case ZEND_BW_XOR: return "ZEND_BW_XOR"; - case ZEND_BW_NOT: return "ZEND_BW_NOT"; - case ZEND_BOOL_NOT: return "ZEND_BOOL_NOT"; - case ZEND_BOOL_XOR: return "ZEND_BOOL_XOR"; - case ZEND_IS_IDENTICAL: return "ZEND_IS_IDENTICAL"; - case ZEND_IS_NOT_IDENTICAL: return "ZEND_IS_NOT_IDENTICAL"; - case ZEND_IS_EQUAL: return "ZEND_IS_EQUAL"; - case ZEND_IS_NOT_EQUAL: return "ZEND_IS_NOT_EQUAL"; - case ZEND_IS_SMALLER: return "ZEND_IS_SMALLER"; - case ZEND_IS_SMALLER_OR_EQUAL: return "ZEND_IS_SMALLER_OR_EQUAL"; - case ZEND_CAST: return "ZEND_CAST"; - case ZEND_QM_ASSIGN: return "ZEND_QM_ASSIGN"; - case ZEND_ASSIGN_ADD: return "ZEND_ASSIGN_ADD"; - case ZEND_ASSIGN_SUB: return "ZEND_ASSIGN_SUB"; - case ZEND_ASSIGN_MUL: return "ZEND_ASSIGN_MUL"; - case ZEND_ASSIGN_DIV: return "ZEND_ASSIGN_DIV"; - case ZEND_ASSIGN_MOD: return "ZEND_ASSIGN_MOD"; - case ZEND_ASSIGN_SL: return "ZEND_ASSIGN_SL"; - case ZEND_ASSIGN_SR: return "ZEND_ASSIGN_SR"; - case ZEND_ASSIGN_CONCAT: return "ZEND_ASSIGN_CONCAT"; - case ZEND_ASSIGN_BW_OR: return "ZEND_ASSIGN_BW_OR"; - case ZEND_ASSIGN_BW_AND: return "ZEND_ASSIGN_BW_AND"; - case ZEND_ASSIGN_BW_XOR: return "ZEND_ASSIGN_BW_XOR"; - case ZEND_PRE_INC: return "ZEND_PRE_INC"; - case ZEND_PRE_DEC: return "ZEND_PRE_DEC"; - case ZEND_POST_INC: return "ZEND_POST_INC"; - case ZEND_POST_DEC: return "ZEND_POST_DEC"; - case ZEND_ASSIGN: return "ZEND_ASSIGN"; - case ZEND_ASSIGN_REF: return "ZEND_ASSIGN_REF"; - case ZEND_ECHO: return "ZEND_ECHO"; - case ZEND_PRINT: return "ZEND_PRINT"; - case ZEND_JMP: return "ZEND_JMP"; - case ZEND_JMPZ: return "ZEND_JMPZ"; - case ZEND_JMPNZ: return "ZEND_JMPNZ"; - case ZEND_JMPZNZ: return "ZEND_JMPZNZ"; - case ZEND_JMPZ_EX: return "ZEND_JMPZ_EX"; - case ZEND_JMPNZ_EX: return "ZEND_JMPNZ_EX"; - case ZEND_CASE: return "ZEND_CASE"; - case ZEND_SWITCH_FREE: return "ZEND_SWITCH_FREE"; - case ZEND_BRK: return "ZEND_BRK"; - case ZEND_CONT: return "ZEND_CONT"; - case ZEND_BOOL: return "ZEND_BOOL"; - case ZEND_INIT_STRING: return "ZEND_INIT_STRING"; - case ZEND_ADD_CHAR: return "ZEND_ADD_CHAR"; - case ZEND_ADD_STRING: return "ZEND_ADD_STRING"; - case ZEND_ADD_VAR: return "ZEND_ADD_VAR"; - case ZEND_BEGIN_SILENCE: return "ZEND_BEGIN_SILENCE"; - case ZEND_END_SILENCE: return "ZEND_END_SILENCE"; - case ZEND_INIT_FCALL_BY_NAME: return "ZEND_INIT_FCALL_BY_NAME"; - case ZEND_DO_FCALL: return "ZEND_DO_FCALL"; - case ZEND_DO_FCALL_BY_NAME: return "ZEND_DO_FCALL_BY_NAME"; - case ZEND_RETURN: return "ZEND_RETURN"; - case ZEND_RECV: return "ZEND_RECV"; - case ZEND_RECV_INIT: return "ZEND_RECV_INIT"; - case ZEND_SEND_VAL: return "ZEND_SEND_VAL"; - case ZEND_SEND_VAR: return "ZEND_SEND_VAR"; - case ZEND_SEND_REF: return "ZEND_SEND_REF"; - case ZEND_NEW: return "ZEND_NEW"; - case ZEND_INIT_NS_FCALL_BY_NAME: return "ZEND_INIT_NS_FCALL_BY_NAME"; - case ZEND_FREE: return "ZEND_FREE"; - case ZEND_INIT_ARRAY: return "ZEND_INIT_ARRAY"; - case ZEND_ADD_ARRAY_ELEMENT: return "ZEND_ADD_ARRAY_ELEMENT"; - case ZEND_INCLUDE_OR_EVAL: return "ZEND_INCLUDE_OR_EVAL"; - case ZEND_UNSET_VAR: return "ZEND_UNSET_VAR"; - case ZEND_UNSET_DIM: return "ZEND_UNSET_DIM"; - case ZEND_UNSET_OBJ: return "ZEND_UNSET_OBJ"; - case ZEND_FE_RESET: return "ZEND_FE_RESET"; - case ZEND_FE_FETCH: return "ZEND_FE_FETCH"; - case ZEND_EXIT: return "ZEND_EXIT"; - case ZEND_FETCH_R: return "ZEND_FETCH_R"; - case ZEND_FETCH_DIM_R: return "ZEND_FETCH_DIM_R"; - case ZEND_FETCH_OBJ_R: return "ZEND_FETCH_OBJ_R"; - case ZEND_FETCH_W: return "ZEND_FETCH_W"; - case ZEND_FETCH_DIM_W: return "ZEND_FETCH_DIM_W"; - case ZEND_FETCH_OBJ_W: return "ZEND_FETCH_OBJ_W"; - case ZEND_FETCH_RW: return "ZEND_FETCH_RW"; - case ZEND_FETCH_DIM_RW: return "ZEND_FETCH_DIM_RW"; - case ZEND_FETCH_OBJ_RW: return "ZEND_FETCH_OBJ_RW"; - case ZEND_FETCH_IS: return "ZEND_FETCH_IS"; - case ZEND_FETCH_DIM_IS: return "ZEND_FETCH_DIM_IS"; - case ZEND_FETCH_OBJ_IS: return "ZEND_FETCH_OBJ_IS"; - case ZEND_FETCH_FUNC_ARG: return "ZEND_FETCH_FUNC_ARG"; - case ZEND_FETCH_DIM_FUNC_ARG: return "ZEND_FETCH_DIM_FUNC_ARG"; - case ZEND_FETCH_OBJ_FUNC_ARG: return "ZEND_FETCH_OBJ_FUNC_ARG"; - case ZEND_FETCH_UNSET: return "ZEND_FETCH_UNSET"; - case ZEND_FETCH_DIM_UNSET: return "ZEND_FETCH_DIM_UNSET"; - case ZEND_FETCH_OBJ_UNSET: return "ZEND_FETCH_OBJ_UNSET"; - case ZEND_FETCH_DIM_TMP_VAR: return "ZEND_FETCH_DIM_TMP_VAR"; - case ZEND_FETCH_CONSTANT: return "ZEND_FETCH_CONSTANT"; - case ZEND_GOTO: return "ZEND_GOTO"; - case ZEND_EXT_STMT: return "ZEND_EXT_STMT"; - case ZEND_EXT_FCALL_BEGIN: return "ZEND_EXT_FCALL_BEGIN"; - case ZEND_EXT_FCALL_END: return "ZEND_EXT_FCALL_END"; - case ZEND_EXT_NOP: return "ZEND_EXT_NOP"; - case ZEND_TICKS: return "ZEND_TICKS"; - case ZEND_SEND_VAR_NO_REF: return "ZEND_SEND_VAR_NO_REF"; - case ZEND_CATCH: return "ZEND_CATCH"; - case ZEND_THROW: return "ZEND_THROW"; - case ZEND_FETCH_CLASS: return "ZEND_FETCH_CLASS"; - case ZEND_CLONE: return "ZEND_CLONE"; - case ZEND_RETURN_BY_REF: return "ZEND_RETURN_BY_REF"; - case ZEND_INIT_METHOD_CALL: return "ZEND_INIT_METHOD_CALL"; - case ZEND_INIT_STATIC_METHOD_CALL: return "ZEND_INIT_STATIC_METHOD_CALL"; - case ZEND_ISSET_ISEMPTY_VAR: return "ZEND_ISSET_ISEMPTY_VAR"; - case ZEND_ISSET_ISEMPTY_DIM_OBJ: return "ZEND_ISSET_ISEMPTY_DIM_OBJ"; - case ZEND_PRE_INC_OBJ: return "ZEND_PRE_INC_OBJ"; - case ZEND_PRE_DEC_OBJ: return "ZEND_PRE_DEC_OBJ"; - case ZEND_POST_INC_OBJ: return "ZEND_POST_INC_OBJ"; - case ZEND_POST_DEC_OBJ: return "ZEND_POST_DEC_OBJ"; - case ZEND_ASSIGN_OBJ: return "ZEND_ASSIGN_OBJ"; - case ZEND_INSTANCEOF: return "ZEND_INSTANCEOF"; - case ZEND_DECLARE_CLASS: return "ZEND_DECLARE_CLASS"; - case ZEND_DECLARE_INHERITED_CLASS: return "ZEND_DECLARE_INHERITED_CLASS"; - case ZEND_DECLARE_FUNCTION: return "ZEND_DECLARE_FUNCTION"; - case ZEND_RAISE_ABSTRACT_ERROR: return "ZEND_RAISE_ABSTRACT_ERROR"; - case ZEND_DECLARE_CONST: return "ZEND_DECLARE_CONST"; - case ZEND_ADD_INTERFACE: return "ZEND_ADD_INTERFACE"; - case ZEND_DECLARE_INHERITED_CLASS_DELAYED: return "ZEND_DECLARE_INHERITED_CLASS_DELAYED"; - case ZEND_VERIFY_ABSTRACT_CLASS: return "ZEND_VERIFY_ABSTRACT_CLASS"; - case ZEND_ASSIGN_DIM: return "ZEND_ASSIGN_DIM"; - case ZEND_ISSET_ISEMPTY_PROP_OBJ: return "ZEND_ISSET_ISEMPTY_PROP_OBJ"; - case ZEND_HANDLE_EXCEPTION: return "ZEND_HANDLE_EXCEPTION"; - case ZEND_USER_OPCODE: return "ZEND_USER_OPCODE"; -#ifdef ZEND_JMP_SET - case ZEND_JMP_SET: return "ZEND_JMP_SET"; -#endif - case ZEND_DECLARE_LAMBDA_FUNCTION: return "ZEND_DECLARE_LAMBDA_FUNCTION"; -#ifdef ZEND_ADD_TRAIT - case ZEND_ADD_TRAIT: return "ZEND_ADD_TRAIT"; -#endif -#ifdef ZEND_BIND_TRAITS - case ZEND_BIND_TRAITS: return "ZEND_BIND_TRAITS"; -#endif -#ifdef ZEND_SEPARATE - case ZEND_SEPARATE: return "ZEND_SEPARATE"; -#endif -#ifdef ZEND_QM_ASSIGN_VAR - case ZEND_QM_ASSIGN_VAR: return "ZEND_QM_ASSIGN_VAR"; -#endif -#ifdef ZEND_JMP_SET_VAR - case ZEND_JMP_SET_VAR: return "ZEND_JMP_SET_VAR"; -#endif - case ZEND_DISCARD_EXCEPTION: return "ZEND_DISCARD_EXCEPTION"; - case ZEND_YIELD: return "ZEND_YIELD"; - case ZEND_GENERATOR_RETURN: return "ZEND_GENERATOR_RETURN"; -#ifdef ZEND_FAST_CALL - case ZEND_FAST_CALL: return "ZEND_FAST_CALL"; -#endif -#ifdef ZEND_FAST_RET - case ZEND_FAST_RET: return "ZEND_FAST_RET"; -#endif -#ifdef ZEND_RECV_VARIADIC - case ZEND_RECV_VARIADIC: return "ZEND_RECV_VARIADIC"; -#endif - case ZEND_OP_DATA: return "ZEND_OP_DATA"; - - default: return "UNKNOWN"; - } -} /* }}} */ - -static void phpdbg_print_opline(zend_execute_data *execute_data TSRMLS_DC) { /* {{{ */ +static void phpdbg_print_opline(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */ +{ zend_op *opline = execute_data->opline; - printf( - "[OPLINE: %p:%s]\n", opline, phpdbg_decode_opcode(opline->opcode TSRMLS_CC)); + printf("[OPLINE: %p:%s]\n", opline, phpdbg_decode_opcode(opline->opcode)); } /* }}} */ void phpdbg_execute_ex(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */ @@ -532,35 +360,20 @@ zend_vm_enter: #endif if (PHPDBG_G(has_file_bp) - && phpdbg_breakpoint_file(execute_data->op_array TSRMLS_CC) == SUCCESS) { + && phpdbg_find_breakpoint_file(execute_data->op_array TSRMLS_CC) == SUCCESS) { while (phpdbg_interactive(0, NULL TSRMLS_CC) != PHPDBG_NEXT) { continue; } } - if (PHPDBG_G(has_sym_bp)) { - zend_execute_data *previous = execute_data->prev_execute_data; - if (previous && (previous != execute_data)) { - if (previous->opline) { - if (previous->opline->opcode == ZEND_DO_FCALL || previous->opline->opcode == ZEND_DO_FCALL_BY_NAME) { - if (phpdbg_breakpoint_symbol(previous->function_state.function TSRMLS_CC) == SUCCESS) { - while (phpdbg_interactive(0, NULL TSRMLS_CC) != PHPDBG_NEXT) { - continue; - } - } - } - } - } else { - if (execute_data->opline->opcode == ZEND_DO_FCALL || execute_data->opline->opcode == ZEND_DO_FCALL_BY_NAME) { - if (phpdbg_breakpoint_symbol(execute_data->function_state.function TSRMLS_CC) == SUCCESS) { - while (phpdbg_interactive(0, NULL TSRMLS_CC) != PHPDBG_NEXT) { - continue; - } - } - } - } - } - + if (PHPDBG_G(has_sym_bp) + && (execute_data->opline->opcode == ZEND_DO_FCALL || execute_data->opline->opcode == ZEND_DO_FCALL_BY_NAME) + && phpdbg_find_breakpoint_symbol(execute_data->function_state.function TSRMLS_CC) == SUCCESS) { + while (phpdbg_interactive(0, NULL TSRMLS_CC) != PHPDBG_NEXT) { + continue; + } + } + PHPDBG_G(vmret) = execute_data->opline->handler(execute_data TSRMLS_CC); phpdbg_print_opline(