summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2020-05-25 19:12:24 +0200
committerChristoph M. Becker <cmbecker69@gmx.de>2020-05-26 17:45:25 +0200
commit8483a21f29fbfd8d86ddf2eb2b7db0ae0b462949 (patch)
treeb802051897238ecb5deeaa6872a38ad1d2798b9e
parente483761a1e8ab058d9155688434c5fa9138f5ae1 (diff)
downloadphp-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>
-rw-r--r--NEWS1
-rw-r--r--Zend/zend_vm_execute.h1
-rw-r--r--Zend/zend_vm_execute.skl1
-rw-r--r--sapi/phpdbg/phpdbg.c12
-rw-r--r--sapi/phpdbg/phpdbg_utils.c7
-rw-r--r--sapi/phpdbg/phpdbg_watch.c12
-rw-r--r--sapi/phpdbg/phpdbg_watch.h1
7 files changed, 29 insertions, 6 deletions
diff --git a/NEWS b/NEWS
index c7b5542554..9093eb7308 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,7 @@ PHP NEWS
- phpdbg:
. Fixed bug #73926 (phpdbg will not accept input on restart execution). (cmb)
+ . Fixed several mostly Windows related phpdbg bugs. (cmb)
11 Jun 2020, PHP 7.4.7
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 13d55291f9..7af6b31501 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -61348,6 +61348,7 @@ void zend_vm_dtor(void)
if (zend_handlers_table) {
zend_hash_destroy(zend_handlers_table);
free(zend_handlers_table);
+ zend_handlers_table = NULL;
}
}
diff --git a/Zend/zend_vm_execute.skl b/Zend/zend_vm_execute.skl
index 3e520e9bac..170fc300bb 100644
--- a/Zend/zend_vm_execute.skl
+++ b/Zend/zend_vm_execute.skl
@@ -75,6 +75,7 @@ void zend_vm_dtor(void)
if (zend_handlers_table) {
zend_hash_destroy(zend_handlers_table);
free(zend_handlers_table);
+ zend_handlers_table = NULL;
}
}
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);