com php-src: First non-working test of segfault handlers: config.m4 config.w32 phpdbg.c phpdbg.h phpdbg_prompt.c phpdbg_pro mpt.h
| From: | Bob Weinand | Date: | Wed, 11 Dec 2013 20:27:03 +0000 |
| Subject: | com php-src: First non-working test of segfault handlers: config.m4 config.w32 phpdbg.c phpdbg.h phpdbg_prompt.c phpdbg_pro mpt.h | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-77113@lists.php.net to get a copy of this message | ||
Commit: 488dd317feacd0ea3a9419e80eb8183ff2879c91
Author: Bob Weinand <bobwei9@hotmail.com> Wed, 11 Dec 2013 21:27:03 +0100
Parents: baceff6ad4bad3f13426be01db2971294dfe703f
Branches: PHP-5.6
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=488dd317feacd0ea3a9419e80eb8183ff2879c91
Log:
First non-working test of segfault handlers
Changed paths:
M config.m4
M config.w32
M phpdbg.c
M phpdbg.h
M phpdbg_prompt.c
M phpdbg_prompt.h
Diff:
diff --git a/config.m4 b/config.m4
index 274e640..3016a20 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 2903150..d97873e 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 7a5cd48..d72133b 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 7d2b5b5..906b894 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 <fcntl.h>
#include <sys/types.h>
@@ -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 c42b8d1..07b9f14 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 0bb2cc9..523fa6a 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[]; /* }}} */