summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Weinand <bobwei9@hotmail.com>2016-02-17 20:26:47 +0100
committerBob Weinand <bobwei9@hotmail.com>2016-02-17 20:27:46 +0100
commit055b4112188cccdc250790ab063479d2922f5fda (patch)
treec44f668b32efacdba63a55b3ad8ce011e743abf7
parentd2287529396539fd2cba6f449ae9679cac64c3b9 (diff)
downloadphp-git-055b4112188cccdc250790ab063479d2922f5fda.tar.gz
Fix crash when advancing inside an internal function
This just happened in the "double ctrl+c" mode, when we halted inside an internal function; there was some code assuming a proper op_array
-rw-r--r--NEWS2
-rw-r--r--sapi/phpdbg/phpdbg_bp.c14
-rw-r--r--sapi/phpdbg/phpdbg_print.c4
-rw-r--r--sapi/phpdbg/phpdbg_prompt.c16
-rw-r--r--sapi/phpdbg/phpdbg_utils.h8
5 files changed, 29 insertions, 15 deletions
diff --git a/NEWS b/NEWS
index 60c75747a3..9d3ddf491e 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,8 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 2016 PHP 7.0.5
+- phpdbg:
+ . Fixed crash when advancing (except step) inside an internal function. (Bob)
?? ??? 2016 PHP 7.0.4
diff --git a/sapi/phpdbg/phpdbg_bp.c b/sapi/phpdbg/phpdbg_bp.c
index eac67d4ac7..5436bda5db 100644
--- a/sapi/phpdbg/phpdbg_bp.c
+++ b/sapi/phpdbg/phpdbg_bp.c
@@ -563,12 +563,14 @@ PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break) /* {
} else {
zend_execute_data *execute_data = EG(current_execute_data);
do {
- zend_op_array *op_array = &execute_data->func->op_array;
- if (op_array->function_name == NULL && op_array->scope == NULL && new_break->class_len == ZSTR_LEN(op_array->filename) && !memcmp(ZSTR_VAL(op_array->filename), new_break->class_name, new_break->class_len)) {
- if (phpdbg_resolve_op_array_break(new_break, op_array) == SUCCESS) {
- return SUCCESS;
- } else {
- return 2;
+ if (ZEND_USER_CODE(execute_data->func->common.type)) {
+ zend_op_array *op_array = &execute_data->func->op_array;
+ if (op_array->function_name == NULL && op_array->scope == NULL && new_break->class_len == ZSTR_LEN(op_array->filename) && !memcmp(ZSTR_VAL(op_array->filename), new_break->class_name, new_break->class_len)) {
+ if (phpdbg_resolve_op_array_break(new_break, op_array) == SUCCESS) {
+ return SUCCESS;
+ } else {
+ return 2;
+ }
}
}
} while ((execute_data = execute_data->prev_execute_data) != NULL);
diff --git a/sapi/phpdbg/phpdbg_print.c b/sapi/phpdbg/phpdbg_print.c
index abfad0219a..00209cb239 100644
--- a/sapi/phpdbg/phpdbg_print.c
+++ b/sapi/phpdbg/phpdbg_print.c
@@ -42,7 +42,7 @@ const phpdbg_command_t phpdbg_print_commands[] = {
PHPDBG_PRINT(opline) /* {{{ */
{
if (PHPDBG_G(in_execution) && EG(current_execute_data)) {
- phpdbg_print_opline(EG(current_execute_data), 1);
+ phpdbg_print_opline(phpdbg_user_execute_data(EG(current_execute_data)), 1);
} else {
phpdbg_error("inactive", "type=\"execution\"", "Not Executing!");
}
@@ -124,7 +124,7 @@ return SUCCESS;
PHPDBG_PRINT(stack) /* {{{ */
{
if (PHPDBG_G(in_execution) && EG(current_execute_data)) {
- zend_op_array *ops = &EG(current_execute_data)->func->op_array;
+ zend_op_array *ops = &phpdbg_user_execute_data(EG(current_execute_data))->func->op_array;
if (ops->function_name) {
if (ops->scope) {
phpdbg_notice("printinfo", "method=\"%s::%s\" num=\"%d\"", "Stack in %s::%s() (%d ops)", ZSTR_VAL(ops->scope->name), ZSTR_VAL(ops->function_name), ops->last);
diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c
index 0314442daa..558ca469b5 100644
--- a/sapi/phpdbg/phpdbg_prompt.c
+++ b/sapi/phpdbg/phpdbg_prompt.c
@@ -518,13 +518,14 @@ PHPDBG_COMMAND(continue) /* {{{ */
} /* }}} */
int phpdbg_skip_line_helper() /* {{{ */ {
- const zend_op_array *op_array = &EG(current_execute_data)->func->op_array;
+ zend_execute_data *ex = phpdbg_user_execute_data(EG(current_execute_data));
+ const zend_op_array *op_array = &ex->func->op_array;
const zend_op *opline = op_array->opcodes;
PHPDBG_G(flags) |= PHPDBG_IN_UNTIL;
- PHPDBG_G(seek_ex) = EG(current_execute_data);
+ PHPDBG_G(seek_ex) = ex;
do {
- if (opline->lineno != EG(current_execute_data)->opline->lineno
+ if (opline->lineno != ex->opline->lineno
|| opline->opcode == ZEND_RETURN
|| opline->opcode == ZEND_FAST_RET
|| opline->opcode == ZEND_GENERATOR_RETURN
@@ -562,10 +563,11 @@ PHPDBG_COMMAND(next) /* {{{ */
} /* }}} */
static void phpdbg_seek_to_end(void) /* {{{ */ {
- const zend_op_array *op_array = &EG(current_execute_data)->func->op_array;
+ zend_execute_data *ex = phpdbg_user_execute_data(EG(current_execute_data));
+ const zend_op_array *op_array = &ex->func->op_array;
const zend_op *opline = op_array->opcodes;
- PHPDBG_G(seek_ex) = EG(current_execute_data);
+ PHPDBG_G(seek_ex) = ex;
do {
switch (opline->opcode) {
case ZEND_RETURN:
@@ -588,7 +590,7 @@ PHPDBG_COMMAND(finish) /* {{{ */
}
phpdbg_seek_to_end();
- if (zend_hash_index_exists(&PHPDBG_G(seek), (zend_ulong) EG(current_execute_data)->opline)) {
+ if (zend_hash_index_exists(&PHPDBG_G(seek), (zend_ulong) phpdbg_user_execute_data(EG(current_execute_data))->opline)) {
zend_hash_clean(&PHPDBG_G(seek));
} else {
PHPDBG_G(flags) |= PHPDBG_IN_FINISH;
@@ -605,7 +607,7 @@ PHPDBG_COMMAND(leave) /* {{{ */
}
phpdbg_seek_to_end();
- if (zend_hash_index_exists(&PHPDBG_G(seek), (zend_ulong) EG(current_execute_data)->opline)) {
+ if (zend_hash_index_exists(&PHPDBG_G(seek), (zend_ulong) phpdbg_user_execute_data(EG(current_execute_data))->opline)) {
zend_hash_clean(&PHPDBG_G(seek));
phpdbg_notice("leave", "type=\"end\"", "Already at the end of the function");
return SUCCESS;
diff --git a/sapi/phpdbg/phpdbg_utils.h b/sapi/phpdbg/phpdbg_utils.h
index 2bd4f35d71..4ba756139b 100644
--- a/sapi/phpdbg/phpdbg_utils.h
+++ b/sapi/phpdbg/phpdbg_utils.h
@@ -99,6 +99,14 @@ char *phpdbg_short_zval_print(zval *zv, int maxlen);
PHPDBG_API zend_bool phpdbg_check_caught_ex(zend_execute_data *ex, zend_object *exception);
+static zend_always_inline zend_execute_data *phpdbg_user_execute_data(zend_execute_data *ex) {
+ while (!ex->func || !ZEND_USER_CODE(ex->func->common.type)) {
+ ex = ex->prev_execute_data;
+ ZEND_ASSERT(ex);
+ }
+ return ex;
+}
+
#ifdef ZTS
#define PHPDBG_OUTPUT_BACKUP_DEFINES() \
zend_output_globals *output_globals_ptr; \