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_win.c phpdbg_btree.c '+
- 'phpdbg_parser.c phpdbg_lexer.c phpdbg_sigsafe.c phpdbg_wait.c phpdbg_io.c';
+ 'phpdbg_parser.c phpdbg_lexer.c phpdbg_sigsafe.c phpdbg_wait.c phpdbg_io.c ' +
+ 'phpdbg_sigio_win32.c';
PHPDBG_DLL='php' + PHP_VERSION + 'phpdbg.dll';
PHPDBG_EXE='phpdbg.exe';
pg->input_buflen = 0;
pg->sigsafe_mem.mem = NULL;
pg->sigsegv_bailout = NULL;
+
+#ifdef PHP_WIN32
+ pg->sigio_watcher_thread = INVALID_HANDLE_VALUE;
+ memset(&pg->swd, 0, sizeof(struct win32_sigio_watcher_data));
+#endif
} /* }}} */
static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */
#include "phpdbg_utils.h"
#include "phpdbg_btree.h"
#include "phpdbg_watch.h"
+#ifdef PHP_WIN32
+# include "phpdbg_sigio_win32.h"
+#else
+# define sigio_watcher_start()
+# define sigio_watcher_stop()
+#endif
int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC);
char *sapi_name_ptr; /* store sapi name to free it if necessary to not leak memory */
int socket_fd; /* file descriptor to socket (wait command) (-1 if unused) */
int socket_server_fd; /* file descriptor to master socket (wait command) (-1 if unused) */
+#ifdef PHP_WIN32
+ HANDLE sigio_watcher_thread; /* sigio watcher thread handle */
+ struct win32_sigio_watcher_data swd;
+#endif
ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */
#endif
zend_bool restore = 1;
zend_execute_data *ex = EG(current_execute_data);
+ sigio_watcher_start();
+
if (!PHPDBG_G(ops)) {
if (phpdbg_compile(TSRMLS_C) == FAILURE) {
phpdbg_error("compile", "type=\"compilefailure\" context=\"%s\"", "Failed to compile %s, cannot run", PHPDBG_G(exec));
zend_execute(EG(active_op_array) TSRMLS_CC);
PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE;
phpdbg_notice("stop", "type=\"normal\"", "Script ended normally");
+ sigio_watcher_stop();
} zend_catch {
EG(active_op_array) = orig_op_array;
EG(opline_ptr) = orig_opline;
phpdbg_error("stop", "type=\"bailout\"", "Caught exit/error from VM");
restore = 0;
}
+ sigio_watcher_stop();
} zend_end_try();
if (PHPDBG_G(socket_fd) != -1) {
}
out:
+ sigio_watcher_stop();
PHPDBG_FRAME(num) = 0;
return SUCCESS;
} /* }}} */
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 7-4 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Anatol Belski <ab@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+
+#include <signal.h>
+
+#include "phpdbg.h"
+
+
+ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
+
+
+VOID
+SigIoWatcherThread(VOID *p)
+{
+ zend_uchar sig;
+
+ (void)recv(PHPDBG_G(swd).fd, &sig, 1, 0);
+
+ if (3 == sig) {
+ printf("signaled, got %d", sig);
+ /* XXX completely not sure where to go from here */
+ if (raise(sig)) {
+ /* just out*/
+ exit(0);
+ }
+ ExitThread(sig);
+ }
+}
+
+
+/* Start this only for the time of the run or eval command,
+for so long that the main thread is busy serving some debug
+session. */
+void
+sigio_watcher_start(void)
+{
+ PHPDBG_G(swd).fd = PHPDBG_G(io)[PHPDBG_STDIN].fd;
+ PHPDBG_G(swd).signaled = 0;
+
+ PHPDBG_G(sigio_watcher_thread) = CreateThread(
+ NULL,
+ 0,
+ (LPTHREAD_START_ROUTINE)SigIoWatcherThread,
+ NULL,
+ 0,
+ NULL);
+}
+
+void
+sigio_watcher_stop(void)
+{
+ DWORD waited;
+
+ if (INVALID_HANDLE_VALUE == PHPDBG_G(sigio_watcher_thread)) {
+ /* it probably did bail out already */
+ return;
+ }
+
+ waited = WaitForSingleObject(PHPDBG_G(sigio_watcher_thread), 300);
+
+ if (WAIT_OBJECT_0 != waited) {
+ if (!CancelSynchronousIo(PHPDBG_G(sigio_watcher_thread))) {
+ /* error out */
+ }
+
+ if (!TerminateThread(PHPDBG_G(sigio_watcher_thread), 0)) {
+ /* error out */
+ }
+ }
+
+ PHPDBG_G(swd).fd = -1;
+ PHPDBG_G(swd).signaled = 0;
+ PHPDBG_G(sigio_watcher_thread) = INVALID_HANDLE_VALUE;
+}
+
--- /dev/null
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 7-4 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Anatol Belski <ab@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+
+#ifndef PHPDBG_SIGIO_WIN32_H
+#define PHPDBG_SIGIO_WIN32_H
+
+#include "phpdbg.h"
+
+struct win32_sigio_watcher_data {
+ int fd;
+ zend_uchar signaled;
+};
+
+void
+sigio_watcher_start(void);
+
+void
+sigio_watcher_stop(void);
+
+#endif /* PHPDBG_SIGIO_WIN32_H */