From 488dd317feacd0ea3a9419e80eb8183ff2879c91 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Wed, 11 Dec 2013 21:27:03 +0100 Subject: [PATCH] First non-working test of segfault handlers --- config.m4 | 2 +- config.w32 | 2 +- phpdbg.c | 49 +++++++++++++++++++++++++++++++++++++++++++------ phpdbg.h | 13 +++++++++++++ phpdbg_prompt.c | 14 ++++++++++++++ phpdbg_prompt.h | 3 ++- 6 files changed, 74 insertions(+), 9 deletions(-) diff --git a/config.m4 b/config.m4 index 274e6409d0..3016a2075d 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 phpdbg_frame.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 phpdbg_watch.c" PHP_SUBST(PHP_PHPDBG_CFLAGS) PHP_SUBST(PHP_PHPDBG_FILES) diff --git a/config.w32 b/config.w32 index 29031507b3..d97873ec85 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_frame.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_watch.c'; PHPDBG_DLL='php' + PHP_VERSION + 'phpdbg.dll'; PHPDBG_EXE='phpdbg.exe'; diff --git a/phpdbg.c b/phpdbg.c index 7a5cd48e43..d72133b218 100644 --- a/phpdbg.c +++ b/phpdbg.c @@ -765,6 +765,26 @@ int phpdbg_open_sockets(char *address, int port[2], int (*listen)[2], int (*sock } /* }}} */ #endif +void phpdbg_signal_handler(int sig, siginfo_t *info, void *context) { + int is_handled = FAILURE; + TSRMLS_FETCH(); + + switch (sig) { + case SIGBUS: + case SIGSEGV: + is_handled = phpdbg_watchpoint_segfault_handler(info, context TSRMLS_CC); + if (is_handled == FAILURE) { +#ifdef ZEND_SIGNALS + zend_sigaction(sig, &PHPDBG_G(old_sigsegv_signal), NULL TSRMLS_CC); +#else + sigaction(sig, &PHPDBG_G(old_sigsegv_signal), NULL); +#endif + } + break; + } + +} + int main(int argc, char **argv) /* {{{ */ { sapi_module_struct *phpdbg = &phpdbg_sapi_module; @@ -802,6 +822,10 @@ int main(int argc, char **argv) /* {{{ */ void ***tsrm_ls; #endif + struct sigaction signal_struct; + signal_struct.sa_sigaction = phpdbg_signal_handler; + signal_struct.sa_flags = SA_SIGINFO | SA_NODEFER; + #ifndef _WIN32 address = strdup("127.0.0.1"); socket[0] = -1; @@ -825,7 +849,9 @@ int main(int argc, char **argv) /* {{{ */ tsrm_startup(1, 1, 0, NULL); tsrm_ls = ts_resource(0); -#endif +#endif + + phpdbg_setup_watchpoints(); phpdbg_main: if (!cleaning) { @@ -1061,17 +1087,28 @@ phpdbg_main: if (phpdbg->startup(phpdbg) == SUCCESS) { zend_activate(TSRMLS_C); - + +#ifdef ZEND_SIGNALS + zend_try { + zend_signal_activate(TSRMLS_C); + } zend_end_try(); +#endif + +#ifdef ZEND_SIGNALS + zend_try { zend_sigaction(SIGSEGV, &signal_struct, &PHPDBG_G(old_sigsegv_signal) TSRMLS_CC); } zend_end_try(); + zend_try { zend_sigaction(SIGBUS, &signal_struct, &PHPDBG_G(old_sigsegv_signal) TSRMLS_CC); } zend_end_try(); +#else + sigaction(SIGSEGV, &signal_struct, &PHPDBG_G(old_sigsegv_signal)); + sigaction(SIGBUS, &signal_struct, &PHPDBG_G(old_sigsegv_signal)); +#endif + /* do not install sigint handlers for remote consoles */ /* sending SIGINT then provides a decent way of shutting down the server */ #ifdef ZEND_SIGNALS # ifndef _WIN32 if (listen[0] < 0) { # endif - zend_try { - zend_signal_activate(TSRMLS_C); - zend_signal(SIGINT, phpdbg_sigint_handler TSRMLS_CC); - } zend_end_try(); + zend_try { zend_signal(SIGINT, phpdbg_sigint_handler TSRMLS_CC); } zend_end_try(); # ifndef _WIN32 } # endif diff --git a/phpdbg.h b/phpdbg.h index 7d2b5b5e0c..906b894f26 100644 --- a/phpdbg.h +++ b/phpdbg.h @@ -38,6 +38,7 @@ #include "zend_globals.h" #include "zend_ini_scanner.h" #include "zend_stream.h" +#include "zend_signal.h" #include "SAPI.h" #include #include @@ -67,6 +68,7 @@ #include "phpdbg_cmd.h" #include "phpdbg_utils.h" +#include "phpdbg_watch.h" #ifdef ZTS # define PHPDBG_G(v) TSRMG(phpdbg_globals_id, zend_phpdbg_globals *, v) @@ -159,12 +161,23 @@ #define PHPDBG_IO_FDS 3 /* }}} */ /* {{{ structs */ +typedef union _phpdbg_btree phpdbg_btree; +union _phpdbg_btree { + phpdbg_btree *branches[2]; + phpdbg_watchpoint_t *watchpoint; +}; + ZEND_BEGIN_MODULE_GLOBALS(phpdbg) HashTable bp[PHPDBG_BREAK_TABLES]; /* break points */ HashTable registered; /* registered */ HashTable seek; /* seek oplines */ phpdbg_frame_t frame; /* frame */ + struct sigaction old_sigsegv_signal; /* segv signal handler */ + + phpdbg_btree *watchpoint_tree; /* tree with watchpoints */ + HashTable watchpoints; /* watchpoints */ + char *exec; /* file to execute */ size_t exec_len; /* size of exec */ zend_op_array *ops; /* op_array */ diff --git a/phpdbg_prompt.c b/phpdbg_prompt.c index c42b8d1efb..07b9f1400e 100644 --- a/phpdbg_prompt.c +++ b/phpdbg_prompt.c @@ -63,6 +63,7 @@ const phpdbg_command_t phpdbg_prompt_commands[] = { PHPDBG_COMMAND_D(source, "execute a phpdbginit", '.', NULL, 1), PHPDBG_COMMAND_D(shell, "shell a command", '-', NULL, 1), PHPDBG_COMMAND_D(quit, "exit phpdbg", 'q', NULL, 0), + PHPDBG_COMMAND_D(watch, "set watchpoint", 'w', NULL, 0), PHPDBG_END_COMMAND }; /* }}} */ @@ -1012,6 +1013,19 @@ PHPDBG_COMMAND(list) /* {{{ */ return SUCCESS; } /* }}} */ +PHPDBG_COMMAND(watch) /* {{{ */ +{ + switch (param->type) { + case STR_PARAM: + phpdbg_create_var_watchpoint(param->str, param->len TSRMLS_CC); + break; + + phpdbg_default_switch_case(); + } + + return SUCCESS; +} /* }}} */ + int phpdbg_interactive(TSRMLS_D) /* {{{ */ { int ret = SUCCESS; diff --git a/phpdbg_prompt.h b/phpdbg_prompt.h index 0bb2cc957f..523fa6ad3c 100644 --- a/phpdbg_prompt.h +++ b/phpdbg_prompt.h @@ -52,7 +52,8 @@ PHPDBG_COMMAND(shell); PHPDBG_COMMAND(set); PHPDBG_COMMAND(source); PHPDBG_COMMAND(register); -PHPDBG_COMMAND(quit); /* }}} */ +PHPDBG_COMMAND(quit); +PHPDBG_COMMAND(watch); /* }}} */ /* {{{ prompt commands */ extern const phpdbg_command_t phpdbg_prompt_commands[]; /* }}} */ -- 2.50.1