From: Felipe Pena Date: Tue, 12 Nov 2013 02:19:43 +0000 (-0200) Subject: - Added "list func" support X-Git-Tag: php-5.6.0alpha1~110^2~456^2~2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e32d511cecd3b39a756f63c68608ffeb24d35b1f;p=php - Added "list func" support --- diff --git a/config.m4 b/config.m4 index 1a99db0f24..df127084ae 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$abc_srcdir" - PHP_PHPDBG_FILES="phpdbg.c phpdbg_prompt.c phpdbg_help.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c" + PHP_PHPDBG_FILES="phpdbg.c phpdbg_prompt.c phpdbg_help.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c" PHP_SUBST(PHP_PHPDBG_CFLAGS) PHP_SUBST(PHP_PHPDBG_FILES) diff --git a/phpdbg_help.c b/phpdbg_help.c index 97a99fde69..eb5982648c 100644 --- a/phpdbg_help.c +++ b/phpdbg_help.c @@ -140,5 +140,7 @@ PHPDBG_HELP(list) /* {{{ */ printf("The list command displays N line from current context file.\n"); printf("\tphpdbg> list 2\n"); printf("Will print next 2 lines from the current file\n"); + printf("\tphpdbg> list func\n"); + printf("Will print func source code\n"); return SUCCESS; } /* }}} */ diff --git a/phpdbg_help.h b/phpdbg_help.h index 9e187a8b39..ba79747a5a 100644 --- a/phpdbg_help.h +++ b/phpdbg_help.h @@ -64,7 +64,7 @@ static const phpdbg_command_t phpdbg_help_commands[] = { PHPDBG_HELP_D(clear, "clearing breakpoints allows you to run code without interruption"), PHPDBG_HELP_D(back, "show debug backtrace information during execution"), PHPDBG_HELP_D(quiet, "be quiet during execution"), - PHPDBG_HELP_D(list, "list specified line"), + PHPDBG_HELP_D(list, "list specified line or function"), {NULL, 0, 0} }; diff --git a/phpdbg_list.c b/phpdbg_list.c index d460315531..d5e07d49df 100644 --- a/phpdbg_list.c +++ b/phpdbg_list.c @@ -73,3 +73,17 @@ void phpdbg_list_file(const char *filename, long count, long offset) /* {{{ */ out: close(fd); } /* }}} */ + +void phpdbg_list_function(const zend_function *fbc) /* {{{ */ +{ + const zend_op_array *ops; + + if (fbc->type != ZEND_USER_FUNCTION) { + return; + } + + ops = (zend_op_array*)fbc; + + phpdbg_list_file(ops->filename, + ops->line_end - ops->line_start + 1, ops->line_start); +} /* }}} */ diff --git a/phpdbg_list.h b/phpdbg_list.h index 4531a65d10..95cc06e93a 100644 --- a/phpdbg_list.h +++ b/phpdbg_list.h @@ -20,6 +20,9 @@ #ifndef PHPDBG_LIST_H #define PHPDBG_LIST_H +#include "zend_compile.h" + void phpdbg_list_file(const char*, long, long); +void phpdbg_list_function(const zend_function*); #endif /* PHPDBG_LIST_H */ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 9565ee61e8..65edb55f18 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -26,6 +26,7 @@ #include "phpdbg_bp.h" #include "phpdbg_opcode.h" #include "phpdbg_list.h" +#include "phpdbg_utils.h" static const phpdbg_command_t phpdbg_prompt_commands[]; @@ -103,7 +104,7 @@ static PHPDBG_COMMAND(step) /* {{{ */ } else { PHPDBG_G(flags) &= ~PHPDBG_IS_STEPPING; } - + printf( "[Stepping %s]\n", (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off"); return SUCCESS; @@ -151,20 +152,20 @@ static PHPDBG_COMMAND(run) /* {{{ */ static PHPDBG_COMMAND(eval) /* {{{ */ { zval retval; - + if (expr_len) { zend_bool stepping = (PHPDBG_G(flags) & PHPDBG_IS_STEPPING); - + /* disable stepping while eval() in progress */ PHPDBG_G(flags) &= ~ PHPDBG_IS_STEPPING; - + if (zend_eval_stringl((char*)expr, expr_len-1, &retval, "eval()'d code" TSRMLS_CC) == SUCCESS) { zend_print_zval_r( &retval, 0 TSRMLS_CC); printf("\n"); } - + /* switch stepping back on */ if (stepping) { PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; @@ -221,7 +222,7 @@ static PHPDBG_COMMAND(print) /* {{{ */ printf("Compiled\t%s\n", PHPDBG_G(ops) ? "yes" : "no"); printf("Stepping\t%s\n", (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off"); printf("Quietness\t%s\n", (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "on" : "off"); - + if (PHPDBG_G(ops)) { printf("Opcodes\t\t%d\n", PHPDBG_G(ops)->last); @@ -305,15 +306,15 @@ static PHPDBG_COMMAND(break) /* {{{ */ { char *line_pos = NULL; char *func_pos = NULL; - + if (!expr_len) { printf( "[No expression found]\n"); return FAILURE; } - + line_pos = strchr(expr, ':'); - + if (line_pos) { if (!(func_pos=strchr(line_pos+1, ':'))) { char path[MAXPATHLEN], resolved_name[MAXPATHLEN]; @@ -336,19 +337,19 @@ static PHPDBG_COMMAND(break) /* {{{ */ } else { char *class; char *func; - + size_t func_len = strlen(func_pos+1), class_len = (line_pos - expr); - + if (func_len) { class = emalloc(class_len+1); func = emalloc(func_len+1); - + memcpy(class, expr, class_len); class[class_len]='\0'; memcpy(func, func_pos+1, func_len); func[func_len]='\0'; - + phpdbg_set_breakpoint_method(class, class_len, func, func_len TSRMLS_CC); } else { printf("[No function found in method expression %s]\n", expr); @@ -437,7 +438,7 @@ static PHPDBG_COMMAND(clear) /* {{{ */ printf("[\tSymbols\t%d]\n", zend_hash_num_elements(&PHPDBG_G(bp_symbols))); printf("[\tOplines\t%d]\n", zend_hash_num_elements(&PHPDBG_G(bp_oplines))); printf("[\tMethods\t%d]\n", zend_hash_num_elements(&PHPDBG_G(bp_methods))); - + phpdbg_clear_breakpoints(TSRMLS_C); return SUCCESS; @@ -489,18 +490,32 @@ static PHPDBG_COMMAND(quiet) { /* {{{ */ static PHPDBG_COMMAND(list) /* {{{ */ { - long offset = 0, count = strtol(expr, NULL, 0); - const char *filename = PHPDBG_G(exec); - - if (zend_is_executing(TSRMLS_C)) { - filename = zend_get_executed_filename(TSRMLS_C); - offset = zend_get_executed_lineno(TSRMLS_C); - } else if (!filename) { - printf("[No file to list]\n"); - return SUCCESS; - } + if (phpdbg_is_numeric(expr)) { + long offset = 0, count = strtol(expr, NULL, 0); + const char *filename = PHPDBG_G(exec); + + if (zend_is_executing(TSRMLS_C)) { + filename = zend_get_executed_filename(TSRMLS_C); + offset = zend_get_executed_lineno(TSRMLS_C); + } else if (!filename) { + printf("[No file to list]\n"); + return SUCCESS; + } + + phpdbg_list_file(filename, count, offset); + } else { + zend_function* fbc; - phpdbg_list_file(filename, count, offset); + if (!EG(function_table)) { + printf("[No function table loaded]\n"); + return SUCCESS; + } + + if (zend_hash_find(EG(function_table), expr, strlen(expr)+1, + (void**)&fbc) == SUCCESS) { + phpdbg_list_function(fbc); + } + } return SUCCESS; } /* }}} */ @@ -573,7 +588,7 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */ } return PHPDBG_NEXT; } - + } } else if (PHPDBG_G(last)) { @@ -652,7 +667,7 @@ zend_vm_enter: } } } - + if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP) && phpdbg_find_breakpoint_opline(execute_data->opline TSRMLS_CC) == SUCCESS) { while (phpdbg_interactive(TSRMLS_C) != PHPDBG_NEXT) { diff --git a/phpdbg_utils.c b/phpdbg_utils.c new file mode 100644 index 0000000000..4b0c4a0216 --- /dev/null +++ b/phpdbg_utils.c @@ -0,0 +1,31 @@ +/* + +----------------------------------------------------------------------+ + | 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 +#include "phpdbg_utils.h" + +int phpdbg_is_numeric(const char *str) /* {{{ */ +{ + for (; *str; str++) { + if (isspace(*str)) { + continue; + } + return isdigit(*str); + } +} /* }}} */ diff --git a/phpdbg_utils.h b/phpdbg_utils.h new file mode 100644 index 0000000000..231a1b3f21 --- /dev/null +++ b/phpdbg_utils.h @@ -0,0 +1,25 @@ +/* + +----------------------------------------------------------------------+ + | 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_UTILS_H +#define PHPDBG_UTILS_H + +int phpdbg_is_numeric(const char *); + +#endif /* PHPDBG_UTILS_H */