Skip to content

Commit 8483a21

Browse files
committed
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>
1 parent e483761 commit 8483a21

File tree

7 files changed

+29
-6
lines changed

7 files changed

+29
-6
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ PHP NEWS
77

88
- phpdbg:
99
. Fixed bug #73926 (phpdbg will not accept input on restart execution). (cmb)
10+
. Fixed several mostly Windows related phpdbg bugs. (cmb)
1011

1112
11 Jun 2020, PHP 7.4.7
1213

Zend/zend_vm_execute.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61348,6 +61348,7 @@ void zend_vm_dtor(void)
6134861348
if (zend_handlers_table) {
6134961349
zend_hash_destroy(zend_handlers_table);
6135061350
free(zend_handlers_table);
61351+
zend_handlers_table = NULL;
6135161352
}
6135261353
}
6135361354

Zend/zend_vm_execute.skl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ void zend_vm_dtor(void)
7575
if (zend_handlers_table) {
7676
zend_hash_destroy(zend_handlers_table);
7777
free(zend_handlers_table);
78+
zend_handlers_table = NULL;
7879
}
7980
}
8081

sapi/phpdbg/phpdbg.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1341,10 +1341,12 @@ php_stream *phpdbg_stream_url_wrap_php(php_stream_wrapper *wrapper, const char *
13411341
if (!strncasecmp(path, "stdin", 6) && PHPDBG_G(stdin_file)) {
13421342
php_stream *stream = php_stream_fopen_from_fd(dup(fileno(PHPDBG_G(stdin_file))), "r", NULL);
13431343
#ifdef PHP_WIN32
1344-
zval *blocking_pipes = php_stream_context_get_option(context, "pipe", "blocking");
1345-
if (blocking_pipes) {
1346-
convert_to_long(blocking_pipes);
1347-
php_stream_set_option(stream, PHP_STREAM_OPTION_PIPE_BLOCKING, Z_LVAL_P(blocking_pipes), NULL);
1344+
if (context != NULL) {
1345+
zval *blocking_pipes = php_stream_context_get_option(context, "pipe", "blocking");
1346+
if (blocking_pipes) {
1347+
convert_to_long(blocking_pipes);
1348+
php_stream_set_option(stream, PHP_STREAM_OPTION_PIPE_BLOCKING, Z_LVAL_P(blocking_pipes), NULL);
1349+
}
13481350
}
13491351
#endif
13501352
return stream;
@@ -2059,6 +2061,8 @@ int main(int argc, char **argv) /* {{{ */
20592061
phpdbg_out:
20602062
#endif
20612063

2064+
phpdbg_purge_watchpoint_tree();
2065+
20622066
if (first_command) {
20632067
free(first_command);
20642068
first_command = NULL;

sapi/phpdbg/phpdbg_utils.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,8 +357,11 @@ PHPDBG_API int phpdbg_get_terminal_height(void) /* {{{ */
357357
#ifdef _WIN32
358358
CONSOLE_SCREEN_BUFFER_INFO csbi;
359359

360-
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
361-
lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
360+
if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi)) {
361+
lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
362+
} else {
363+
lines = 40;
364+
}
362365
#elif defined(HAVE_SYS_IOCTL_H) && defined(TIOCGWINSZ)
363366
struct winsize w;
364367

sapi/phpdbg/phpdbg_watch.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,6 +1406,8 @@ void phpdbg_setup_watchpoints(void) {
14061406
zend_hash_init(PHPDBG_G(watchlist_mem), phpdbg_pagesize / (sizeof(Bucket) + sizeof(uint32_t)), NULL, NULL, 1);
14071407
PHPDBG_G(watchlist_mem_backup) = malloc(phpdbg_pagesize > sizeof(HashTable) ? phpdbg_pagesize : sizeof(HashTable));
14081408
zend_hash_init(PHPDBG_G(watchlist_mem_backup), phpdbg_pagesize / (sizeof(Bucket) + sizeof(uint32_t)), NULL, NULL, 1);
1409+
1410+
PHPDBG_G(watch_tmp) = NULL;
14091411
}
14101412

14111413
void phpdbg_destroy_watchpoints(void) {
@@ -1433,3 +1435,13 @@ void phpdbg_destroy_watchpoints(void) {
14331435
zend_hash_destroy(PHPDBG_G(watchlist_mem_backup));
14341436
free(PHPDBG_G(watchlist_mem_backup));
14351437
}
1438+
1439+
void phpdbg_purge_watchpoint_tree(void) {
1440+
phpdbg_btree_position pos;
1441+
phpdbg_btree_result *res;
1442+
1443+
pos = phpdbg_btree_find_between(&PHPDBG_G(watchpoint_tree), 0, -1);
1444+
while ((res = phpdbg_btree_next(&pos))) {
1445+
phpdbg_deactivate_watchpoint(res->ptr);
1446+
}
1447+
}

sapi/phpdbg/phpdbg_watch.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ typedef struct {
119119

120120
void phpdbg_setup_watchpoints(void);
121121
void phpdbg_destroy_watchpoints(void);
122+
void phpdbg_purge_watchpoint_tree(void);
122123

123124
#ifndef _WIN32
124125
int phpdbg_watchpoint_segfault_handler(siginfo_t *info, void *context);

0 commit comments

Comments
 (0)