From c987e46b6fbebd02af25a3e60856e751ab9cc7f9 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 8 Dec 2013 16:07:49 -0200 Subject: [PATCH 01/12] - CS + ws --- phpdbg_prompt.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index c44db469bc1..d61dbf999ff 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -132,7 +132,8 @@ static inline int phpdbg_call_register(phpdbg_input_t *input TSRMLS_DC) /* {{{ * return FAILURE; } /* }}} */ -void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC) { +void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC) /* {{{ */ +{ struct stat sb; if (init_file && VCWD_STAT(init_file, &sb) != -1) { @@ -190,7 +191,7 @@ void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_ { phpdbg_input_t *input = phpdbg_read_input(cmd TSRMLS_CC); switch (phpdbg_do_cmd(phpdbg_prompt_commands, input TSRMLS_CC)) { - case FAILURE: + case FAILURE: if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { if (phpdbg_call_register(input TSRMLS_CC) == FAILURE) { phpdbg_error("Unrecognized command in %s:%d: %s!", init_file, line, input->string); @@ -244,7 +245,7 @@ void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TS if (i != -1) { scan_dir[i] = 0; } - + asprintf( &init_file, "%s/%s", scan_dir, PHPDBG_INIT_FILENAME); phpdbg_try_file_init(init_file, strlen(init_file), 1 TSRMLS_CC); @@ -838,7 +839,7 @@ PHPDBG_COMMAND(print) /* {{{ */ phpdbg_writeln("Functions\t%d", zend_hash_num_elements(EG(function_table))); phpdbg_writeln("Constants\t%d", zend_hash_num_elements(EG(zend_constants))); phpdbg_writeln("Included\t%d", zend_hash_num_elements(&EG(included_files))); - + phpdbg_writeln(SEPARATE); } break; @@ -923,7 +924,7 @@ PHPDBG_COMMAND(source) /* {{{ */ switch (param->type) { case STR_PARAM: { if (input->argc > 2) { - if (phpdbg_argv_is(1, "export")) { + if (phpdbg_argv_is(1, "export")) { FILE *h = VCWD_FOPEN(input->argv[2]->string, "w+"); if (h) { phpdbg_export_breakpoints(h TSRMLS_CC); @@ -1400,8 +1401,8 @@ zend_vm_enter: /* search for breakpoints */ { phpdbg_breakbase_t *brake; - - if ((PHPDBG_G(flags) & PHPDBG_BP_MASK) && + + if ((PHPDBG_G(flags) & PHPDBG_BP_MASK) && (brake = phpdbg_find_breakpoint(execute_data TSRMLS_CC))) { phpdbg_hit_breakpoint( brake, 1 TSRMLS_CC); From bae424dbb7e4aced9db13a1d605f56284d4ee558 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 8 Dec 2013 16:29:15 -0200 Subject: [PATCH 02/12] - Moved frame related code to phpdbg_frame.c --- config.m4 | 2 +- config.w32 | 2 +- phpdbg_frame.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++++ phpdbg_frame.h | 31 +++++++++ phpdbg_prompt.c | 145 ++--------------------------------------- 5 files changed, 205 insertions(+), 143 deletions(-) create mode 100644 phpdbg_frame.c create mode 100644 phpdbg_frame.h diff --git a/config.m4 b/config.m4 index 640b5ac5aea..274e6409d04 100644 --- a/config.m4 +++ b/config.m4 @@ -18,7 +18,7 @@ if test "$PHP_PHPDBG" != "no"; then fi PHP_PHPDBG_CFLAGS="-D_GNU_SOURCE" - 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 phpdbg_set.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 phpdbg_set.c phpdbg_frame.c" PHP_SUBST(PHP_PHPDBG_CFLAGS) PHP_SUBST(PHP_PHPDBG_FILES) diff --git a/config.w32 b/config.w32 index 25458d54f2c..29031507b31 100644 --- a/config.w32 +++ b/config.w32 @@ -1,7 +1,7 @@ ARG_ENABLE('phpdbg', 'Build phpdbg', 'yes'); ARG_ENABLE('phpdbgs', 'Build phpdbg shared', 'no'); -PHPDBG_SOURCES='phpdbg.c phpdbg_prompt.c phpdbg_cmd.c phpdbg_info.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_set.c'; +PHPDBG_SOURCES='phpdbg.c phpdbg_prompt.c phpdbg_cmd.c phpdbg_info.c phpdbg_help.c phpdbg_break.c phpdbg_print.c phpdbg_bp.c phpdbg_opcode.c phpdbg_list.c phpdbg_utils.c phpdbg_set.c phpdbg_frame.c'; PHPDBG_DLL='php' + PHP_VERSION + 'phpdbg.dll'; PHPDBG_EXE='phpdbg.exe'; diff --git a/phpdbg_frame.c b/phpdbg_frame.c new file mode 100644 index 00000000000..4d9c7dabc13 --- /dev/null +++ b/phpdbg_frame.c @@ -0,0 +1,168 @@ +/* + +----------------------------------------------------------------------+ + | 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 | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#include "zend.h" +#include "phpdbg.h" +#include "phpdbg_utils.h" +#include "phpdbg_frame.h" +#include "phpdbg_list.h" + +ZEND_EXTERN_MODULE_GLOBALS(phpdbg); + +void phpdbg_restore_frame(TSRMLS_D) /* {{{ */ +{ + if (PHPDBG_FRAME(num) == 0) { + return; + } + + PHPDBG_FRAME(num) = 0; + + /* move things back */ + EG(current_execute_data) = PHPDBG_FRAME(execute_data); + + EG(opline_ptr) = &PHPDBG_EX(opline); + EG(active_op_array) = PHPDBG_EX(op_array); + EG(return_value_ptr_ptr) = PHPDBG_EX(original_return_value); + EG(active_symbol_table) = PHPDBG_EX(symbol_table); + EG(This) = PHPDBG_EX(current_this); + EG(scope) = PHPDBG_EX(current_scope); + EG(called_scope) = PHPDBG_EX(current_called_scope); +} /* }}} */ + +void phpdbg_switch_frame(int frame TSRMLS_DC) /* {{{ */ +{ + zend_execute_data *execute_data = PHPDBG_FRAME(num)?PHPDBG_FRAME(execute_data):EG(current_execute_data); + int i = 0; + + if (PHPDBG_FRAME(num) == frame) { + phpdbg_notice("Already in frame #%d", frame); + return; + } + + while (execute_data) { + if (i++ == frame) { + break; + } + + do { + execute_data = execute_data->prev_execute_data; + } while (execute_data && execute_data->opline == NULL); + } + + if (execute_data == NULL) { + phpdbg_error("No frame #%d", frame); + return; + } + + phpdbg_restore_frame(TSRMLS_C); + + if (frame > 0) { + PHPDBG_FRAME(num) = frame; + + /* backup things and jump back */ + PHPDBG_FRAME(execute_data) = EG(current_execute_data); + EG(current_execute_data) = execute_data; + + EG(opline_ptr) = &PHPDBG_EX(opline); + EG(active_op_array) = PHPDBG_EX(op_array); + PHPDBG_FRAME(execute_data)->original_return_value = EG(return_value_ptr_ptr); + EG(return_value_ptr_ptr) = PHPDBG_EX(original_return_value); + EG(active_symbol_table) = PHPDBG_EX(symbol_table); + EG(This) = PHPDBG_EX(current_this); + EG(scope) = PHPDBG_EX(current_scope); + EG(called_scope) = PHPDBG_EX(current_called_scope); + } + + phpdbg_notice("Switched to frame #%d", frame); + phpdbg_list_file( + zend_get_executed_filename(TSRMLS_C), + 3, + zend_get_executed_lineno(TSRMLS_C)-1, + zend_get_executed_lineno(TSRMLS_C) + TSRMLS_CC + ); +} /* }}} */ + +void phpdbg_dump_backtrace(const phpdbg_param_t *param TSRMLS_DC) /* {{{ */ +{ + zval zbacktrace; + zval **tmp, **argstmp; + zval **file, **line, **funcname, **class, **type, **args; + HashPosition position; + int i = 0, limit = (param->type == NUMERIC_PARAM) ? param->num : 0; + char is_class; + + if (limit < 0) { + phpdbg_error("Invalid backtrace size %d", limit); + } + + zend_fetch_debug_backtrace( + &zbacktrace, 0, 0, limit TSRMLS_CC); + + zend_hash_internal_pointer_reset_ex(Z_ARRVAL(zbacktrace), &position); + zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), (void**)&tmp, &position); + while (1) { + zend_hash_find(Z_ARRVAL_PP(tmp), "file", sizeof("file"), (void **)&file); + zend_hash_find(Z_ARRVAL_PP(tmp), "line", sizeof("line"), (void **)&line); + zend_hash_move_forward_ex(Z_ARRVAL(zbacktrace), &position); + if (zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), (void**)&tmp, &position) == FAILURE) { + phpdbg_write( + "frame #%d: {main} at %s:%ld", + i, Z_STRVAL_PP(file), Z_LVAL_PP(line)); + break; + } + zend_hash_find(Z_ARRVAL_PP(tmp), "function", sizeof("function"), (void **)&funcname); + if ((is_class = zend_hash_find(Z_ARRVAL_PP(tmp), "object", sizeof("object"), (void **)&class)) == FAILURE) { + is_class = zend_hash_find(Z_ARRVAL_PP(tmp), "class", sizeof("class"), (void **)&class); + } else { + zend_get_object_classname(*class, (const char **)&Z_STRVAL_PP(class), (zend_uint *)&Z_STRLEN_PP(class) TSRMLS_CC); + } + if (is_class == SUCCESS) { + zend_hash_find(Z_ARRVAL_PP(tmp), "type", sizeof("type"), (void **)&type); + } + + phpdbg_write( + "frame #%d: %s%s%s(", + i++, + is_class == FAILURE?"":Z_STRVAL_PP(class), + is_class == FAILURE?"":Z_STRVAL_PP(type), + Z_STRVAL_PP(funcname) + ); + + if (zend_hash_find(Z_ARRVAL_PP(tmp), "args", sizeof("args"), (void **)&args) == SUCCESS) { + HashPosition iterator; + int j = 0; + + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(args), &iterator); + while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(args), (void **) &argstmp, &iterator) == SUCCESS) { + if (j++) { + phpdbg_write(", "); + } + zend_print_flat_zval_r(*argstmp TSRMLS_CC); + zend_hash_move_forward_ex(Z_ARRVAL_PP(args), &iterator); + } + } + + phpdbg_writeln(") at %s:%ld", Z_STRVAL_PP(file), Z_LVAL_PP(line)); + } + + phpdbg_writeln(EMPTY); + zval_dtor(&zbacktrace); +} /* }}} */ diff --git a/phpdbg_frame.h b/phpdbg_frame.h new file mode 100644 index 00000000000..ef6f04c403c --- /dev/null +++ b/phpdbg_frame.h @@ -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 | + | Authors: Bob Weinand | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHPDBG_FRAME_H +#define PHPDBG_FRAME_H + +#include "TSRM.h" +#include "phpdbg_cmd.h" + +void phpdbg_restore_frame(TSRMLS_D); +void phpdbg_switch_frame(int TSRMLS_DC); +void phpdbg_dump_backtrace(const phpdbg_param_t* TSRMLS_DC); + +#endif /* PHPDBG_FRAME_H */ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index d61dbf999ff..7e71b3842dd 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -34,6 +34,7 @@ #include "phpdbg_prompt.h" #include "phpdbg_cmd.h" #include "phpdbg_set.h" +#include "phpdbg_frame.h" /* {{{ command declarations */ const phpdbg_command_t phpdbg_prompt_commands[] = { @@ -472,80 +473,6 @@ PHPDBG_COMMAND(leave) /* {{{ */ return PHPDBG_LEAVE; } /* }}} */ -static inline void phpdbg_restore_frame(TSRMLS_D) /* {{{ */ -{ - if (PHPDBG_FRAME(num) == 0) { - return; - } - - PHPDBG_FRAME(num) = 0; - - /* move things back */ - EG(current_execute_data) = PHPDBG_FRAME(execute_data); - - EG(opline_ptr) = &PHPDBG_EX(opline); - EG(active_op_array) = PHPDBG_EX(op_array); - EG(return_value_ptr_ptr) = PHPDBG_EX(original_return_value); - EG(active_symbol_table) = PHPDBG_EX(symbol_table); - EG(This) = PHPDBG_EX(current_this); - EG(scope) = PHPDBG_EX(current_scope); - EG(called_scope) = PHPDBG_EX(current_called_scope); -} /* }}} */ - -static inline void phpdbg_switch_frame(int frame TSRMLS_DC) /* {{{ */ -{ - zend_execute_data *execute_data = PHPDBG_FRAME(num)?PHPDBG_FRAME(execute_data):EG(current_execute_data); - int i = 0; - - if (PHPDBG_FRAME(num) == frame) { - phpdbg_notice("Already in frame #%d", frame); - return; - } - - while (execute_data) { - if (i++ == frame) { - break; - } - - do { - execute_data = execute_data->prev_execute_data; - } while (execute_data && execute_data->opline == NULL); - } - - if (execute_data == NULL) { - phpdbg_error("No frame #%d", frame); - return; - } - - phpdbg_restore_frame(TSRMLS_C); - - if (frame > 0) { - PHPDBG_FRAME(num) = frame; - - /* backup things and jump back */ - PHPDBG_FRAME(execute_data) = EG(current_execute_data); - EG(current_execute_data) = execute_data; - - EG(opline_ptr) = &PHPDBG_EX(opline); - EG(active_op_array) = PHPDBG_EX(op_array); - PHPDBG_FRAME(execute_data)->original_return_value = EG(return_value_ptr_ptr); - EG(return_value_ptr_ptr) = PHPDBG_EX(original_return_value); - EG(active_symbol_table) = PHPDBG_EX(symbol_table); - EG(This) = PHPDBG_EX(current_this); - EG(scope) = PHPDBG_EX(current_scope); - EG(called_scope) = PHPDBG_EX(current_called_scope); - } - - phpdbg_notice("Switched to frame #%d", frame); - phpdbg_list_file( - zend_get_executed_filename(TSRMLS_C), - 3, - zend_get_executed_lineno(TSRMLS_C)-1, - zend_get_executed_lineno(TSRMLS_C) - TSRMLS_CC - ); -} /* }}} */ - PHPDBG_COMMAND(frame) /* {{{ */ { switch (param->type) { @@ -728,73 +655,9 @@ PHPDBG_COMMAND(back) /* {{{ */ switch (param->type) { case EMPTY_PARAM: - case NUMERIC_PARAM: { - zval zbacktrace; - zval **tmp, **argstmp; - HashPosition position; - int i = 0, - limit = (param->type == NUMERIC_PARAM) ? param->num : 0; - - zval **file, **line, **funcname, **class, **type, **args; - char is_class; - - if (limit < 0) { - phpdbg_error("Invalid backtrace size %d", limit); - } - - zend_fetch_debug_backtrace( - &zbacktrace, 0, 0, limit TSRMLS_CC); - - zend_hash_internal_pointer_reset_ex(Z_ARRVAL(zbacktrace), &position); - zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), (void**)&tmp, &position); - while (1) { - zend_hash_find(Z_ARRVAL_PP(tmp), "file", sizeof("file"), (void **)&file); - zend_hash_find(Z_ARRVAL_PP(tmp), "line", sizeof("line"), (void **)&line); - zend_hash_move_forward_ex(Z_ARRVAL(zbacktrace), &position); - if (zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), (void**)&tmp, &position) == FAILURE) { - phpdbg_write( - "frame #%d: {main} at %s:%ld", - i, Z_STRVAL_PP(file), Z_LVAL_PP(line)); - break; - } - zend_hash_find(Z_ARRVAL_PP(tmp), "function", sizeof("function"), (void **)&funcname); - if ((is_class = zend_hash_find(Z_ARRVAL_PP(tmp), "object", sizeof("object"), (void **)&class)) == FAILURE) { - is_class = zend_hash_find(Z_ARRVAL_PP(tmp), "class", sizeof("class"), (void **)&class); - } else { - zend_get_object_classname(*class, (const char **)&Z_STRVAL_PP(class), (zend_uint *)&Z_STRLEN_PP(class) TSRMLS_CC); - } - if (is_class == SUCCESS) { - zend_hash_find(Z_ARRVAL_PP(tmp), "type", sizeof("type"), (void **)&type); - } - - phpdbg_write( - "frame #%d: %s%s%s(", - i++, - is_class == FAILURE?"":Z_STRVAL_PP(class), - is_class == FAILURE?"":Z_STRVAL_PP(type), - Z_STRVAL_PP(funcname) - ); - - if (zend_hash_find(Z_ARRVAL_PP(tmp), "args", sizeof("args"), (void **)&args) == SUCCESS) { - HashPosition iterator; - int j = 0; - - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(args), &iterator); - while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(args), (void **) &argstmp, &iterator) == SUCCESS) { - if (j++) { - phpdbg_write(", "); - } - zend_print_flat_zval_r(*argstmp TSRMLS_CC); - zend_hash_move_forward_ex(Z_ARRVAL_PP(args), &iterator); - } - } - - phpdbg_writeln(") at %s:%ld", Z_STRVAL_PP(file), Z_LVAL_PP(line)); - } - - phpdbg_writeln(EMPTY); - zval_dtor(&zbacktrace); - } break; + case NUMERIC_PARAM: + phpdbg_dump_backtrace(TSRMLS_C); + break; phpdbg_default_switch_case(); } From 3ec948bca392612859667e4f619016c1477840c1 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 8 Dec 2013 16:30:52 -0200 Subject: [PATCH 03/12] - Fixed build --- phpdbg_prompt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index 7e71b3842dd..a6f3cf39c62 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -656,7 +656,7 @@ PHPDBG_COMMAND(back) /* {{{ */ switch (param->type) { case EMPTY_PARAM: case NUMERIC_PARAM: - phpdbg_dump_backtrace(TSRMLS_C); + phpdbg_dump_backtrace(param TSRMLS_CC); break; phpdbg_default_switch_case(); From e5a2d2efbd02004bb729aad6719ddbafde19207a Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 8 Dec 2013 16:33:19 -0200 Subject: [PATCH 04/12] - Change phpdbg_dump_backtrace prototype --- phpdbg_frame.c | 4 ++-- phpdbg_frame.h | 2 +- phpdbg_prompt.c | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/phpdbg_frame.c b/phpdbg_frame.c index 4d9c7dabc13..bbd7d340b79 100644 --- a/phpdbg_frame.c +++ b/phpdbg_frame.c @@ -100,13 +100,13 @@ void phpdbg_switch_frame(int frame TSRMLS_DC) /* {{{ */ ); } /* }}} */ -void phpdbg_dump_backtrace(const phpdbg_param_t *param TSRMLS_DC) /* {{{ */ +void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ { zval zbacktrace; zval **tmp, **argstmp; zval **file, **line, **funcname, **class, **type, **args; HashPosition position; - int i = 0, limit = (param->type == NUMERIC_PARAM) ? param->num : 0; + int i = 0, limit = num; char is_class; if (limit < 0) { diff --git a/phpdbg_frame.h b/phpdbg_frame.h index ef6f04c403c..4b874b0ee9b 100644 --- a/phpdbg_frame.h +++ b/phpdbg_frame.h @@ -26,6 +26,6 @@ void phpdbg_restore_frame(TSRMLS_D); void phpdbg_switch_frame(int TSRMLS_DC); -void phpdbg_dump_backtrace(const phpdbg_param_t* TSRMLS_DC); +void phpdbg_dump_backtrace(size_t TSRMLS_DC); #endif /* PHPDBG_FRAME_H */ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index a6f3cf39c62..da00ab16919 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -656,7 +656,8 @@ PHPDBG_COMMAND(back) /* {{{ */ switch (param->type) { case EMPTY_PARAM: case NUMERIC_PARAM: - phpdbg_dump_backtrace(param TSRMLS_CC); + phpdbg_dump_backtrace( + (param->type == NUMERIC_PARAM) ? param->num : 0 TSRMLS_CC); break; phpdbg_default_switch_case(); From 1fc10b5706422e4a59788040b7fbba497e5939a6 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 8 Dec 2013 16:47:53 -0200 Subject: [PATCH 05/12] - Splitting prototype dumping code --- phpdbg_frame.c | 91 +++++++++++++++++++++++++++++--------------------- phpdbg_frame.h | 1 - 2 files changed, 53 insertions(+), 39 deletions(-) diff --git a/phpdbg_frame.c b/phpdbg_frame.c index bbd7d340b79..c35a4f96f16 100644 --- a/phpdbg_frame.c +++ b/phpdbg_frame.c @@ -100,14 +100,58 @@ void phpdbg_switch_frame(int frame TSRMLS_DC) /* {{{ */ ); } /* }}} */ +static void phpdbg_dump_prototype(zval **tmp TSRMLS_DC) /* {{{ */ +{ + zval **funcname, **class, **type, **args, **argstmp; + char is_class; + + zend_hash_find(Z_ARRVAL_PP(tmp), "function", sizeof("function"), + (void **)&funcname); + + if ((is_class = zend_hash_find(Z_ARRVAL_PP(tmp), + "object", sizeof("object"), (void **)&class)) == FAILURE) { + is_class = zend_hash_find(Z_ARRVAL_PP(tmp), "class", sizeof("class"), + (void **)&class); + } else { + zend_get_object_classname(*class, (const char **)&Z_STRVAL_PP(class), + (zend_uint *)&Z_STRLEN_PP(class) TSRMLS_CC); + } + + if (is_class == SUCCESS) { + zend_hash_find(Z_ARRVAL_PP(tmp), "type", sizeof("type"), (void **)&type); + } + + phpdbg_write("%s%s%s(", + is_class == FAILURE?"":Z_STRVAL_PP(class), + is_class == FAILURE?"":Z_STRVAL_PP(type), + Z_STRVAL_PP(funcname) + ); + + if (zend_hash_find(Z_ARRVAL_PP(tmp), "args", sizeof("args"), + (void **)&args) == SUCCESS) { + HashPosition iterator; + int j = 0; + + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(args), &iterator); + while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(args), + (void **) &argstmp, &iterator) == SUCCESS) { + if (j++) { + phpdbg_write(", "); + } + zend_print_flat_zval_r(*argstmp TSRMLS_CC); + zend_hash_move_forward_ex(Z_ARRVAL_PP(args), &iterator); + } + } + phpdbg_write(")"); +} + void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ { zval zbacktrace; - zval **tmp, **argstmp; - zval **file, **line, **funcname, **class, **type, **args; + zval **tmp; + zval **file, **line; HashPosition position; int i = 0, limit = num; - char is_class; if (limit < 0) { phpdbg_error("Invalid backtrace size %d", limit); @@ -122,45 +166,16 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ zend_hash_find(Z_ARRVAL_PP(tmp), "file", sizeof("file"), (void **)&file); zend_hash_find(Z_ARRVAL_PP(tmp), "line", sizeof("line"), (void **)&line); zend_hash_move_forward_ex(Z_ARRVAL(zbacktrace), &position); + + phpdbg_write("frame #%d: ", i++); + if (zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), (void**)&tmp, &position) == FAILURE) { - phpdbg_write( - "frame #%d: {main} at %s:%ld", - i, Z_STRVAL_PP(file), Z_LVAL_PP(line)); + phpdbg_write("{main} at %s:%ld", Z_STRVAL_PP(file), Z_LVAL_PP(line)); break; } - zend_hash_find(Z_ARRVAL_PP(tmp), "function", sizeof("function"), (void **)&funcname); - if ((is_class = zend_hash_find(Z_ARRVAL_PP(tmp), "object", sizeof("object"), (void **)&class)) == FAILURE) { - is_class = zend_hash_find(Z_ARRVAL_PP(tmp), "class", sizeof("class"), (void **)&class); - } else { - zend_get_object_classname(*class, (const char **)&Z_STRVAL_PP(class), (zend_uint *)&Z_STRLEN_PP(class) TSRMLS_CC); - } - if (is_class == SUCCESS) { - zend_hash_find(Z_ARRVAL_PP(tmp), "type", sizeof("type"), (void **)&type); - } - phpdbg_write( - "frame #%d: %s%s%s(", - i++, - is_class == FAILURE?"":Z_STRVAL_PP(class), - is_class == FAILURE?"":Z_STRVAL_PP(type), - Z_STRVAL_PP(funcname) - ); - - if (zend_hash_find(Z_ARRVAL_PP(tmp), "args", sizeof("args"), (void **)&args) == SUCCESS) { - HashPosition iterator; - int j = 0; - - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(args), &iterator); - while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(args), (void **) &argstmp, &iterator) == SUCCESS) { - if (j++) { - phpdbg_write(", "); - } - zend_print_flat_zval_r(*argstmp TSRMLS_CC); - zend_hash_move_forward_ex(Z_ARRVAL_PP(args), &iterator); - } - } - - phpdbg_writeln(") at %s:%ld", Z_STRVAL_PP(file), Z_LVAL_PP(line)); + phpdbg_dump_prototype(tmp TSRMLS_CC); + phpdbg_writeln(" at %s:%ld", Z_STRVAL_PP(file), Z_LVAL_PP(line)); } phpdbg_writeln(EMPTY); diff --git a/phpdbg_frame.h b/phpdbg_frame.h index 4b874b0ee9b..fbccd5404f5 100644 --- a/phpdbg_frame.h +++ b/phpdbg_frame.h @@ -22,7 +22,6 @@ #define PHPDBG_FRAME_H #include "TSRM.h" -#include "phpdbg_cmd.h" void phpdbg_restore_frame(TSRMLS_D); void phpdbg_switch_frame(int TSRMLS_DC); From 508772840e6a5a11b29d314fb4134aac2a5120dd Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 8 Dec 2013 16:48:20 -0200 Subject: [PATCH 06/12] - CS --- phpdbg_frame.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phpdbg_frame.c b/phpdbg_frame.c index c35a4f96f16..1037265c05d 100644 --- a/phpdbg_frame.c +++ b/phpdbg_frame.c @@ -169,7 +169,8 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ phpdbg_write("frame #%d: ", i++); - if (zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), (void**)&tmp, &position) == FAILURE) { + if (zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), + (void**)&tmp, &position) == FAILURE) { phpdbg_write("{main} at %s:%ld", Z_STRVAL_PP(file), Z_LVAL_PP(line)); break; } From 50e8a47c901a262eee0ff88677730723ffdd9e25 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 8 Dec 2013 17:37:35 -0200 Subject: [PATCH 07/12] - Added argument name to backtrace dump --- phpdbg_frame.c | 10 +++++++++- phpdbg_utils.c | 39 +++++++++++++++++++++++++++++++++------ phpdbg_utils.h | 1 + 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/phpdbg_frame.c b/phpdbg_frame.c index 1037265c05d..1bc1f9ccead 100644 --- a/phpdbg_frame.c +++ b/phpdbg_frame.c @@ -130,11 +130,19 @@ static void phpdbg_dump_prototype(zval **tmp TSRMLS_DC) /* {{{ */ if (zend_hash_find(Z_ARRVAL_PP(tmp), "args", sizeof("args"), (void **)&args) == SUCCESS) { HashPosition iterator; - int j = 0; + const zend_function *func = phpdbg_get_function( + Z_STRVAL_PP(funcname), is_class == FAILURE ? NULL : Z_STRVAL_PP(class) TSRMLS_CC); + const zend_arg_info *arginfo = func ? func->common.arg_info : NULL; + int j = 0, m = func ? func->common.num_args : 0; zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(args), &iterator); while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(args), (void **) &argstmp, &iterator) == SUCCESS) { + + if (m && j < m) { + phpdbg_write("%s=", arginfo[j].name); + } + if (j++) { phpdbg_write(", "); } diff --git a/phpdbg_utils.c b/phpdbg_utils.c index 67e1cbc4643..f543af092ae 100644 --- a/phpdbg_utils.c +++ b/phpdbg_utils.c @@ -144,6 +144,33 @@ PHPDBG_API const char *phpdbg_current_file(TSRMLS_D) /* {{{ */ return file; } /* }}} */ +PHPDBG_API const zend_function *phpdbg_get_function(const char *fname, const char *cname TSRMLS_DC) /* {{{ */ +{ + zend_function *func = NULL; + size_t fname_len = strlen(fname); + char *lcname = zend_str_tolower_dup(fname, fname_len); + + if (cname) { + zend_class_entry **ce; + size_t cname_len = strlen(cname); + char *lc_cname = zend_str_tolower_dup(cname, cname_len); + int ret = zend_lookup_class(lc_cname, cname_len, &ce TSRMLS_CC); + + efree(lc_cname); + + if (ret == SUCCESS) { + zend_hash_find(&(*ce)->function_table, lcname, fname_len+1, + (void**)&func); + } + } else { + zend_hash_find(EG(function_table), lcname, fname_len+1, + (void**)&func); + } + + efree(lcname); + return func; +} /* }}} */ + PHPDBG_API char *phpdbg_trim(const char *str, size_t len, size_t *new_len) /* {{{ */ { const char *p = str; @@ -245,18 +272,18 @@ PHPDBG_API int phpdbg_print(int type TSRMLS_DC, FILE *fp, const char *format, .. PHPDBG_API int phpdbg_rlog(FILE *fp, const char *fmt, ...) { /* {{{ */ int rc = 0; - + va_list args; struct timeval tp; - + va_start(args, fmt); if (gettimeofday(&tp, NULL) == SUCCESS) { char friendly[100]; char *format = NULL, *buffer = NULL; - + strftime(friendly, 100, "%a %b %d %T.%%04d %Y", localtime(&tp.tv_sec)); asprintf( - &buffer, friendly, tp.tv_usec/1000); + &buffer, friendly, tp.tv_usec/1000); asprintf( &format, "[%s]: %s\n", buffer, fmt); rc = vfprintf( @@ -266,7 +293,7 @@ PHPDBG_API int phpdbg_rlog(FILE *fp, const char *fmt, ...) { /* {{{ */ free(buffer); } va_end(args); - + return rc; } /* }}} */ @@ -327,7 +354,7 @@ PHPDBG_API void phpdbg_set_prompt(const char *prompt TSRMLS_DC) /* {{{ */ } /* }}} */ PHPDBG_API const char *phpdbg_get_prompt(TSRMLS_D) /* {{{ */ -{ +{ /* find cached prompt */ if (PHPDBG_G(prompt)[1]) { return PHPDBG_G(prompt)[1]; diff --git a/phpdbg_utils.h b/phpdbg_utils.h index 3252f365574..3126d0c2cf6 100644 --- a/phpdbg_utils.h +++ b/phpdbg_utils.h @@ -30,6 +30,7 @@ PHPDBG_API int phpdbg_is_class_method(const char*, size_t, char**, char**); PHPDBG_API const char *phpdbg_current_file(TSRMLS_D); PHPDBG_API char *phpdbg_resolve_path(const char* TSRMLS_DC); PHPDBG_API char *phpdbg_trim(const char*, size_t, size_t*); +PHPDBG_API const zend_function *phpdbg_get_function(const char*, const char* TSRMLS_DC); /** * Error/notice/formatting helpers From b655a0bc7ef93b1bfc178033b334d1d3c23b6379 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 8 Dec 2013 17:52:14 -0200 Subject: [PATCH 08/12] - Fix argname printing order --- phpdbg_frame.c | 7 ++++--- test.php | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/phpdbg_frame.c b/phpdbg_frame.c index 1bc1f9ccead..88e2824ea91 100644 --- a/phpdbg_frame.c +++ b/phpdbg_frame.c @@ -139,13 +139,14 @@ static void phpdbg_dump_prototype(zval **tmp TSRMLS_DC) /* {{{ */ while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(args), (void **) &argstmp, &iterator) == SUCCESS) { + if (j) { + phpdbg_write(", "); + } if (m && j < m) { phpdbg_write("%s=", arginfo[j].name); } + ++j; - if (j++) { - phpdbg_write(", "); - } zend_print_flat_zval_r(*argstmp TSRMLS_CC); zend_hash_move_forward_ex(Z_ARRVAL_PP(args), &iterator); } diff --git a/test.php b/test.php index 8ced95e7a37..744ed798650 100644 --- a/test.php +++ b/test.php @@ -13,7 +13,7 @@ class phpdbg { } } -function test($x) { +function test($x, $y = 0) { $var = $x + 1; $var += 2; $var <<= 3; @@ -32,7 +32,7 @@ $dbg = new phpdbg(); var_dump( $dbg->isGreat("PHP Rocks !!")); -foreach (test(1) as $gen) +foreach (test(1,2) as $gen) continue; echo "it works!\n"; From cd3b070d7eb98119878bfe496d6d2c4748ed550b Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 8 Dec 2013 18:04:39 -0200 Subject: [PATCH 09/12] - Added variadic support to prototype dumping --- phpdbg_frame.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/phpdbg_frame.c b/phpdbg_frame.c index 88e2824ea91..5414242e3e8 100644 --- a/phpdbg_frame.c +++ b/phpdbg_frame.c @@ -134,22 +134,29 @@ static void phpdbg_dump_prototype(zval **tmp TSRMLS_DC) /* {{{ */ Z_STRVAL_PP(funcname), is_class == FAILURE ? NULL : Z_STRVAL_PP(class) TSRMLS_CC); const zend_arg_info *arginfo = func ? func->common.arg_info : NULL; int j = 0, m = func ? func->common.num_args : 0; + zend_bool is_variadic = 0; zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(args), &iterator); while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(args), (void **) &argstmp, &iterator) == SUCCESS) { - if (j) { phpdbg_write(", "); } if (m && j < m) { - phpdbg_write("%s=", arginfo[j].name); +#if PHP_VERSION_ID >= 50600 + is_variadic = arginfo[j].is_variadic; +#endif + phpdbg_write("%s=%s", + arginfo[j].name, is_variadic ? "[": ""); } ++j; zend_print_flat_zval_r(*argstmp TSRMLS_CC); zend_hash_move_forward_ex(Z_ARRVAL_PP(args), &iterator); } + if (is_variadic) { + phpdbg_write("]"); + } } phpdbg_write(")"); } From e3bf7ad5b5cfc630b97d1e51ea72cd52f2818dc9 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 8 Dec 2013 21:43:19 +0100 Subject: [PATCH 10/12] Renumbered frames in backtrace for internal functions --- phpdbg_frame.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/phpdbg_frame.c b/phpdbg_frame.c index 5414242e3e8..24aff59dd92 100644 --- a/phpdbg_frame.c +++ b/phpdbg_frame.c @@ -167,7 +167,8 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ zval **tmp; zval **file, **line; HashPosition position; - int i = 0, limit = num; + int i = 1, limit = num; + int user_defined; if (limit < 0) { phpdbg_error("Invalid backtrace size %d", limit); @@ -179,20 +180,25 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ zend_hash_internal_pointer_reset_ex(Z_ARRVAL(zbacktrace), &position); zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), (void**)&tmp, &position); while (1) { - zend_hash_find(Z_ARRVAL_PP(tmp), "file", sizeof("file"), (void **)&file); + user_defined = zend_hash_find(Z_ARRVAL_PP(tmp), "file", sizeof("file"), (void **)&file); zend_hash_find(Z_ARRVAL_PP(tmp), "line", sizeof("line"), (void **)&line); zend_hash_move_forward_ex(Z_ARRVAL(zbacktrace), &position); - phpdbg_write("frame #%d: ", i++); - if (zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), (void**)&tmp, &position) == FAILURE) { - phpdbg_write("{main} at %s:%ld", Z_STRVAL_PP(file), Z_LVAL_PP(line)); + phpdbg_write("frame #0: {main} at %s:%ld", Z_STRVAL_PP(file), Z_LVAL_PP(line)); break; } - phpdbg_dump_prototype(tmp TSRMLS_CC); - phpdbg_writeln(" at %s:%ld", Z_STRVAL_PP(file), Z_LVAL_PP(line)); + if (user_defined == SUCCESS) { + phpdbg_write("frame #%d: ", i++); + phpdbg_dump_prototype(tmp TSRMLS_CC); + phpdbg_writeln(" at %s:%ld", Z_STRVAL_PP(file), Z_LVAL_PP(line)); + } else { + phpdbg_write(" => "); + phpdbg_dump_prototype(tmp TSRMLS_CC); + phpdbg_writeln(" (internal function)"); + } } phpdbg_writeln(EMPTY); From 71ae30f1b8fc208f807cd8ffe0de457086cac7b5 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 8 Dec 2013 21:58:01 +0100 Subject: [PATCH 11/12] WS --- phpdbg.init.d | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpdbg.init.d b/phpdbg.init.d index cc18957b4cf..99a1ab328b8 100755 --- a/phpdbg.init.d +++ b/phpdbg.init.d @@ -3,7 +3,7 @@ # Author: krakjoe # # Purpose: Daemonize phpdbg automatically on boot # # chkconfig: 2345 07 09 # -# description:Starts, stops and restarts phpdbg daemon # +# description: Starts, stops and restarts phpdbg daemon # ################################################################ LOCKFILE=/var/lock/subsys/phpdbg PIDFILE=/var/run/phpdbg.pid @@ -16,7 +16,7 @@ if [ "x${PHPDBG}" == "x" ]; then PHPDBG=$(which phpdbg 2>/dev/null) fi ################################################################ -# Options to pass to phpdbg upon boot # +# Options to pass to phpdbg upon boot # ################################################################ OPTIONS= LOGFILE=/var/log/phpdbg.log From b35f6ee7234af7a4872b434875de8d761b09ebe9 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Sun, 8 Dec 2013 22:11:50 +0100 Subject: [PATCH 12/12] Pssst, compiler! --- phpdbg_bp.c | 4 ++-- phpdbg_cmd.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/phpdbg_bp.c b/phpdbg_bp.c index 3c0f1985267..50580a5f5f1 100644 --- a/phpdbg_bp.c +++ b/phpdbg_bp.c @@ -601,7 +601,7 @@ static inline zend_bool phpdbg_find_breakpoint_param(phpdbg_param_t *param, zend } break; case FILE_PARAM: { - if ((param->file.line == zend_get_executed_lineno(TSRMLS_C))) { + if (param->file.line == zend_get_executed_lineno(TSRMLS_C)) { const char *str = zend_get_executed_filename(TSRMLS_C); size_t lengths[2] = {strlen(param->file.name), strlen(str)}; @@ -640,7 +640,7 @@ static inline zend_bool phpdbg_find_breakpoint_param(phpdbg_param_t *param, zend } break; case ADDR_PARAM: { - return ((phpdbg_opline_ptr_t)execute_data->opline == param->addr); + return ((zend_ulong)(phpdbg_opline_ptr_t)execute_data->opline == param->addr); } break; case NUMERIC_PARAM: diff --git a/phpdbg_cmd.c b/phpdbg_cmd.c index 543c01c6f0f..d48624aa75f 100644 --- a/phpdbg_cmd.c +++ b/phpdbg_cmd.c @@ -147,7 +147,7 @@ PHPDBG_API char* phpdbg_param_tostring(const phpdbg_param_t *param, char **point case FILE_PARAM: asprintf(pointer, - "%s:%u", + "%s:%lu", param->file.name, param->file.line); break;