summaryrefslogtreecommitdiff
path: root/sapi/phpdbg/phpdbg.c
diff options
context:
space:
mode:
Diffstat (limited to 'sapi/phpdbg/phpdbg.c')
-rw-r--r--sapi/phpdbg/phpdbg.c325
1 files changed, 171 insertions, 154 deletions
diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c
index 9b7993ddf0..1e0b214a23 100644
--- a/sapi/phpdbg/phpdbg.c
+++ b/sapi/phpdbg/phpdbg.c
@@ -18,10 +18,6 @@
+----------------------------------------------------------------------+
*/
-#if !defined(ZEND_SIGNALS) || defined(_WIN32)
-# include <signal.h>
-#endif
-
#include "phpdbg.h"
#include "phpdbg_prompt.h"
#include "phpdbg_bp.h"
@@ -75,72 +71,7 @@ PHP_INI_END()
static zend_bool phpdbg_booted = 0;
static zend_bool phpdbg_fully_started = 0;
-
-static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */
-{
- pg->prompt[0] = NULL;
- pg->prompt[1] = NULL;
-
- pg->colors[0] = NULL;
- pg->colors[1] = NULL;
- pg->colors[2] = NULL;
-
- pg->lines = phpdbg_get_terminal_height();
- pg->exec = NULL;
- pg->exec_len = 0;
- pg->buffer = NULL;
- pg->last_was_newline = 1;
- pg->ops = NULL;
- pg->vmret = 0;
- pg->in_execution = 0;
- pg->bp_count = 0;
- pg->flags = PHPDBG_DEFAULT_FLAGS;
- pg->oplog = NULL;
- memset(pg->io, 0, sizeof(pg->io));
- pg->frame.num = 0;
- pg->sapi_name_ptr = NULL;
- pg->socket_fd = -1;
- pg->socket_server_fd = -1;
- pg->unclean_eval = 0;
-
- pg->req_id = 0;
- pg->err_buf.active = 0;
- pg->err_buf.type = 0;
-
- pg->input_buflen = 0;
- pg->sigsafe_mem.mem = NULL;
- pg->sigsegv_bailout = NULL;
-
- pg->oplog_list = NULL;
-
-#ifdef PHP_WIN32
- pg->sigio_watcher_thread = INVALID_HANDLE_VALUE;
- memset(&pg->swd, 0, sizeof(struct win32_sigio_watcher_data));
-#endif
-
- pg->eol = PHPDBG_EOL_LF;
-} /* }}} */
-
-static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */
-{
- ZEND_INIT_MODULE_GLOBALS(phpdbg, php_phpdbg_globals_ctor, NULL);
- REGISTER_INI_ENTRIES();
-
- zend_execute_ex = phpdbg_execute_ex;
-
- REGISTER_STRINGL_CONSTANT("PHPDBG_VERSION", PHPDBG_VERSION, sizeof(PHPDBG_VERSION)-1, CONST_CS|CONST_PERSISTENT);
-
- REGISTER_LONG_CONSTANT("PHPDBG_FILE", FILE_PARAM, CONST_CS|CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PHPDBG_METHOD", METHOD_PARAM, CONST_CS|CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PHPDBG_LINENO", NUMERIC_PARAM, CONST_CS|CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PHPDBG_FUNC", STR_PARAM, CONST_CS|CONST_PERSISTENT);
-
- REGISTER_LONG_CONSTANT("PHPDBG_COLOR_PROMPT", PHPDBG_COLOR_PROMPT, CONST_CS|CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PHPDBG_COLOR_NOTICE", PHPDBG_COLOR_NOTICE, CONST_CS|CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("PHPDBG_COLOR_ERROR", PHPDBG_COLOR_ERROR, CONST_CS|CONST_PERSISTENT);
-
- return SUCCESS;
-} /* }}} */
+zend_bool use_mm_wrappers = 0;
static void php_phpdbg_destroy_bp_file(zval *brake) /* {{{ */
{
@@ -189,8 +120,62 @@ static void php_phpdbg_destroy_registered(zval *data) /* {{{ */
destroy_zend_function(function);
} /* }}} */
+static void php_phpdbg_destroy_file_source(zval *data) /* {{{ */
+{
+ phpdbg_file_source *source = (phpdbg_file_source *) Z_PTR_P(data);
+ destroy_op_array(&source->op_array);
+ if (source->buf) {
+ efree(source->buf);
+ }
+ efree(source);
+} /* }}} */
-static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */
+static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */
+{
+ pg->prompt[0] = NULL;
+ pg->prompt[1] = NULL;
+
+ pg->colors[0] = NULL;
+ pg->colors[1] = NULL;
+ pg->colors[2] = NULL;
+
+ pg->lines = phpdbg_get_terminal_height();
+ pg->exec = NULL;
+ pg->exec_len = 0;
+ pg->buffer = NULL;
+ pg->last_was_newline = 1;
+ pg->ops = NULL;
+ pg->vmret = 0;
+ pg->in_execution = 0;
+ pg->bp_count = 0;
+ pg->flags = PHPDBG_DEFAULT_FLAGS;
+ pg->oplog = NULL;
+ memset(pg->io, 0, sizeof(pg->io));
+ pg->frame.num = 0;
+ pg->sapi_name_ptr = NULL;
+ pg->socket_fd = -1;
+ pg->socket_server_fd = -1;
+ pg->unclean_eval = 0;
+
+ pg->req_id = 0;
+ pg->err_buf.active = 0;
+ pg->err_buf.type = 0;
+
+ pg->input_buflen = 0;
+ pg->sigsafe_mem.mem = NULL;
+ pg->sigsegv_bailout = NULL;
+
+ pg->oplog_list = NULL;
+
+#ifdef PHP_WIN32
+ pg->sigio_watcher_thread = INVALID_HANDLE_VALUE;
+ memset(&pg->swd, 0, sizeof(struct win32_sigio_watcher_data));
+#endif
+
+ pg->eol = PHPDBG_EOL_LF;
+} /* }}} */
+
+static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */
{
zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], 8, NULL, php_phpdbg_destroy_bp_file, 0);
zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], 8, NULL, php_phpdbg_destroy_bp_file, 0);
@@ -207,10 +192,28 @@ static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */
zend_hash_init(&PHPDBG_G(seek), 8, NULL, NULL, 0);
zend_hash_init(&PHPDBG_G(registered), 8, NULL, php_phpdbg_destroy_registered, 0);
+ zend_hash_init(&PHPDBG_G(file_sources), 0, NULL, php_phpdbg_destroy_file_source, 0);
+ phpdbg_setup_watchpoints();
+
+ REGISTER_INI_ENTRIES();
+
+ zend_execute_ex = phpdbg_execute_ex;
+
+ REGISTER_STRINGL_CONSTANT("PHPDBG_VERSION", PHPDBG_VERSION, sizeof(PHPDBG_VERSION)-1, CONST_CS|CONST_PERSISTENT);
+
+ REGISTER_LONG_CONSTANT("PHPDBG_FILE", FILE_PARAM, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("PHPDBG_METHOD", METHOD_PARAM, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("PHPDBG_LINENO", NUMERIC_PARAM, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("PHPDBG_FUNC", STR_PARAM, CONST_CS|CONST_PERSISTENT);
+
+ REGISTER_LONG_CONSTANT("PHPDBG_COLOR_PROMPT", PHPDBG_COLOR_PROMPT, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("PHPDBG_COLOR_NOTICE", PHPDBG_COLOR_NOTICE, CONST_CS|CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("PHPDBG_COLOR_ERROR", PHPDBG_COLOR_ERROR, CONST_CS|CONST_PERSISTENT);
+
return SUCCESS;
} /* }}} */
-static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
+static PHP_MSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
{
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE]);
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING]);
@@ -226,8 +229,17 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
zend_hash_destroy(&PHPDBG_G(file_sources));
zend_hash_destroy(&PHPDBG_G(seek));
zend_hash_destroy(&PHPDBG_G(registered));
- zend_hash_destroy(&PHPDBG_G(watchpoints));
- zend_llist_destroy(&PHPDBG_G(watchlist_mem));
+ phpdbg_destroy_watchpoints();
+
+ if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
+ phpdbg_notice("stop", "type=\"normal\"", "Script ended normally");
+ }
+
+ /* hack to restore mm_heap->use_custom_heap in order to receive memory leak info */
+ if (use_mm_wrappers) {
+ /* ASSUMING that mm_heap->use_custom_heap is the first element of the struct ... */
+ *(int *) zend_mm_get_heap() = 0;
+ }
if (PHPDBG_G(buffer)) {
free(PHPDBG_G(buffer));
@@ -262,6 +274,26 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
PHPDBG_G(oplog_list) = NULL;
}
+ fflush(stdout);
+ if (SG(request_info).argv0) {
+ free(SG(request_info).argv0);
+ SG(request_info).argv0 = NULL;
+ }
+
+ return SUCCESS;
+}
+/* }}} */
+
+static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */
+{
+ /* deactivate symbol table caching to have these properly destroyed upon stack leaving (especially important for watchpoints) */
+ EG(symtable_cache_limit) = EG(symtable_cache) - 1;
+
+ return SUCCESS;
+} /* }}} */
+
+static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
+{
return SUCCESS;
} /* }}} */
@@ -752,7 +784,7 @@ static zend_module_entry sapi_phpdbg_module_entry = {
PHPDBG_NAME,
phpdbg_user_functions,
PHP_MINIT(phpdbg),
- NULL,
+ PHP_MSHUTDOWN(phpdbg),
PHP_RINIT(phpdbg),
PHP_RSHUTDOWN(phpdbg),
NULL,
@@ -795,7 +827,7 @@ static void php_sapi_phpdbg_send_header(sapi_header_struct *sapi_header, void *s
}
/* }}} */
-static void php_sapi_phpdbg_log_message(char *message) /* {{{ */
+static void php_sapi_phpdbg_log_message(char *message, int syslog_type_int) /* {{{ */
{
/*
* We must not request TSRM before being booted
@@ -845,17 +877,15 @@ static void php_sapi_phpdbg_log_message(char *message) /* {{{ */
}
/* }}} */
-static int php_sapi_phpdbg_deactivate(void) /* {{{ */
+static int php_sapi_phpdbg_activate(void) /* {{{ */
{
- fflush(stdout);
- if (SG(request_info).argv0) {
- free(SG(request_info).argv0);
- SG(request_info).argv0 = NULL;
- }
+ return SUCCESS;
+}
+static int php_sapi_phpdbg_deactivate(void) /* {{{ */
+{
return SUCCESS;
}
-/* }}} */
static void php_sapi_phpdbg_register_vars(zval *track_vars_array) /* {{{ */
{
@@ -994,7 +1024,7 @@ static sapi_module_struct phpdbg_sapi_module = {
php_sapi_phpdbg_module_startup, /* startup */
php_module_shutdown_wrapper, /* shutdown */
- NULL, /* activate */
+ php_sapi_phpdbg_activate, /* activate */
php_sapi_phpdbg_deactivate, /* deactivate */
php_sapi_phpdbg_ub_write, /* unbuffered write */
@@ -1236,16 +1266,12 @@ void phpdbg_signal_handler(int sig, siginfo_t *info, void *context) /* {{{ */
switch (sig) {
case SIGBUS:
case SIGSEGV:
- if (PHPDBG_G(sigsegv_bailout)) {
- LONGJMP(*PHPDBG_G(sigsegv_bailout), FAILURE);
- }
is_handled = phpdbg_watchpoint_segfault_handler(info, context);
if (is_handled == FAILURE) {
-#ifdef ZEND_SIGNALS
+ if (PHPDBG_G(sigsegv_bailout)) {
+ LONGJMP(*PHPDBG_G(sigsegv_bailout), FAILURE);
+ }
zend_sigaction(sig, &PHPDBG_G(old_sigsegv_signal), NULL);
-#else
- sigaction(sig, &PHPDBG_G(old_sigsegv_signal), NULL);
-#endif
}
break;
}
@@ -1312,7 +1338,6 @@ int main(int argc, char **argv) /* {{{ */
FILE* stream = NULL;
char *print_opline_func;
zend_bool ext_stmt = 0;
- zend_bool use_mm_wrappers = 0;
zend_bool is_exit;
int exit_status;
@@ -1336,17 +1361,15 @@ int main(int argc, char **argv) /* {{{ */
setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */
#endif
+phpdbg_main:
#ifdef ZTS
tsrm_startup(1, 1, 0, NULL);
(void)ts_resource(0);
ZEND_TSRMLS_CACHE_UPDATE();
#endif
-#ifdef ZEND_SIGNALS
zend_signal_startup();
-#endif
-phpdbg_main:
ini_entries = NULL;
ini_entries_len = 0;
ini_ignore = 0;
@@ -1426,9 +1449,6 @@ phpdbg_main:
/* begin phpdbg options */
case 'S': { /* set SAPI name */
- if (sapi_name) {
- free(sapi_name);
- }
sapi_name = strdup(php_optarg);
} break;
@@ -1503,6 +1523,7 @@ phpdbg_main:
} break;
case 'h': {
+ ZEND_INIT_MODULE_GLOBALS(phpdbg, php_phpdbg_globals_ctor, NULL);
sapi_startup(phpdbg);
phpdbg->startup(phpdbg);
PHPDBG_G(flags) = 0;
@@ -1518,6 +1539,7 @@ phpdbg_main:
} break;
case 'V': {
+ ZEND_INIT_MODULE_GLOBALS(phpdbg, php_phpdbg_globals_ctor, NULL);
sapi_startup(phpdbg);
phpdbg->startup(phpdbg);
printf(
@@ -1594,6 +1616,20 @@ phpdbg_main:
phpdbg->ini_entries = ini_entries;
+ ZEND_INIT_MODULE_GLOBALS(phpdbg, php_phpdbg_globals_ctor, NULL);
+
+ if (settings > (zend_phpdbg_globals *) 0x2) {
+#ifdef ZTS
+ *((zend_phpdbg_globals *) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(phpdbg_globals_id)]) = *settings;
+#else
+ phpdbg_globals = *settings;
+#endif
+ free(settings);
+ }
+
+ /* set flags from command line */
+ PHPDBG_G(flags) = flags;
+
if (phpdbg->startup(phpdbg) == SUCCESS) {
zend_mm_heap *mm_heap;
#ifdef _WIN32
@@ -1604,17 +1640,9 @@ phpdbg_main:
void (*_free)(void*);
void* (*_realloc)(void*, size_t);
- /* set flags from command line */
- PHPDBG_G(flags) = flags;
-
- if (settings > (zend_phpdbg_globals *) 0x2) {
-#ifdef ZTS
- *((zend_phpdbg_globals *) (*((void ***) TSRMLS_CACHE))[TSRM_UNSHUFFLE_RSRC_ID(phpdbg_globals_id)]) = *settings;
-#else
- phpdbg_globals = *settings;
-#endif
- free(settings);
- }
+ zend_try {
+ zend_signal_activate();
+ } zend_end_try();
/* setup remote server if necessary */
if (cleaning <= 0 && listen > 0) {
@@ -1624,7 +1652,7 @@ phpdbg_main:
}
#ifndef _WIN32
- sigaction(SIGIO, &sigio_struct, NULL);
+ zend_sigaction(SIGIO, &sigio_struct, NULL);
#endif
/* set remote flag to stop service shutting down upon quit */
@@ -1632,7 +1660,7 @@ phpdbg_main:
#ifndef _WIN32
} else {
- signal(SIGHUP, phpdbg_sighup_handler);
+ zend_signal(SIGHUP, phpdbg_sighup_handler);
#endif
}
@@ -1641,8 +1669,6 @@ phpdbg_main:
use_mm_wrappers = !_malloc && !_realloc && !_free;
- phpdbg_init_list();
-
PHPDBG_G(original_free_function) = _free;
_free = phpdbg_watch_efree;
@@ -1656,21 +1682,8 @@ phpdbg_main:
zend_mm_set_custom_handlers(mm_heap, _malloc, _free, _realloc);
}
- phpdbg_setup_watchpoints();
-#if defined(ZEND_SIGNALS) && !defined(_WIN32)
- zend_try {
- zend_signal_activate();
- } zend_end_try();
-#endif
-
-#if defined(ZEND_SIGNALS) && !defined(_WIN32)
- zend_try { zend_sigaction(SIGSEGV, &signal_struct, &PHPDBG_G(old_sigsegv_signal)); } zend_end_try();
- zend_try { zend_sigaction(SIGBUS, &signal_struct, &PHPDBG_G(old_sigsegv_signal)); } zend_end_try();
-#elif !defined(_WIN32)
- sigaction(SIGSEGV, &signal_struct, &PHPDBG_G(old_sigsegv_signal));
- sigaction(SIGBUS, &signal_struct, &PHPDBG_G(old_sigsegv_signal));
-#endif
+ phpdbg_init_list();
PHPDBG_G(sapi_name_ptr) = sapi_name;
@@ -1708,24 +1721,24 @@ phpdbg_main:
return 1;
}
+#ifndef _WIN32
+ zend_try { zend_sigaction(SIGSEGV, &signal_struct, &PHPDBG_G(old_sigsegv_signal)); } zend_end_try();
+ zend_try { zend_sigaction(SIGBUS, &signal_struct, &PHPDBG_G(old_sigsegv_signal)); } zend_end_try();
+#endif
+
/* do not install sigint handlers for remote consoles */
/* sending SIGINT then provides a decent way of shutting down the server */
#ifndef _WIN32
if (listen < 0) {
#endif
-#if defined(ZEND_SIGNALS) && !defined(_WIN32)
zend_try { zend_signal(SIGINT, phpdbg_sigint_handler); } zend_end_try();
-#else
- signal(SIGINT, phpdbg_sigint_handler);
-#endif
#ifndef _WIN32
}
/* setup io here */
if (remote) {
PHPDBG_G(flags) |= PHPDBG_IS_REMOTE;
-
- signal(SIGPIPE, SIG_IGN);
+ zend_signal(SIGPIPE, SIG_IGN);
}
PHPDBG_G(io)[PHPDBG_STDIN].ptr = stdin;
PHPDBG_G(io)[PHPDBG_STDIN].fd = fileno(stdin);
@@ -1955,6 +1968,10 @@ phpdbg_out:
zend_objects_store_mark_destructed(&EG(objects_store));
}
+ zend_try {
+ php_request_shutdown(NULL);
+ } zend_end_try();
+
/* backup globals when cleaning */
if ((cleaning > 0 || remote) && !quit_immediately) {
settings = calloc(1, sizeof(zend_phpdbg_globals));
@@ -1982,41 +1999,50 @@ phpdbg_out:
}
}
- /* hack to restore mm_heap->use_custom_heap in order to receive memory leak info */
- if (use_mm_wrappers) {
- /* ASSUMING that mm_heap->use_custom_heap is the first element of the struct ... */
- *(int *) mm_heap = 0;
- }
- zend_try {
- php_request_shutdown(NULL);
- } zend_end_try();
-
if (exit_status == 0) {
exit_status = EG(exit_status);
}
+ php_output_deactivate();
+
if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
+ PHPDBG_G(flags) |= PHPDBG_IS_QUITTING;
if (PHPDBG_G(in_execution) || is_exit) {
if (!quit_immediately && !phpdbg_startup_run) {
- phpdbg_notice("stop", "type=\"normal\"", "Script ended normally");
+ PHPDBG_G(flags) -= PHPDBG_IS_QUITTING;
cleaning++;
}
}
}
- php_output_deactivate();
zend_try {
php_module_shutdown();
} zend_end_try();
#ifndef _WIN32
+ /* force override (no zend_signals) to prevent crashes due to signal recursion in SIGSEGV/SIGBUS handlers */
+ signal(SIGSEGV, SIG_DFL);
+ signal(SIGBUS, SIG_DFL);
+
/* reset it... else we risk a stack overflow upon next run (when clean'ing) */
php_stream_stdio_ops.write = PHPDBG_G(php_stdiop_write);
#endif
+ }
+
+ sapi_shutdown();
+
+#ifdef ZTS
+ ts_free_id(phpdbg_globals_id);
+#endif
- sapi_shutdown();
+ if (sapi_name) {
+ free(sapi_name);
}
+#ifdef ZTS
+ tsrm_shutdown();
+#endif
+
if ((cleaning > 0 || remote) && !quit_immediately) {
/* reset internal php_getopt state */
php_getopt(-1, argv, OPTIONS, NULL, &php_optind, 0, 0);
@@ -2024,21 +2050,12 @@ phpdbg_out:
goto phpdbg_main;
}
-#ifdef ZTS
- /* bugggy */
- /* tsrm_shutdown(); */
-#endif
-
#ifndef _WIN32
if (address) {
free(address);
}
#endif
- if (PHPDBG_G(sapi_name_ptr)) {
- free(PHPDBG_G(sapi_name_ptr));
- }
-
/* usually 0; just for -rr */
return exit_status;
} /* }}} */