diff options
author | Christoph M. Becker <cmbecker69@gmx.de> | 2020-05-25 19:12:24 +0200 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2020-05-26 17:45:25 +0200 |
commit | 8483a21f29fbfd8d86ddf2eb2b7db0ae0b462949 (patch) | |
tree | b802051897238ecb5deeaa6872a38ad1d2798b9e /sapi/phpdbg | |
parent | e483761a1e8ab058d9155688434c5fa9138f5ae1 (diff) | |
download | php-git-8483a21f29fbfd8d86ddf2eb2b7db0ae0b462949.tar.gz |
Fix several mostly Windows related phpdbg bugs
* Properly initialize PHPDBG_G(watch_tmp)
Otherwise that may cause segfaults in ZTS builds.
* Deactivate potentially remaining watchpoints after REPL
Otherwise the memory could still be protected, resulting in segfaults
during shutdown.
* NULL zend_handlers_table after freeing
As of commit 4130fe4[1], the `zend_handlers_table` is explicitly
freed in the `zend_vm_dtor()`. Since phpdbg (and maybe some other
SAPIs) may restart the engine afterwards, we have to make sure that
the table is also NULLed.
* Only set context option if there is a context
In other words, we must not follow the null pointer.
* Cater to file handles without attached console
File handles do not necessarily have an attached console (for
instance, pipes do not), in which case `GetConsoleScreenBufferInfo()`
fails. In this case we set a default value (`40`) for lines like on
other systems.
[1] <http://git.php.net/?p=php-src.git;a=commit;h=4130fe437a5db7ead1444d3748bd0fbad9829cb2>
Diffstat (limited to 'sapi/phpdbg')
-rw-r--r-- | sapi/phpdbg/phpdbg.c | 12 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_utils.c | 7 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_watch.c | 12 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_watch.h | 1 |
4 files changed, 26 insertions, 6 deletions
diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c index 8207e36540..0f1f03625c 100644 --- a/sapi/phpdbg/phpdbg.c +++ b/sapi/phpdbg/phpdbg.c @@ -1341,10 +1341,12 @@ php_stream *phpdbg_stream_url_wrap_php(php_stream_wrapper *wrapper, const char * if (!strncasecmp(path, "stdin", 6) && PHPDBG_G(stdin_file)) { php_stream *stream = php_stream_fopen_from_fd(dup(fileno(PHPDBG_G(stdin_file))), "r", NULL); #ifdef PHP_WIN32 - zval *blocking_pipes = php_stream_context_get_option(context, "pipe", "blocking"); - if (blocking_pipes) { - convert_to_long(blocking_pipes); - php_stream_set_option(stream, PHP_STREAM_OPTION_PIPE_BLOCKING, Z_LVAL_P(blocking_pipes), NULL); + if (context != NULL) { + zval *blocking_pipes = php_stream_context_get_option(context, "pipe", "blocking"); + if (blocking_pipes) { + convert_to_long(blocking_pipes); + php_stream_set_option(stream, PHP_STREAM_OPTION_PIPE_BLOCKING, Z_LVAL_P(blocking_pipes), NULL); + } } #endif return stream; @@ -2059,6 +2061,8 @@ phpdbg_out: phpdbg_out: #endif + phpdbg_purge_watchpoint_tree(); + if (first_command) { free(first_command); first_command = NULL; diff --git a/sapi/phpdbg/phpdbg_utils.c b/sapi/phpdbg/phpdbg_utils.c index 857b5e3311..dca70deb8f 100644 --- a/sapi/phpdbg/phpdbg_utils.c +++ b/sapi/phpdbg/phpdbg_utils.c @@ -357,8 +357,11 @@ PHPDBG_API int phpdbg_get_terminal_height(void) /* {{{ */ #ifdef _WIN32 CONSOLE_SCREEN_BUFFER_INFO csbi; - GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); - lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; + if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) { + lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1; + } else { + lines = 40; + } #elif defined(HAVE_SYS_IOCTL_H) && defined(TIOCGWINSZ) struct winsize w; diff --git a/sapi/phpdbg/phpdbg_watch.c b/sapi/phpdbg/phpdbg_watch.c index d9f9f8673f..317aa9666a 100644 --- a/sapi/phpdbg/phpdbg_watch.c +++ b/sapi/phpdbg/phpdbg_watch.c @@ -1406,6 +1406,8 @@ void phpdbg_setup_watchpoints(void) { zend_hash_init(PHPDBG_G(watchlist_mem), phpdbg_pagesize / (sizeof(Bucket) + sizeof(uint32_t)), NULL, NULL, 1); PHPDBG_G(watchlist_mem_backup) = malloc(phpdbg_pagesize > sizeof(HashTable) ? phpdbg_pagesize : sizeof(HashTable)); zend_hash_init(PHPDBG_G(watchlist_mem_backup), phpdbg_pagesize / (sizeof(Bucket) + sizeof(uint32_t)), NULL, NULL, 1); + + PHPDBG_G(watch_tmp) = NULL; } void phpdbg_destroy_watchpoints(void) { @@ -1433,3 +1435,13 @@ void phpdbg_destroy_watchpoints(void) { zend_hash_destroy(PHPDBG_G(watchlist_mem_backup)); free(PHPDBG_G(watchlist_mem_backup)); } + +void phpdbg_purge_watchpoint_tree(void) { + phpdbg_btree_position pos; + phpdbg_btree_result *res; + + pos = phpdbg_btree_find_between(&PHPDBG_G(watchpoint_tree), 0, -1); + while ((res = phpdbg_btree_next(&pos))) { + phpdbg_deactivate_watchpoint(res->ptr); + } +} diff --git a/sapi/phpdbg/phpdbg_watch.h b/sapi/phpdbg/phpdbg_watch.h index 313df624ea..9814d78e2e 100644 --- a/sapi/phpdbg/phpdbg_watch.h +++ b/sapi/phpdbg/phpdbg_watch.h @@ -119,6 +119,7 @@ typedef struct { void phpdbg_setup_watchpoints(void); void phpdbg_destroy_watchpoints(void); +void phpdbg_purge_watchpoint_tree(void); #ifndef _WIN32 int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context); |