fi
PHP_PHPDBG_CFLAGS="-I$abc_srcdir"
- PHP_PHPDBG_FILES="phpdbg.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c"
+ PHP_PHPDBG_FILES="phpdbg.c phpdbg_prompt.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_info.c phpdbg_cmd.c"
PHP_SUBST(PHP_PHPDBG_CFLAGS)
PHP_SUBST(PHP_PHPDBG_FILES)
void (*zend_execute_old)(zend_op_array *op_array TSRMLS_DC);
#endif
-const char* phpdbg_get_param_type(phpdbg_param_t *param TSRMLS_DC) {
- switch (param->type) {
- case EMPTY_PARAM:
- return "empty";
- case ADDR_PARAM:
- return "address";
- case NUMERIC_PARAM:
- return "numeric";
- case METHOD_PARAM:
- return "method";
- case FILE_PARAM:
- return "file";
- case STR_PARAM:
- return "string";
-
- default: /* this is bad */
- return "unknown";
- }
-}
-
-phpdbg_param_type phpdbg_parse_param(const char *str, size_t len, phpdbg_param_t *param TSRMLS_DC) /* {{{ */
-{
- char *class_name, *func_name;
-
- if (len == 0) {
- param->type = EMPTY_PARAM;
- goto parsed;
- }
-
- if (phpdbg_is_addr(str)) {
-
- param->addr = strtoul(str, 0, 16);
- param->type = ADDR_PARAM;
- goto parsed;
-
- } else if (phpdbg_is_numeric(str)) {
-
- param->num = strtol(str, NULL, 0);
- param->type = NUMERIC_PARAM;
- goto parsed;
-
- } else if (phpdbg_is_class_method(str, len+1, &class_name, &func_name)) {
-
- param->method.class = class_name;
- param->method.name = func_name;
- param->type = METHOD_PARAM;
- goto parsed;
-
- } else {
- const char *line_pos = strchr(str, ':');
-
- if (line_pos && phpdbg_is_numeric(line_pos+1)) {
- char path[MAXPATHLEN];
-
- memcpy(path, str, line_pos - str);
- path[line_pos - str] = 0;
-
- param->file.name = phpdbg_resolve_path(path TSRMLS_CC);
- param->file.line = strtol(line_pos+1, NULL, 0);
- param->type = FILE_PARAM;
- goto parsed;
- }
- }
-
- param->str = estrndup(str, len);
- param->len = len;
- param->type = STR_PARAM;
-
-parsed:
- phpdbg_debug("phpdbg_parse_param(\"%s\", %lu): %s", str, len, phpdbg_get_param_type(param TSRMLS_CC));
- return param->type;
-} /* }}} */
-
-void phpdbg_clear_param(phpdbg_param_t *param TSRMLS_DC) /* {{{ */
-{
- switch (param->type) {
- case FILE_PARAM:
- efree(param->file.name);
- break;
- case METHOD_PARAM:
- efree(param->method.class);
- efree(param->method.name);
- break;
- case STR_PARAM:
- efree(param->str);
- break;
- default:
- break;
- }
-} /* }}} */
-
static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */
{
pg->exec = NULL;
# include <readline/history.h>
#endif
+#include "phpdbg_cmd.h"
+
#ifdef ZTS
# define PHPDBG_G(v) TSRMG(phpdbg_globals_id, zend_phpdbg_globals *, v)
#else
#define PHPDBG_ISSUES "http://github.com/krakjoe/phpdbg/issues"
#define PHPDBG_VERSION "0.0.2-dev" /* }}} */
-typedef struct _phpdbg_command_t phpdbg_command_t;
-
-/* {{{ Command and Parameter */
-typedef enum {
- EMPTY_PARAM = 0,
- ADDR_PARAM,
- FILE_PARAM,
- METHOD_PARAM,
- STR_PARAM,
- NUMERIC_PARAM
-} phpdbg_param_type;
-
-typedef struct _phpdbg_param {
- phpdbg_param_type type;
- long num;
- zend_ulong addr;
- struct {
- char *name;
- long line;
- } file;
- struct {
- char *class;
- char *name;
- } method;
- char *str;
- size_t len;
-} phpdbg_param_t;
-
-typedef int (*phpdbg_command_handler_t)(phpdbg_param_t *param TSRMLS_DC);
-
-struct _phpdbg_command_t {
- const char *name; /* Command name */
- size_t name_len; /* Command name length */
- const char *tip; /* Menu tip */
- size_t tip_len; /* Menu tip length */
- char alias; /* Alias */
- phpdbg_command_handler_t handler; /* Command handler */
- const phpdbg_command_t *subs; /* Sub Commands */
-};
-
-#define PHPDBG_END_COMAND {NULL, 0, NULL, 0, '\0', NULL, NULL}
-
ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
HashTable bp[PHPDBG_BREAK_TABLES]; /* break points */
char *exec; /* file to execute */
zend_ulong flags; /* phpdbg flags */
FILE *oplog; /* opline log */
ZEND_END_MODULE_GLOBALS(phpdbg)
-
-phpdbg_param_type phpdbg_parse_param(const char*, size_t, phpdbg_param_t* TSRMLS_DC);
-void phpdbg_clear_param(phpdbg_param_t * TSRMLS_DC);
-const char* phpdbg_get_param_type(phpdbg_param_t *param TSRMLS_DC);
/* }}} */
#endif /* PHPDBG_H */
#define PHPDBG_BREAK_H
#include "TSRM.h"
+#include "phpdbg_cmd.h"
-/**
- * Command Declarators
- */
-#define PHPDBG_BREAK_D(name, tip) \
- {PHPDBG_STRL(#name), tip, sizeof(tip)-1, 0, phpdbg_do_break_##name, NULL}
-#define PHPDBG_BREAK_EX_D(name, tip, alias) \
- {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_break_##name, NULL}
-#define PHPDBG_BREAK(name) \
- int phpdbg_do_break_##name(phpdbg_param_t *param TSRMLS_DC)
+#define PHPDBG_BREAK(name) PHPDBG_COMMAND(break_##name)
/**
* Printer Forward Declarations
* Commands
*/
static const phpdbg_command_t phpdbg_break_commands[] = {
- PHPDBG_BREAK_EX_D(file, "specify breakpoint by file:line", 'F'),
- PHPDBG_BREAK_EX_D(method, "specify breakpoint by class::method", 'm'),
- PHPDBG_BREAK_EX_D(address, "specify breakpoint by address", 'a'),
- PHPDBG_BREAK_EX_D(on, "specify breakpoint by expression", 'o'),
- PHPDBG_BREAK_EX_D(lineno, "specify breakpoint by line of currently executing file", 'l'),
- PHPDBG_BREAK_EX_D(func, "specify breakpoint by global function name", 'f'),
- PHPDBG_END_COMAND
+ PHPDBG_COMMAND_D_EX(file, "specify breakpoint by file:line", 'F', break_file, NULL, 1),
+ PHPDBG_COMMAND_D_EX(method, "specify breakpoint by class::method", 'm', break_method, NULL, 1),
+ PHPDBG_COMMAND_D_EX(address, "specify breakpoint by address", 'a', break_address, NULL, 1),
+ PHPDBG_COMMAND_D_EX(on, "specify breakpoint by expression", 'o', break_on, NULL, 1),
+ PHPDBG_COMMAND_D_EX(lineno, "specify breakpoint by line of currently executing file", 'l', break_lineno, NULL, 1),
+ PHPDBG_COMMAND_D_EX(func, "specify breakpoint by global function name", 'f', break_func, NULL, 1),
+ PHPDBG_END_COMMAND
};
#endif /* PHPDBG_BREAK_H */
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | 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 <felipe@php.net> |
+ | Authors: Joe Watkins <joe.watkins@live.co.uk> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "phpdbg.h"
+#include "phpdbg_cmd.h"
+#include "phpdbg_utils.h"
+
+ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
+
+const char *phpdbg_get_param_type(const phpdbg_param_t *param TSRMLS_DC) /* {{{ */
+{
+ switch (param->type) {
+ case EMPTY_PARAM:
+ return "empty";
+ case ADDR_PARAM:
+ return "address";
+ case NUMERIC_PARAM:
+ return "numeric";
+ case METHOD_PARAM:
+ return "method";
+ case FILE_PARAM:
+ return "file";
+ case STR_PARAM:
+ return "string";
+ default: /* this is bad */
+ return "unknown";
+ }
+}
+
+phpdbg_param_type phpdbg_parse_param(const char *str, size_t len, phpdbg_param_t *param TSRMLS_DC) /* {{{ */
+{
+ char *class_name, *func_name;
+
+ if (len == 0) {
+ param->type = EMPTY_PARAM;
+ goto parsed;
+ }
+
+ if (phpdbg_is_addr(str)) {
+
+ param->addr = strtoul(str, 0, 16);
+ param->type = ADDR_PARAM;
+ goto parsed;
+
+ } else if (phpdbg_is_numeric(str)) {
+
+ param->num = strtol(str, NULL, 0);
+ param->type = NUMERIC_PARAM;
+ goto parsed;
+
+ } else if (phpdbg_is_class_method(str, len+1, &class_name, &func_name)) {
+
+ param->method.class = class_name;
+ param->method.name = func_name;
+ param->type = METHOD_PARAM;
+ goto parsed;
+
+ } else {
+ const char *line_pos = strchr(str, ':');
+
+ if (line_pos && phpdbg_is_numeric(line_pos+1)) {
+ char path[MAXPATHLEN];
+
+ memcpy(path, str, line_pos - str);
+ path[line_pos - str] = 0;
+
+ param->file.name = phpdbg_resolve_path(path TSRMLS_CC);
+ param->file.line = strtol(line_pos+1, NULL, 0);
+ param->type = FILE_PARAM;
+ goto parsed;
+ }
+ }
+
+ param->str = estrndup(str, len);
+ param->len = len;
+ param->type = STR_PARAM;
+
+parsed:
+ phpdbg_debug("phpdbg_parse_param(\"%s\", %lu): %s", str, len, phpdbg_get_param_type(param TSRMLS_CC));
+ return param->type;
+} /* }}} */
+
+void phpdbg_clear_param(phpdbg_param_t *param TSRMLS_DC) /* {{{ */
+{
+ switch (param->type) {
+ case FILE_PARAM:
+ efree(param->file.name);
+ break;
+ case METHOD_PARAM:
+ efree(param->method.class);
+ efree(param->method.name);
+ break;
+ case STR_PARAM:
+ efree(param->str);
+ break;
+ default:
+ break;
+ }
+} /* }}} */
+
+int phpdbg_do_cmd( const phpdbg_command_t *command,
+ phpdbg_command_t **selected,
+ char *cmd_line, size_t cmd_len TSRMLS_DC) /* {{{ */
+{
+ int rc = FAILURE;
+
+ char *expr = NULL;
+#ifndef _WIN32
+ const char *cmd = strtok_r(cmd_line, " ", &expr);
+#else
+ const char *cmd = strtok_s(cmd_line, " ", &expr);
+#endif
+ size_t expr_len = (cmd != NULL) ? strlen(cmd) : 0;
+
+ phpdbg_param_t *param = NULL;
+
+ while (command && command->name && command->handler) {
+ if ((command->name_len == expr_len && memcmp(cmd, command->name, expr_len) == 0)
+ || (expr_len == 1 && command->alias && command->alias == cmd_line[0])) {
+
+ param = emalloc(sizeof(phpdbg_param_t));
+
+ PHPDBG_G(last) = (phpdbg_command_t*) command;
+
+ /* urm ... */
+ if (PHPDBG_G(lparam)) {
+ //phpdbg_clear_param(
+ // PHPDBG_G(lparam) TSRMLS_CC);
+ //efree(PHPDBG_G(lparam));
+ }
+
+ phpdbg_parse_param(
+ expr,
+ (cmd_len - expr_len) ? (((cmd_len - expr_len) - sizeof(" "))+1) : 0,
+ param TSRMLS_CC);
+
+ PHPDBG_G(lparam) = param;
+
+ if (command->subs && param->type == STR_PARAM) {
+ if (phpdbg_do_cmd(command->subs, selected, param->str, param->len TSRMLS_CC) == SUCCESS) {
+ rc = SUCCESS;
+ /* because we can */
+ phpdbg_clear_param(param TSRMLS_CC);
+ efree(param);
+ goto done;
+ }
+ }
+
+ *selected = (phpdbg_command_t*) command;
+
+ if (command->has_args == REQUIRED_ARG && param->type == EMPTY_PARAM) {
+ phpdbg_error("This command requires argument!");
+ rc = FAILURE;
+ } else if (command->has_args == NO_ARG && param->type != EMPTY_PARAM) {
+ phpdbg_error("This command does not expect argument!");
+ rc = FAILURE;
+ } else {
+ rc = command->handler(param TSRMLS_CC);
+ }
+ break;
+ }
+ ++command;
+ }
+
+done:
+ if (selected && param) {
+ phpdbg_debug(
+ "phpdbg_do_cmd(%s, \"%s\"): %d",
+ command->name, phpdbg_get_param_type(param TSRMLS_CC), (rc==SUCCESS));
+ }
+
+ return rc;
+} /* }}} */
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | 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 <felipe@php.net> |
+ | Authors: Joe Watkins <joe.watkins@live.co.uk> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef PHPDBG_CMD_H
+#define PHPDBG_CMD_H
+
+#include "TSRM.h"
+
+typedef struct _phpdbg_command_t phpdbg_command_t;
+
+/* {{{ Command and Parameter */
+enum {
+ NO_ARG = 0,
+ REQUIRED_ARG,
+ OPTIONAL_ARG
+};
+
+typedef enum {
+ EMPTY_PARAM = 0,
+ ADDR_PARAM,
+ FILE_PARAM,
+ METHOD_PARAM,
+ STR_PARAM,
+ NUMERIC_PARAM
+} phpdbg_param_type;
+
+typedef struct _phpdbg_param {
+ phpdbg_param_type type;
+ long num;
+ zend_ulong addr;
+ struct {
+ char *name;
+ long line;
+ } file;
+ struct {
+ char *class;
+ char *name;
+ } method;
+ char *str;
+ size_t len;
+} phpdbg_param_t;
+
+typedef int (*phpdbg_command_handler_t)(phpdbg_param_t *param TSRMLS_DC);
+
+struct _phpdbg_command_t {
+ const char *name; /* Command name */
+ size_t name_len; /* Command name length */
+ const char *tip; /* Menu tip */
+ size_t tip_len; /* Menu tip length */
+ char alias; /* Alias */
+ phpdbg_command_handler_t handler; /* Command handler */
+ const phpdbg_command_t *subs; /* Sub Commands */
+ char has_args; /* Accept args? */
+};
+/* }}} */
+
+#define PHPDBG_STRL(s) s, sizeof(s)-1
+
+/**
+ * Command Executor
+ */
+int phpdbg_do_cmd(const phpdbg_command_t*, phpdbg_command_t**, char *, size_t TSRMLS_DC);
+phpdbg_param_type phpdbg_parse_param(const char*, size_t, phpdbg_param_t* TSRMLS_DC);
+void phpdbg_clear_param(phpdbg_param_t * TSRMLS_DC);
+const char* phpdbg_get_param_type(const phpdbg_param_t *param TSRMLS_DC);
+
+/**
+ * Command Declarators
+ */
+#define PHPDBG_COMMAND_HANDLER(name) phpdbg_do_##name
+
+#define PHPDBG_COMMAND_D_EX(name, tip, alias, handler, children, has_args) \
+ {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##handler, children, has_args}
+
+#define PHPDBG_COMMAND_D(name, tip, alias, children, has_args) \
+ {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, children, has_args}
+
+#define PHPDBG_COMMAND(name) int phpdbg_do_##name(phpdbg_param_t *param TSRMLS_DC)
+
+#define PHPDBG_END_COMMAND {NULL, 0, NULL, 0, '\0', NULL, NULL, '\0'}
+
+#define phpdbg_default_switch_case() \
+ default:\
+ phpdbg_error(\
+ "Unsupported parameter type (%s) for command", \
+ phpdbg_get_param_type(param TSRMLS_CC)); \
+ break
+
+#endif /* PHPDBG_CMD_H */
#define PHPDBG_HELP_H
#include "TSRM.h"
-#include "phpdbg_prompt.h"
+#include "phpdbg.h"
+#include "phpdbg_cmd.h"
-/**
- * Command Declarators
- */
-#define PHPDBG_HELP_D(name, tip, alias) \
- {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_help_##name, NULL}
-#define PHPDBG_HELP(name) \
- int phpdbg_do_help_##name(phpdbg_param_t *param TSRMLS_DC)
+#define PHPDBG_HELP(name) PHPDBG_COMMAND(help_##name)
/**
* Helper Forward Declarations
* Commands
*/
static const phpdbg_command_t phpdbg_help_commands[] = {
- PHPDBG_HELP_D(exec, "the execution context should be a valid path", 'e'),
- PHPDBG_HELP_D(compile, "pre-compilation allows inspection of code before execution", 'c'),
- PHPDBG_HELP_D(step, "stepping through execution allows inspection of the opline as it is executed", 's'),
- PHPDBG_HELP_D(next, "continue executing while stepping or after breaking", 'n'),
- PHPDBG_HELP_D(run, "execution inside the phpdbg vm allows detailed inspection and debugging", 'r'),
- PHPDBG_HELP_D(eval, "access to eval() allows you to affect the environment during execution", 'E'),
- PHPDBG_HELP_D(until, "continue until the program reaches a source line different than the current one", 'u'),
- PHPDBG_HELP_D(finish, "continue until the current function has returned", 'f'),
- PHPDBG_HELP_D(leave, "continue until the current function is returning", 'L'),
- PHPDBG_HELP_D(print, "printing allows inspection of the execution environment", 'p'),
- PHPDBG_HELP_D(break, "breakpoints allow execution interruption", 'b'),
- PHPDBG_HELP_D(clean, "resetting the environment is useful while debugging and recompiling", 'X'),
- PHPDBG_HELP_D(clear, "clearing breakpoints allows you to run code without interruption", 'c'),
- PHPDBG_HELP_D(info, "quick access to useful information on the console", 'i'),
- PHPDBG_HELP_D(back, "show debug backtrace information during execution", 't'),
- PHPDBG_HELP_D(quiet, "be quiet during execution", 's'),
- PHPDBG_HELP_D(list, "listing code gives you quick access to code while executing", 'l'),
- PHPDBG_HELP_D(oplog, "keep clutter off the screen by sending oplogs to a file", 'O'),
- {NULL, 0, 0}
+ PHPDBG_COMMAND_D_EX(exec, "the execution context should be a valid path", 'e', help_exec, NULL, 0),
+ PHPDBG_COMMAND_D_EX(compile, "pre-compilation allows inspection of code before execution", 'c', help_compile, NULL, 0),
+ PHPDBG_COMMAND_D_EX(step, "stepping through execution allows inspection of the opline as it is executed", 's', help_step, NULL, 0),
+ PHPDBG_COMMAND_D_EX(next, "continue executing while stepping or after breaking", 'n', help_next, NULL, 0),
+ PHPDBG_COMMAND_D_EX(run, "execution inside the phpdbg vm allows detailed inspection and debugging", 'r', help_run, NULL, 0),
+ PHPDBG_COMMAND_D_EX(eval, "access to eval() allows you to affect the environment during execution", 'E', help_eval, NULL, 0),
+ PHPDBG_COMMAND_D_EX(until, "continue until the program reaches a source line different than the current one", 'u', help_until, NULL, 0),
+ PHPDBG_COMMAND_D_EX(finish, "continue until the current function has returned", 'f', help_finish, NULL, 0),
+ PHPDBG_COMMAND_D_EX(leave, "continue until the current function is returning", 'L', help_leave, NULL, 0),
+ PHPDBG_COMMAND_D_EX(print, "printing allows inspection of the execution environment", 'p', help_print, NULL, 0),
+ PHPDBG_COMMAND_D_EX(break, "breakpoints allow execution interruption", 'b', help_break, NULL, 0),
+ PHPDBG_COMMAND_D_EX(clean, "resetting the environment is useful while debugging and recompiling", 'X', help_clean, NULL, 0),
+ PHPDBG_COMMAND_D_EX(clear, "clearing breakpoints allows you to run code 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(quiet, "be quiet during execution", 's', help_quiet, NULL, 0),
+ PHPDBG_COMMAND_D_EX(list, "listing code gives you quick access to code while executing", 'l', help_list, NULL, 0),
+ PHPDBG_COMMAND_D_EX(oplog, "keep clutter off the screen by sending oplogs to a file", 'O', help_oplog, NULL, 0),
+ PHPDBG_END_COMMAND
};
#define phpdbg_help_header() \
phpdbg_write("|-------- ");
phpdbg_print_class_name(&pce TSRMLS_CC);
phpdbg_writeln(EMPTY);
- } while(pce = pce->parent);
+ } while ((pce = pce->parent));
}
if ((*ce)->info.user.filename) {
#ifndef PHPDBG_INFO_H
#define PHPDBG_INFO_H
-#include "TSRM.h"
-#include "phpdbg.h"
-#include "phpdbg_prompt.h"
-#include "phpdbg_utils.h"
+#include "phpdbg_cmd.h"
-/**
- * Command Declarators
- */
-#define PHPDBG_INFO_HANDLER(name) phpdbg_do_info_##name
-#define PHPDBG_INFO_D(name, tip) \
- {PHPDBG_STRL(#name), tip, sizeof(tip)-1, 0, PHPDBG_INFO_HANDLER(name), NULL}
-#define PHPDBG_INFO_EX_D(name, tip, alias) \
- {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, PHPDBG_INFO_HANDLER(name), NULL}
-#define PHPDBG_INFO(name) \
- int PHPDBG_INFO_HANDLER(name)(phpdbg_param_t *param TSRMLS_DC)
+#define PHPDBG_INFO(name) PHPDBG_COMMAND(info_##name)
PHPDBG_INFO(files);
PHPDBG_INFO(classes);
PHPDBG_INFO(vars);
static const phpdbg_command_t phpdbg_info_commands[] = {
- PHPDBG_INFO_EX_D(files, "lists included files", 'F'),
- PHPDBG_INFO_EX_D(classes, "lists loaded classes", 'c'),
- PHPDBG_INFO_EX_D(funcs, "lists loaded classes", 'f'),
- PHPDBG_INFO_EX_D(error, "show the last error", 'e'),
- PHPDBG_INFO_EX_D(vars, "show active variables", 'v'),
- PHPDBG_END_COMAND
+ PHPDBG_COMMAND_D_EX(files, "lists included files", 'F', info_files, NULL, 0),
+ PHPDBG_COMMAND_D_EX(classes, "lists loaded classes", 'c', info_classes, NULL, 0),
+ PHPDBG_COMMAND_D_EX(funcs, "lists loaded classes", 'f', info_funcs, NULL, 0),
+ PHPDBG_COMMAND_D_EX(error, "show the last error", 'e', info_error, NULL, 0),
+ PHPDBG_COMMAND_D_EX(vars, "show active variables", 'v', info_vars, NULL, 0),
+ PHPDBG_END_COMMAND
};
#endif /* PHPDBG_INFO_H */
#define PHPDBG_LIST_H
#include "TSRM.h"
-#include "phpdbg_prompt.h"
-#include "phpdbg_utils.h"
-
-/**
- * Command Declarators
- */
-#define PHPDBG_LIST_HANDLER(name) phpdbg_do_list_##name
-#define PHPDBG_LIST_D(name, tip) \
- {PHPDBG_STRL(#name), tip, sizeof(tip)-1, 0, phpdbg_do_list_##name, NULL}
-#define PHPDBG_LIST_EX_D(name, tip, alias) \
- {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_list_##name, NULL}
-#define PHPDBG_LIST(name) \
- int PHPDBG_LIST_HANDLER(name)(phpdbg_param_t *param TSRMLS_DC)
+#include "phpdbg_cmd.h"
+#define PHPDBG_LIST(name) PHPDBG_COMMAND(list_##name)
+#define PHPDBG_LIST_HANDLER(name) PHPDBG_COMMAND_HANDLER(list_##name)
PHPDBG_LIST(lines);
PHPDBG_LIST(class);
void phpdbg_list_file(const char*, long, long, int TSRMLS_DC);
static const phpdbg_command_t phpdbg_list_commands[] = {
- PHPDBG_LIST_EX_D(lines, "lists the specified lines", 'l'),
- PHPDBG_LIST_EX_D(class, "lists the specified class", 'c'),
- PHPDBG_LIST_EX_D(method, "lists the specified method", 'm'),
- PHPDBG_LIST_EX_D(func, "lists the specified function", 'f'),
- PHPDBG_END_COMAND
+ PHPDBG_COMMAND_D_EX(lines, "lists the specified lines", 'l', list_lines, NULL, 1),
+ PHPDBG_COMMAND_D_EX(class, "lists the specified class", 'c', list_class, NULL, 1),
+ PHPDBG_COMMAND_D_EX(method, "lists the specified method", 'm', list_method, NULL, 1),
+ PHPDBG_COMMAND_D_EX(func, "lists the specified function", 'f', list_func, NULL, 1),
+ PHPDBG_END_COMMAND
};
#endif /* PHPDBG_LIST_H */
#include "phpdbg_print.h"
#include "phpdbg_utils.h"
#include "phpdbg_opcode.h"
+#include "phpdbg_prompt.h"
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
phpdbg_writeln(
"\t#%d-%d %s::%s() %s",
op_array->line_start, op_array->line_end,
- method->common.scope->name,
+ method->common.scope->name,
method->common.function_name,
op_array->filename ? op_array->filename : "unknown");
} else {
method->common.function_name ? method->common.function_name : "{main}",
op_array->filename ? op_array->filename : "unknown");
}
-
-
+
+
do {
const char *decode = phpdbg_decode_opcode(opline->opcode);
if (decode != NULL) {
phpdbg_writeln(
- "\t\t#%lu\t%p %s", opline->lineno, opline, decode);
+ "\t\t#%lu\t%p %s", opline->lineno, opline, decode);
} else phpdbg_error("\tFailed to decode opline @ %ld", opline);
-
+
opline++;
} while (++opcode < end);
}
} break;
-
+
default: {
if (method->common.scope) {
phpdbg_writeln(
if (!PHPDBG_G(ops)) {
phpdbg_compile(TSRMLS_C);
}
-
+
if (PHPDBG_G(ops)) {
phpdbg_notice(
"Context %s", PHPDBG_G(exec));
} else {
phpdbg_error("No execution context set");
}
-
+
return SUCCESS;
} /* }}} */
PHPDBG_PRINT(class) /* {{{ */
{
zend_class_entry **ce;
-
+
switch (param->type) {
case STR_PARAM: {
if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) {
phpdbg_notice(
- "%s %s: %s",
- ((*ce)->type == ZEND_USER_CLASS) ?
+ "%s %s: %s",
+ ((*ce)->type == ZEND_USER_CLASS) ?
"User" : "Internal",
- ((*ce)->ce_flags & ZEND_ACC_INTERFACE) ?
+ ((*ce)->ce_flags & ZEND_ACC_INTERFACE) ?
"Interface" :
((*ce)->ce_flags & ZEND_ACC_ABSTRACT) ?
"Abstract Class" :
- "Class",
+ "Class",
(*ce)->name);
-
+
phpdbg_writeln("Methods (%d):", zend_hash_num_elements(&(*ce)->function_table));
if (zend_hash_num_elements(&(*ce)->function_table)) {
HashPosition position;
zend_function *method;
-
+
for (zend_hash_internal_pointer_reset_ex(&(*ce)->function_table, &position);
zend_hash_get_current_data_ex(&(*ce)->function_table, (void**) &method, &position) == SUCCESS;
zend_hash_move_forward_ex(&(*ce)->function_table, &position)) {
"The class %s could not be found", param->str);
}
} break;
-
+
phpdbg_default_switch_case();
}
if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) {
phpdbg_notice(
- "%s Method %s",
- (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal",
+ "%s Method %s",
+ (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal",
fbc->common.function_name);
-
+
phpdbg_print_function_helper(fbc TSRMLS_CC);
} else {
phpdbg_error(
"The method %s could not be found", param->method.name);
}
-
+
efree(lcname);
} else {
phpdbg_error(
"The class %s could not be found", param->method.class);
}
} break;
-
+
phpdbg_default_switch_case();
}
-
+
return SUCCESS;
} /* }}} */
zend_function* fbc;
const char *func_name = param->str;
size_t func_name_len = param->len;
- char *lcname;
+ char *lcname;
/* search active scope if begins with period */
if (func_name[0] == '.') {
if (EG(scope)) {
} else {
func_table = EG(function_table);
}
-
+
lcname = zend_str_tolower_dup(func_name, func_name_len);
-
+
if (zend_hash_find(func_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) {
phpdbg_notice(
"%s %s %s",
- (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal",
+ (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal",
(fbc->common.scope) ? "Method" : "Function",
fbc->common.function_name);
-
+
phpdbg_print_function_helper(fbc TSRMLS_CC);
} else {
phpdbg_error(
"The function %s could not be found", func_name);
}
-
+
efree(lcname);
} break;
-
+
phpdbg_default_switch_case();
}
#ifndef PHPDBG_PRINT_H
#define PHPDBG_PRINT_H
-#include "TSRM.h"
-#include "phpdbg_prompt.h"
+#include "phpdbg_cmd.h"
-/**
- * Command Declarators
- */
-#define PHPDBG_PRINT_D(name, tip, alias) \
- {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_print_##name, NULL}
-#define PHPDBG_PRINT(name) \
- int phpdbg_do_print_##name(phpdbg_param_t *param TSRMLS_DC)
+#define PHPDBG_PRINT(name) PHPDBG_COMMAND(print_##name)
/**
* Printer Forward Declarations
* Commands
*/
static const phpdbg_command_t phpdbg_print_commands[] = {
- PHPDBG_PRINT_D(exec, "print execution context instructions", 'e'),
- PHPDBG_PRINT_D(opline, "print the current opline information", 'o'),
- PHPDBG_PRINT_D(class, "print out the instructions in the specified class", 'c'),
- PHPDBG_PRINT_D(method, "print out the instructions in the specified method", 'm'),
- PHPDBG_PRINT_D(func, "print out the instructions in the specified function", 'f'),
- PHPDBG_END_COMAND
+ PHPDBG_COMMAND_D_EX(exec, "print execution context instructions", 'e', print_exec, NULL, 0),
+ PHPDBG_COMMAND_D_EX(opline, "print the current opline information", 'o', print_opline, NULL, 0),
+ PHPDBG_COMMAND_D_EX(class, "print out the instructions in the specified class", 'c', print_class, NULL, 1),
+ PHPDBG_COMMAND_D_EX(method, "print out the instructions in the specified method", 'm', print_method, NULL, 1),
+ PHPDBG_COMMAND_D_EX(func, "print out the instructions in the specified function", 'f', print_func, NULL, 1),
+ PHPDBG_END_COMMAND
};
#endif /* PHPDBG_PRINT_H */
#include "phpdbg_opcode.h"
#include "phpdbg_list.h"
#include "phpdbg_utils.h"
+#include "phpdbg_prompt.h"
+#include "phpdbg_cmd.h"
/* {{{ forward declarations */
static PHPDBG_COMMAND(exec);
/* {{{ command declarations */
static const phpdbg_command_t phpdbg_prompt_commands[] = {
- PHPDBG_COMMAND_EX_D(exec, "set execution context", 'e'),
- PHPDBG_COMMAND_EX_D(compile, "attempt to pre-compile execution context", 'c'),
- PHPDBG_COMMAND_EX_D(step, "step through execution", 's'),
- PHPDBG_COMMAND_EX_D(next, "continue execution", 'n'),
- PHPDBG_COMMAND_EX_D(run, "attempt execution", 'r'),
- PHPDBG_COMMAND_EX_D(eval, "evaluate some code", 'E'),
- PHPDBG_COMMAND_EX_D(until, "continue until reaches next line", 'u'),
- PHPDBG_COMMAND_EX_D(finish, "continue past the end of the stack", 'f'),
- PHPDBG_COMMAND_EX_D(leave, "continue until the end of the stack", 'L'),
- PHPDBG_COMMANDS_D(print, "print something", 'p', phpdbg_print_commands),
- PHPDBG_COMMANDS_D(break, "set breakpoint", 'b', phpdbg_break_commands),
- PHPDBG_COMMAND_EX_D(back, "show trace", 't'),
- PHPDBG_COMMANDS_D(list, "lists some code", 'l', phpdbg_list_commands),
- PHPDBG_COMMANDS_D(info, "displays some informations", 'i', phpdbg_info_commands),
- PHPDBG_COMMAND_EX_D(clean, "clean the execution environment", 'X'),
- PHPDBG_COMMAND_EX_D(clear, "clear breakpoints", 'C'),
- PHPDBG_COMMANDS_D(help, "show help menu", 'h', phpdbg_help_commands),
- PHPDBG_COMMAND_EX_D(quiet, "silence some output", 'Q'),
- PHPDBG_COMMAND_EX_D(aliases, "show alias list", 'a'),
- PHPDBG_COMMAND_EX_D(oplog, "sets oplog output", 'O'),
- PHPDBG_COMMAND_EX_D(quit, "exit phpdbg", 'q'),
- PHPDBG_END_COMAND
+ PHPDBG_COMMAND_D(exec, "set execution context", 'e', NULL, 1),
+ PHPDBG_COMMAND_D(compile, "attempt to pre-compile execution context", 'c', NULL, 0),
+ PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, 1),
+ PHPDBG_COMMAND_D(next, "continue execution", 'n', NULL, 0),
+ PHPDBG_COMMAND_D(run, "attempt execution", 'r', NULL, 0),
+ PHPDBG_COMMAND_D(eval, "evaluate some code", 'E', NULL, 1),
+ PHPDBG_COMMAND_D(until, "continue until reaches next line", 'u', NULL, 0),
+ PHPDBG_COMMAND_D(finish, "continue past the end of the stack", 'f', NULL, 0),
+ PHPDBG_COMMAND_D(leave, "continue until the end of the stack", 'L', NULL, 0),
+ PHPDBG_COMMAND_D(print, "print something", 'p', phpdbg_print_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(list, "lists some code", 'l', phpdbg_list_commands, 2),
+ PHPDBG_COMMAND_D(info, "displays some informations", 'i', phpdbg_info_commands, 1),
+ PHPDBG_COMMAND_D(clean, "clean the execution environment", 'X', NULL, 0),
+ PHPDBG_COMMAND_D(clear, "clear breakpoints", 'C', NULL, 0),
+ PHPDBG_COMMAND_D(help, "show help menu", 'h', phpdbg_help_commands, 1),
+ PHPDBG_COMMAND_D(quiet, "silence some output", 'Q', NULL, 1),
+ PHPDBG_COMMAND_D(aliases, "show alias list", 'a', NULL, 0),
+ PHPDBG_COMMAND_D(oplog, "sets oplog output", 'O', NULL, 1),
+ PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0),
+ PHPDBG_END_COMMAND
}; /* }}} */
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
if (!EG(active_symbol_table)) {
zend_rebuild_symbol_table(TSRMLS_C);
}
-
+
zend_try {
/* last chance ... */
zend_activate_auto_globals(TSRMLS_C);
} zend_end_try();
-
+
zend_try {
zend_execute(
EG(active_op_array) TSRMLS_CC);
return SUCCESS;
} /* }}} */
-int phpdbg_do_cmd( const phpdbg_command_t *command,
- phpdbg_command_t **selected,
- char *cmd_line, size_t cmd_len TSRMLS_DC) /* {{{ */
-{
- int rc = FAILURE;
-
- char *expr = NULL;
-#ifndef _WIN32
- const char *cmd = strtok_r(cmd_line, " ", &expr);
-#else
- const char *cmd = strtok_s(cmd_line, " ", &expr);
-#endif
- size_t expr_len = (cmd != NULL) ? strlen(cmd) : 0;
-
- phpdbg_param_t *param = NULL;
-
- while (command && command->name && command->handler) {
- if ((command->name_len == expr_len && memcmp(cmd, command->name, expr_len) == 0)
- || (expr_len == 1 && command->alias && command->alias == cmd_line[0])) {
-
- param = emalloc(sizeof(phpdbg_param_t));
-
- PHPDBG_G(last) = (phpdbg_command_t*) command;
-
- /* urm ... */
- if (PHPDBG_G(lparam)) {
- //phpdbg_clear_param(
- // PHPDBG_G(lparam) TSRMLS_CC);
- //efree(PHPDBG_G(lparam));
- }
-
- phpdbg_parse_param(
- expr,
- (cmd_len - expr_len) ? (((cmd_len - expr_len) - sizeof(" "))+1) : 0,
- param TSRMLS_CC);
-
- PHPDBG_G(lparam) = param;
-
- if (command->subs && param->type == STR_PARAM) {
- if (phpdbg_do_cmd(command->subs, selected, param->str, param->len TSRMLS_CC) == SUCCESS) {
- rc = SUCCESS;
- /* because we can */
- phpdbg_clear_param(param TSRMLS_CC);
- efree(param);
- goto done;
- }
- }
-
- *selected = (phpdbg_command_t*) command;
-
- rc = command->handler(param TSRMLS_CC);
-
- break;
- }
- ++command;
- }
-
-done:
- if (selected && param) {
- phpdbg_debug(
- "phpdbg_do_cmd(%s, \"%s\"): %d",
- command->name, phpdbg_get_param_type(param TSRMLS_CC), (rc==SUCCESS));
- }
-
- return rc;
-} /* }}} */
-
int phpdbg_interactive(TSRMLS_D) /* {{{ */
{
size_t cmd_len;
*/
#define PHPDBG_MAX_CMD 500
-#define PHPDBG_STRL(s) s, sizeof(s)-1
-
-/**
- * Command Executor
- */
-int phpdbg_do_cmd(const phpdbg_command_t *command, phpdbg_command_t **selected, char *cmd_line, size_t cmd_len TSRMLS_DC);
-
-/**
- * Command Declarators
- */
-#define PHPDBG_COMMAND_D(name, tip) \
- {PHPDBG_STRL(#name), tip, sizeof(tip)-1, 0, phpdbg_do_##name, NULL}
-#define PHPDBG_COMMAND_EX_D(name, tip, alias) \
- {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, NULL}
-#define PHPDBG_COMMANDS_D(name, tip, alias, children) \
- {PHPDBG_STRL(#name), tip, sizeof(tip)-1, alias, phpdbg_do_##name, children}
-#define PHPDBG_COMMAND(name) \
- int phpdbg_do_##name(phpdbg_param_t *param TSRMLS_DC)
-
void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TSRMLS_DC);
void phpdbg_welcome(zend_bool cleaning TSRMLS_DC);
int phpdbg_interactive(TSRMLS_D);
void phpdbg_execute_ex(zend_op_array *op_array TSRMLS_DC);
#endif
-#define phpdbg_default_switch_case() \
- default:\
- phpdbg_error(\
- "Unsupported parameter type (%s) for command", \
- phpdbg_get_param_type(param TSRMLS_CC)); \
- break
-
#endif /* PHPDBG_PROMPT_H */