summaryrefslogtreecommitdiff
path: root/sapi
diff options
context:
space:
mode:
Diffstat (limited to 'sapi')
-rw-r--r--sapi/cgi/cgi_main.c141
-rw-r--r--sapi/cli/config.w325
-rw-r--r--sapi/cli/php_cli.c8
-rw-r--r--sapi/fpm/fpm/fpm_conf.c2
-rw-r--r--sapi/fpm/fpm/fpm_events.c3
-rw-r--r--sapi/litespeed/lsapilib.c4
-rw-r--r--sapi/phpdbg/phpdbg_frame.c4
-rw-r--r--sapi/phpdbg/phpdbg_help.c2
-rw-r--r--sapi/phpdbg/phpdbg_list.c5
-rw-r--r--sapi/phpdbg/phpdbg_opcode.c110
-rw-r--r--sapi/phpdbg/phpdbg_print.c6
-rw-r--r--sapi/phpdbg/phpdbg_prompt.c10
-rw-r--r--sapi/phpdbg/phpdbg_utils.c12
-rw-r--r--sapi/phpdbg/phpdbg_watch.c4
-rw-r--r--sapi/phpdbg/tests/breakpoints_001.phpt22
-rw-r--r--sapi/phpdbg/tests/breakpoints_002.phpt28
-rw-r--r--sapi/phpdbg/tests/breakpoints_003.phpt14
-rw-r--r--sapi/phpdbg/tests/breakpoints_004.phpt28
-rw-r--r--sapi/phpdbg/tests/exceptions_003.phpt2
-rw-r--r--sapi/phpdbg/tests/stepping_001.phpt4
20 files changed, 271 insertions, 143 deletions
diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c
index 8983b53dc2..e758b33eeb 100644
--- a/sapi/cgi/cgi_main.c
+++ b/sapi/cgi/cgi_main.c
@@ -35,6 +35,7 @@
#ifdef PHP_WIN32
# include "win32/time.h"
# include "win32/signal.h"
+# include "win32/winutil.h"
# include <process.h>
#endif
@@ -102,7 +103,6 @@ struct sigaction act, old_term, old_quit, old_int;
static void (*php_php_import_environment_variables)(zval *array_ptr);
-#ifndef PHP_WIN32
/* these globals used for forking children on unix systems */
/**
* Number of child processes that will get created to service requests
@@ -115,6 +115,7 @@ static int children = 0;
*/
static int parent = 1;
+#ifndef PHP_WIN32
/* Did parent received exit signals SIG_TERM/SIG_INT/SIG_QUIT */
static int exit_signal = 0;
@@ -222,6 +223,14 @@ static php_cgi_globals_struct php_cgi_globals;
#define TRANSLATE_SLASHES(path)
#endif
+#ifdef PHP_WIN32
+#define WIN32_MAX_SPAWN_CHILDREN 64
+HANDLE kid_cgi_ps[WIN32_MAX_SPAWN_CHILDREN];
+int kids;
+HANDLE job = NULL;
+JOBOBJECT_EXTENDED_LIMIT_INFORMATION job_info = { 0 };
+#endif
+
#ifndef HAVE_ATTRIBUTE_WEAK
static void fcgi_log(int type, const char *format, ...) {
va_list ap;
@@ -354,9 +363,7 @@ static void sapi_fcgi_flush(void *server_context)
fcgi_request *request = (fcgi_request*) server_context;
if (
-#ifndef PHP_WIN32
!parent &&
-#endif
request && !fcgi_flush(request, 0)) {
php_handle_aborted_connection();
@@ -900,9 +907,7 @@ static int sapi_cgi_deactivate(void)
if (SG(sapi_started)) {
if (fcgi_is_fastcgi()) {
if (
-#ifndef PHP_WIN32
!parent &&
-#endif
!fcgi_finish_request((fcgi_request*)SG(server_context), 0)) {
php_handle_aborted_connection();
}
@@ -1431,6 +1436,29 @@ void fastcgi_cleanup(int signal)
exit(0);
}
}
+#else
+BOOL WINAPI fastcgi_cleanup(DWORD sig)
+{
+ int i = kids;
+
+ while (0 < i--) {
+ if (NULL == kid_cgi_ps[i]) {
+ continue;
+ }
+
+ TerminateProcess(kid_cgi_ps[i], 0);
+ CloseHandle(kid_cgi_ps[i]);
+ kid_cgi_ps[i] = NULL;
+ }
+
+ if (job) {
+ CloseHandle(job);
+ }
+
+ parent = 0;
+
+ return TRUE;
+}
#endif
PHP_INI_BEGIN()
@@ -1979,8 +2007,7 @@ consult the installation file that came with this distribution, or visit \n\
/* library is already initialized, now init our request */
request = fcgi_init_request(fcgi_fd, NULL, NULL, NULL);
-#ifndef PHP_WIN32
- /* Pre-fork, if required */
+ /* Pre-fork or spawn, if required */
if (getenv("PHP_FCGI_CHILDREN")) {
char * children_str = getenv("PHP_FCGI_CHILDREN");
children = atoi(children_str);
@@ -1996,6 +2023,7 @@ consult the installation file that came with this distribution, or visit \n\
fcgi_set_mgmt_var("FCGI_MAX_REQS", sizeof("FCGI_MAX_REQS")-1, "1", sizeof("1")-1);
}
+#ifndef PHP_WIN32
if (children) {
int running = 0;
pid_t pid;
@@ -2081,6 +2109,103 @@ consult the installation file that came with this distribution, or visit \n\
parent = 0;
}
+#else
+ if (children) {
+ char *cmd_line;
+ char kid_buf[16];
+ char my_name[MAX_PATH] = {0};
+ int i;
+
+ ZeroMemory(&kid_cgi_ps, sizeof(kid_cgi_ps));
+ kids = children < WIN32_MAX_SPAWN_CHILDREN ? children : WIN32_MAX_SPAWN_CHILDREN;
+
+ SetConsoleCtrlHandler(fastcgi_cleanup, TRUE);
+
+ /* kids will inherit the env, don't let them spawn */
+ SetEnvironmentVariable("PHP_FCGI_CHILDREN", NULL);
+
+ GetModuleFileName(NULL, my_name, MAX_PATH);
+ cmd_line = my_name;
+
+ job = CreateJobObject(NULL, NULL);
+ if (!job) {
+ DWORD err = GetLastError();
+ char *err_text = php_win32_error_to_msg(err);
+
+ fprintf(stderr, "unable to create job object: [0x%08lx]: %s\n", err, err_text);
+
+ goto parent_out;
+ }
+
+ job_info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
+ if (!SetInformationJobObject(job, JobObjectExtendedLimitInformation, &job_info, sizeof(job_info))) {
+ DWORD err = GetLastError();
+ char *err_text = php_win32_error_to_msg(err);
+
+ fprintf(stderr, "unable to configure job object: [0x%08lx]: %s\n", err, err_text);
+ }
+
+ while (parent) {
+ i = kids;
+ while (0 < i--) {
+ DWORD status;
+
+ if (NULL != kid_cgi_ps[i]) {
+ if(!GetExitCodeProcess(kid_cgi_ps[i], &status) || status != STILL_ACTIVE) {
+ CloseHandle(kid_cgi_ps[i]);
+ kid_cgi_ps[i] = NULL;
+ }
+ }
+ }
+
+ i = kids;
+ while (0 < i--) {
+ PROCESS_INFORMATION pi;
+ STARTUPINFO si;
+
+ if (NULL != kid_cgi_ps[i]) {
+ continue;
+ }
+
+ ZeroMemory(&si, sizeof(si));
+ si.cb = sizeof(si);
+ ZeroMemory(&pi, sizeof(pi));
+
+ si.dwFlags = STARTF_USESTDHANDLES;
+ si.hStdOutput = INVALID_HANDLE_VALUE;
+ si.hStdInput = (HANDLE)_get_osfhandle(fcgi_fd);
+ si.hStdError = INVALID_HANDLE_VALUE;
+
+ if (CreateProcess(NULL, cmd_line, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
+ kid_cgi_ps[i] = pi.hProcess;
+ if (!AssignProcessToJobObject(job, pi.hProcess)) {
+ DWORD err = GetLastError();
+ char *err_text = php_win32_error_to_msg(err);
+
+ fprintf(stderr, "unable to assign child process to job object: [0x%08lx]: %s\n", err, err_text);
+ }
+ CloseHandle(pi.hThread);
+ } else {
+ DWORD err = GetLastError();
+ char *err_text = php_win32_error_to_msg(err);
+
+ kid_cgi_ps[i] = NULL;
+
+ fprintf(stderr, "unable to spawn: [0x%08lx]: %s\n", err, err_text);
+ }
+ }
+
+ WaitForMultipleObjects(kids, kid_cgi_ps, FALSE, INFINITE);
+ }
+
+ snprintf(kid_buf, 16, "%d", children);
+ /* restore my env */
+ SetEnvironmentVariable("PHP_FCGI_CHILDREN", kid_buf);
+
+ goto parent_out;
+ } else {
+ parent = 0;
+ }
#endif /* WIN32 */
}
@@ -2584,9 +2709,7 @@ out:
#endif
}
-#ifndef PHP_WIN32
parent_out:
-#endif
SG(server_context) = NULL;
php_module_shutdown();
diff --git a/sapi/cli/config.w32 b/sapi/cli/config.w32
index 664394c8a6..c6409b59df 100644
--- a/sapi/cli/config.w32
+++ b/sapi/cli/config.w32
@@ -12,6 +12,11 @@ if (PHP_CLI == "yes") {
ADD_FLAG("CFLAGS_CLI", "/D PHP_WIN32_DEBUG_HEAP");
}
ADD_FLAG("LDFLAGS_CLI", "/stack:67108864");
+
+ if (CHECK_LIB("edit_a.lib;edit.lib", "cli", PHP_CLI) &&
+ CHECK_HEADER_ADD_INCLUDE("editline/readline.h", "CFLAGS_CLI")) {
+ ADD_FLAG("CFLAGS_CLI", "/D HAVE_LIBEDIT");
+ }
}
if (PHP_CLI_WIN32 == "yes") {
diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c
index 978c8b332e..09ce00f9e7 100644
--- a/sapi/cli/php_cli.c
+++ b/sapi/cli/php_cli.c
@@ -689,6 +689,14 @@ static int do_cli(int argc, char **argv) /* {{{ */
#else
"NTS "
#endif
+#ifdef COMPILER
+ COMPILER
+ " "
+#endif
+#ifdef ARCHITECTURE
+ ARCHITECTURE
+ " "
+#endif
#if ZEND_DEBUG
"DEBUG "
#endif
diff --git a/sapi/fpm/fpm/fpm_conf.c b/sapi/fpm/fpm/fpm_conf.c
index 9a619ce887..2a92fb25a7 100644
--- a/sapi/fpm/fpm/fpm_conf.c
+++ b/sapi/fpm/fpm/fpm_conf.c
@@ -1573,7 +1573,7 @@ static void fpm_conf_dump() /* {{{ */
/*
* Please keep the same order as in fpm_conf.h and in php-fpm.conf.in
*/
- zlog(ZLOG_NOTICE, "[General]");
+ zlog(ZLOG_NOTICE, "[global]");
zlog(ZLOG_NOTICE, "\tpid = %s", STR2STR(fpm_global_config.pid_file));
zlog(ZLOG_NOTICE, "\terror_log = %s", STR2STR(fpm_global_config.error_log));
#ifdef HAVE_SYSLOG_H
diff --git a/sapi/fpm/fpm/fpm_events.c b/sapi/fpm/fpm/fpm_events.c
index ca45cb1665..2b8e8cf13a 100644
--- a/sapi/fpm/fpm/fpm_events.c
+++ b/sapi/fpm/fpm/fpm_events.c
@@ -291,7 +291,7 @@ int fpm_event_pre_init(char *machanism) /* {{{ */
}
return -1;
}
-/* }} */
+/* }}} */
const char *fpm_event_machanism_name() /* {{{ */
{
@@ -538,4 +538,3 @@ int fpm_event_del(struct fpm_event_s *ev) /* {{{ */
}
/* }}} */
-/* }}} */
diff --git a/sapi/litespeed/lsapilib.c b/sapi/litespeed/lsapilib.c
index 4fc4c6e2e6..41a1715d07 100644
--- a/sapi/litespeed/lsapilib.c
+++ b/sapi/litespeed/lsapilib.c
@@ -1499,7 +1499,7 @@ int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, size_t bufLen, in
char * pBufCur = pBuf;
char * pCur;
char * p;
- if (!pReq || (pReq->m_fd ==-1) ||( !pBuf )|| !getLF )
+ if (!pReq || (pReq->m_fd ==-1) ||( !pBuf )||(bufLen < 0 )|| !getLF )
return -1;
*getLF = 0;
while( (left = pBufEnd - pBufCur ) > 0 )
@@ -1543,7 +1543,7 @@ ssize_t LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, size_t bufLen )
ssize_t len;
off_t total;
/* char *pOldBuf = pBuf; */
- if (!pReq || (pReq->m_fd ==-1) || ( !pBuf ))
+ if (!pReq || (pReq->m_fd ==-1) || ( !pBuf )||(bufLen < 0 ))
return -1;
total = pReq->m_reqBodyLen - pReq->m_reqBodyRead;
diff --git a/sapi/phpdbg/phpdbg_frame.c b/sapi/phpdbg/phpdbg_frame.c
index d6256a84af..f64d18b4bb 100644
--- a/sapi/phpdbg/phpdbg_frame.c
+++ b/sapi/phpdbg/phpdbg_frame.c
@@ -36,8 +36,6 @@ void phpdbg_restore_frame(void) /* {{{ */
/* move things back */
EG(current_execute_data) = PHPDBG_FRAME(execute_data);
-
- EG(scope) = PHPDBG_EX(func)->op_array.scope;
} /* }}} */
void phpdbg_switch_frame(int frame) /* {{{ */
@@ -78,8 +76,6 @@ void phpdbg_switch_frame(int frame) /* {{{ */
/* backup things and jump back */
PHPDBG_FRAME(execute_data) = EG(current_execute_data);
EG(current_execute_data) = execute_data;
-
- EG(scope) = PHPDBG_EX(func)->op_array.scope;
}
phpdbg_notice("frame", "id=\"%d\"", "Switched to frame #%d", frame);
diff --git a/sapi/phpdbg/phpdbg_help.c b/sapi/phpdbg/phpdbg_help.c
index 97b93f4345..fb73419910 100644
--- a/sapi/phpdbg/phpdbg_help.c
+++ b/sapi/phpdbg/phpdbg_help.c
@@ -810,7 +810,7 @@ phpdbg_help_text_t phpdbg_help_text[] = {
{"run",
"Enter the vm, startinging execution. Execution will then continue until the next breakpoint "
-"or completion of the script. Add parameters you want to use as $argv"
+"or completion of the script. Add parameters you want to use as $argv" CR CR
"**Examples**" CR CR
" $P run" CR
" $P r" CR
diff --git a/sapi/phpdbg/phpdbg_list.c b/sapi/phpdbg/phpdbg_list.c
index e9cf1bc0b8..2e97ad4b73 100644
--- a/sapi/phpdbg/phpdbg_list.c
+++ b/sapi/phpdbg/phpdbg_list.c
@@ -200,11 +200,12 @@ void phpdbg_list_function_byname(const char *str, size_t len) /* {{{ */
/* search active scope if begins with period */
if (func_name[0] == '.') {
- if (EG(scope)) {
+ zend_class_entry *scope = zend_get_executed_scope();
+ if (scope) {
func_name++;
func_name_len--;
- func_table = &EG(scope)->function_table;
+ func_table = &scope->function_table;
} else {
phpdbg_error("inactive", "type=\"noclasses\"", "No active class");
return;
diff --git a/sapi/phpdbg/phpdbg_opcode.c b/sapi/phpdbg/phpdbg_opcode.c
index e64ab0d636..8bd7c4e50e 100644
--- a/sapi/phpdbg/phpdbg_opcode.c
+++ b/sapi/phpdbg/phpdbg_opcode.c
@@ -36,7 +36,8 @@ static inline const char *phpdbg_decode_opcode(zend_uchar opcode) /* {{{ */
return "UNKNOWN";
} /* }}} */
-static inline char *phpdbg_decode_op(zend_op_array *ops, znode_op *op, uint32_t type) /* {{{ */
+static inline char *phpdbg_decode_op(
+ zend_op_array *ops, const znode_op *op, uint32_t type) /* {{{ */
{
char *decode = NULL;
@@ -62,91 +63,72 @@ static inline char *phpdbg_decode_op(zend_op_array *ops, znode_op *op, uint32_t
return decode;
} /* }}} */
-char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op) /*{{{ */
+char *phpdbg_decode_input_op(
+ zend_op_array *ops, const zend_op *opline, znode_op op, zend_uchar op_type,
+ uint32_t flags) {
+ char *result = NULL;
+ if (op_type != IS_UNUSED) {
+ result = phpdbg_decode_op(ops, &op, op_type);
+ } else if (ZEND_VM_OP_JMP_ADDR == (flags & ZEND_VM_OP_MASK)) {
+ spprintf(&result, 0, "J%td", OP_JMP_ADDR(opline, op) - ops->opcodes);
+ } else if (ZEND_VM_OP_NUM == (flags & ZEND_VM_OP_MASK)) {
+ spprintf(&result, 0, "%" PRIu32, op.num);
+ } else if (ZEND_VM_OP_TRY_CATCH == (flags & ZEND_VM_OP_MASK)) {
+ if (opline->opcode != ZEND_FAST_RET || opline->extended_value) {
+ spprintf(&result, 0, "try-catch(%" PRIu32 ")", op.num);
+ }
+ } else if (ZEND_VM_OP_LIVE_RANGE == (flags & ZEND_VM_OP_MASK)) {
+ if (opline->extended_value & ZEND_FREE_ON_RETURN) {
+ spprintf(&result, 0, "live-range(%" PRIu32 ")", op.num);
+ }
+ } else if (ZEND_VM_OP_THIS == (flags & ZEND_VM_OP_MASK)) {
+ result = estrdup("THIS");
+ } else if (ZEND_VM_OP_NEXT == (flags & ZEND_VM_OP_MASK)) {
+ result = estrdup("NEXT");
+ } else if (ZEND_VM_OP_CLASS_FETCH == (flags & ZEND_VM_OP_MASK)) {
+ //zend_dump_class_fetch_type(op.num);
+ } else if (ZEND_VM_OP_CONSTRUCTOR == (flags & ZEND_VM_OP_MASK)) {
+ result = estrdup("CONSTRUCTOR");
+ }
+ return result;
+}
+
+char *phpdbg_decode_opline(zend_op_array *ops, zend_op *opline) /*{{{ */
{
- const char *opcode_name = phpdbg_decode_opcode(op->opcode);
+ const char *opcode_name = phpdbg_decode_opcode(opline->opcode);
+ uint32_t flags = zend_get_opcode_flags(opline->opcode);
char *result, *decode[4] = {NULL, NULL, NULL, NULL};
/* EX */
- switch (op->opcode) {
+ switch (opline->opcode) {
case ZEND_FAST_CALL:
- if (op->extended_value == ZEND_FAST_CALL_FROM_FINALLY) {
+ if (opline->extended_value == ZEND_FAST_CALL_FROM_FINALLY) {
decode[0] = estrdup("FAST_CALL<FROM_FINALLY>");
}
break;
case ZEND_FAST_RET:
- if (op->extended_value != 0) {
+ if (opline->extended_value != 0) {
spprintf(&decode[0], 0, "FAST_RET<%s>",
- op->extended_value == ZEND_FAST_RET_TO_CATCH ? "TO_CATCH" : "TO_FINALLY");
+ opline->extended_value == ZEND_FAST_RET_TO_CATCH ? "TO_CATCH" : "TO_FINALLY");
}
break;
}
/* OP1 */
- switch (op->opcode) {
- case ZEND_JMP:
- case ZEND_FAST_CALL:
- spprintf(&decode[1], 0, "J%td", OP_JMP_ADDR(op, op->op1) - ops->opcodes);
- break;
-
- case ZEND_INIT_FCALL:
- case ZEND_RECV:
- case ZEND_RECV_INIT:
- case ZEND_RECV_VARIADIC:
- spprintf(&decode[1], 0, "%" PRIu32, op->op1.num);
- break;
-
- default:
- decode[1] = phpdbg_decode_op(ops, &op->op1, op->op1_type);
- break;
- }
+ decode[1] = phpdbg_decode_input_op(
+ ops, opline, opline->op1, opline->op1_type, ZEND_VM_OP1_FLAGS(flags));
/* OP2 */
- switch (op->opcode) {
- case ZEND_JMPZNZ:
- spprintf(&decode[2], 0, "J%td or J%td",
- OP_JMP_ADDR(op, op->op2) - ops->opcodes,
- ZEND_OFFSET_TO_OPLINE(op, op->extended_value) - ops->opcodes);
- break;
-
- case ZEND_JMPZ:
- case ZEND_JMPNZ:
- case ZEND_JMPZ_EX:
- case ZEND_JMPNZ_EX:
- case ZEND_JMP_SET:
- case ZEND_ASSERT_CHECK:
- spprintf(&decode[2], 0, "J%td", OP_JMP_ADDR(op, op->op2) - ops->opcodes);
- break;
-
- case ZEND_FAST_CALL:
- case ZEND_FAST_RET:
- if (op->extended_value != 0) {
- spprintf(&decode[2], 0, "J%" PRIu32, op->op2.opline_num);
- }
- break;
-
- case ZEND_SEND_VAL:
- case ZEND_SEND_VAL_EX:
- case ZEND_SEND_VAR:
- case ZEND_SEND_VAR_NO_REF:
- case ZEND_SEND_REF:
- case ZEND_SEND_VAR_EX:
- case ZEND_SEND_USER:
- spprintf(&decode[2], 0, "%" PRIu32, op->op2.num);
- break;
-
- default:
- decode[2] = phpdbg_decode_op(ops, &op->op2, op->op2_type);
- break;
- }
+ decode[2] = phpdbg_decode_input_op(
+ ops, opline, opline->op2, opline->op2_type, ZEND_VM_OP2_FLAGS(flags));
/* RESULT */
- switch (op->opcode) {
+ switch (opline->opcode) {
case ZEND_CATCH:
- spprintf(&decode[3], 0, "%" PRIu32, op->result.num);
+ spprintf(&decode[3], 0, "%" PRIu32, opline->result.num);
break;
default:
- decode[3] = phpdbg_decode_op(ops, &op->result, op->result_type);
+ decode[3] = phpdbg_decode_op(ops, &opline->result, opline->result_type);
break;
}
diff --git a/sapi/phpdbg/phpdbg_print.c b/sapi/phpdbg/phpdbg_print.c
index 3725bf6083..034354a9e7 100644
--- a/sapi/phpdbg/phpdbg_print.c
+++ b/sapi/phpdbg/phpdbg_print.c
@@ -217,11 +217,13 @@ PHPDBG_PRINT(func) /* {{{ */
zend_string *lcname;
/* search active scope if begins with period */
if (func_name[0] == '.') {
- if (EG(scope)) {
+ zend_class_entry *scope = zend_get_executed_scope();
+
+ if (scope) {
func_name++;
func_name_len--;
- func_table = &EG(scope)->function_table;
+ func_table = &scope->function_table;
} else {
phpdbg_error("inactive", "type=\"noclasses\"", "No active class");
return SUCCESS;
diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c
index a01c8a399f..3b7274a997 100644
--- a/sapi/phpdbg/phpdbg_prompt.c
+++ b/sapi/phpdbg/phpdbg_prompt.c
@@ -120,9 +120,7 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack) /* {{{ */
ZVAL_STRINGL(&fci.function_name, lc_name, name->len);
fci.size = sizeof(zend_fcall_info);
- fci.function_table = &PHPDBG_G(registered);
//???fci.symbol_table = zend_rebuild_symbol_table();
- fci.symbol_table = NULL;
fci.object = NULL;
fci.retval = &fretval;
fci.no_separation = 1;
@@ -654,7 +652,7 @@ static inline void phpdbg_handle_exception(void) /* {{{ */
phpdbg_error("exception", "name=\"%s\" file=\"%s\" line=\"" ZEND_LONG_FMT "\"", "Uncaught %s in %s on line " ZEND_LONG_FMT, ZSTR_VAL(ex->ce->name), ZSTR_VAL(file), line);
zend_string_release(file);
- phpdbg_writeln("exceptionmsg", "msg=\"%s\"", ZSTR_VAL(msg));
+ phpdbg_writeln("exceptionmsg", "msg=\"%s\"", "%s", ZSTR_VAL(msg));
zend_string_release(msg);
if (EG(prev_exception)) {
@@ -689,7 +687,7 @@ PHPDBG_COMMAND(run) /* {{{ */
}
/* clean up from last execution */
- if (ex && ex->symbol_table) {
+ if (ex && (ZEND_CALL_INFO(ex) & ZEND_CALL_HAS_SYMBOL_TABLE)) {
zend_hash_clean(ex->symbol_table);
} else {
zend_rebuild_symbol_table();
@@ -799,7 +797,6 @@ PHPDBG_COMMAND(ev) /* {{{ */
zval retval;
zend_execute_data *original_execute_data = EG(current_execute_data);
- zend_class_entry *original_scope = EG(scope);
zend_vm_stack original_stack = EG(vm_stack);
zend_object *ex = NULL;
@@ -847,7 +844,6 @@ PHPDBG_COMMAND(ev) /* {{{ */
OBJ_RELEASE(ex);
}
EG(current_execute_data) = original_execute_data;
- EG(scope) = original_scope;
EG(vm_stack_top) = original_stack->top;
EG(vm_stack_end) = original_stack->end;
EG(vm_stack) = original_stack;
@@ -1634,7 +1630,7 @@ next:
execute_data->call->func->type == ZEND_USER_FUNCTION) {
zend_execute_ex = execute_ex;
}
- PHPDBG_G(vmret) = zend_vm_call_opcode_handler(execute_data);
+ PHPDBG_G(vmret) = zend_vm_call_opcode_handler(execute_data);
zend_execute_ex = phpdbg_execute_ex;
if (PHPDBG_G(vmret) != 0) {
diff --git a/sapi/phpdbg/phpdbg_utils.c b/sapi/phpdbg/phpdbg_utils.c
index 7158f3ba6c..6f42665809 100644
--- a/sapi/phpdbg/phpdbg_utils.c
+++ b/sapi/phpdbg/phpdbg_utils.c
@@ -804,6 +804,18 @@ char *phpdbg_short_zval_print(zval *zv, int maxlen) /* {{{ */
break;
case IS_DOUBLE:
spprintf(&decode, 0, "%.*G", 14, Z_DVAL_P(zv));
+
+ /* Make sure it looks like a float */
+ if (zend_finite(Z_DVAL_P(zv)) && !strchr(decode, '.')) {
+ size_t len = strlen(decode);
+ char *decode2 = emalloc(len + strlen(".0") + 1);
+ memcpy(decode2, decode, len);
+ decode2[len] = '.';
+ decode2[len+1] = '0';
+ decode2[len+2] = '\0';
+ efree(decode);
+ decode = decode2;
+ }
break;
case IS_STRING: {
int i;
diff --git a/sapi/phpdbg/phpdbg_watch.c b/sapi/phpdbg/phpdbg_watch.c
index 2c324aa5dc..0224ff4fd1 100644
--- a/sapi/phpdbg/phpdbg_watch.c
+++ b/sapi/phpdbg/phpdbg_watch.c
@@ -680,7 +680,9 @@ static int phpdbg_watchpoint_parse_step(char *name, size_t namelen, char *key, s
}
static int phpdbg_watchpoint_parse_symtables(char *input, size_t len, int (*callback)(phpdbg_watchpoint_t *)) {
- if (EG(scope) && len >= 5 && !memcmp("$this", input, 5)) {
+ zend_class_entry *scope = zend_get_executed_scope();
+
+ if (scope && len >= 5 && !memcmp("$this", input, 5)) {
zend_hash_str_add(EG(current_execute_data)->symbol_table, ZEND_STRL("this"), &EG(current_execute_data)->This);
}
diff --git a/sapi/phpdbg/tests/breakpoints_001.phpt b/sapi/phpdbg/tests/breakpoints_001.phpt
index 934f0d3554..17e7c65cbf 100644
--- a/sapi/phpdbg/tests/breakpoints_001.phpt
+++ b/sapi/phpdbg/tests/breakpoints_001.phpt
@@ -11,23 +11,23 @@ q
[Successful compilation of %s]
prompt> [Breakpoint #0 added at %s:3]
prompt> [Breakpoint #0 at %s:3, hits: 1]
->00003: echo 1;
- 00004: echo 2;
- 00005: echo 3;
+>00003: echo $i++;
+ 00004: echo $i++;
+ 00005: echo $i++;
prompt> [Breakpoint #1 added at %s:4]
prompt> 1
[Breakpoint #1 at %s:4, hits: 1]
->00004: echo 2;
- 00005: echo 3;
- 00006: echo 4;
+>00004: echo $i++;
+ 00005: echo $i++;
+ 00006: echo $i++;
prompt> 234
[Script ended normally]
prompt>
--FILE--
<?php
-
-echo 1;
-echo 2;
-echo 3;
-echo 4;
+$i = 1;
+echo $i++;
+echo $i++;
+echo $i++;
+echo $i++;
diff --git a/sapi/phpdbg/tests/breakpoints_002.phpt b/sapi/phpdbg/tests/breakpoints_002.phpt
index 18aaef1f36..96c98194b1 100644
--- a/sapi/phpdbg/tests/breakpoints_002.phpt
+++ b/sapi/phpdbg/tests/breakpoints_002.phpt
@@ -14,27 +14,27 @@ q
prompt> [Breakpoint #0 added at %s:4]
prompt> 1
[Breakpoint #0 at %s:4, hits: 1]
->00004: echo 2;
- 00005: echo 3;
- 00006: echo 4;
+>00004: echo $i++;
+ 00005: echo $i++;
+ 00006: echo $i++;
prompt> [Breakpoint #1 added at %s:3]
prompt> Do you really want to restart execution? (type y or n): [Breakpoint #1 at %s:3, hits: 1]
->00003: echo 1;
- 00004: echo 2;
- 00005: echo 3;
+>00003: echo $i++;
+ 00004: echo $i++;
+ 00005: echo $i++;
prompt> 1
[Breakpoint #0 at %s:4, hits: 1]
->00004: echo 2;
- 00005: echo 3;
- 00006: echo 4;
+>00004: echo $i++;
+ 00005: echo $i++;
+ 00006: echo $i++;
prompt> 234
[Script ended normally]
prompt>
--FILE--
<?php
-
-echo 1;
-echo 2;
-echo 3;
-echo 4;
+$i = 1;
+echo $i++;
+echo $i++;
+echo $i++;
+echo $i++;
diff --git a/sapi/phpdbg/tests/breakpoints_003.phpt b/sapi/phpdbg/tests/breakpoints_003.phpt
index 8caa64632b..12b2504487 100644
--- a/sapi/phpdbg/tests/breakpoints_003.phpt
+++ b/sapi/phpdbg/tests/breakpoints_003.phpt
@@ -16,8 +16,8 @@ prompt> [Deleted breakpoint #0]
prompt> [Breakpoint #1 added at %s:5]
prompt> 12
[Breakpoint #1 at %s:5, hits: 1]
->00005: echo 3;
- 00006: echo 4;
+>00005: echo $i++;
+ 00006: echo $i++;
00007:
prompt> [Deleted breakpoint #1]
prompt> Do you really want to restart execution? (type y or n): 1234
@@ -25,9 +25,9 @@ prompt> Do you really want to restart execution? (type y or n): 1234
prompt>
--FILE--
<?php
-
-echo 1;
-echo 2;
-echo 3;
-echo 4;
+$i = 1;
+echo $i++;
+echo $i++;
+echo $i++;
+echo $i++;
diff --git a/sapi/phpdbg/tests/breakpoints_004.phpt b/sapi/phpdbg/tests/breakpoints_004.phpt
index 27ebd0bea2..917e908efb 100644
--- a/sapi/phpdbg/tests/breakpoints_004.phpt
+++ b/sapi/phpdbg/tests/breakpoints_004.phpt
@@ -12,30 +12,30 @@ q
[Successful compilation of %s]
prompt> [Breakpoint #0 added at ZEND_ECHO]
prompt> [Breakpoint #0 in ZEND_ECHO at %s:3, hits: 1]
->00003: echo 1;
- 00004: echo 2;
- 00005: echo 3;
+>00003: echo $i++;
+ 00004: echo $i++;
+ 00005: echo $i++;
prompt> 1
[Breakpoint #0 in ZEND_ECHO at %s:4, hits: 2]
->00004: echo 2;
- 00005: echo 3;
- 00006: echo 4;
+>00004: echo $i++;
+ 00005: echo $i++;
+ 00006: echo $i++;
prompt> 2
[Breakpoint #0 in ZEND_ECHO at %s:5, hits: 3]
->00005: echo 3;
- 00006: echo 4;
+>00005: echo $i++;
+ 00006: echo $i++;
00007:
prompt> 3
[Breakpoint #0 in ZEND_ECHO at %s:6, hits: 4]
->00006: echo 4;
+>00006: echo $i++;
00007:
prompt> 4
[Script ended normally]
prompt>
--FILE--
<?php
-
-echo 1;
-echo 2;
-echo 3;
-echo 4;
+$i = 1;
+echo $i++;
+echo $i++;
+echo $i++;
+echo $i++;
diff --git a/sapi/phpdbg/tests/exceptions_003.phpt b/sapi/phpdbg/tests/exceptions_003.phpt
index fffe7a9296..37e7289092 100644
--- a/sapi/phpdbg/tests/exceptions_003.phpt
+++ b/sapi/phpdbg/tests/exceptions_003.phpt
@@ -25,7 +25,7 @@ prompt> [L7 %s ECHO "ok "
00008: }
00009: } catch (Error $e) {
prompt> ok
-[L7 %s FAST_RET<TO_CATCH> ~%d J7 %s]
+[L7 %s FAST_RET<TO_CATCH> ~%d try-catch(0) %s]
[L9 %s CATCH "Error" $e 1 %s]
>00005: x();
00006: } finally {
diff --git a/sapi/phpdbg/tests/stepping_001.phpt b/sapi/phpdbg/tests/stepping_001.phpt
index 5c92ba2f0b..ec9def278f 100644
--- a/sapi/phpdbg/tests/stepping_001.phpt
+++ b/sapi/phpdbg/tests/stepping_001.phpt
@@ -1,5 +1,7 @@
--TEST--
Stepping with exceptions must not be stuck at CATCH
+--INI--
+opcache.enable=0
--PHPDBG--
b ZEND_THROW
r
@@ -32,7 +34,7 @@ prompt> [L10 %s ECHO "ok"
00011: } finally {
00012: echo " ... ok";
prompt> ok
-[L11 %s FAST_CALL J8 ~%d %s]
+[L11 %s FAST_CALL J8 try-catch(0) ~%d %s]
>00011: } finally {
00012: echo " ... ok";
00013: }