com php-src: Fix crash when advancing inside an internal function: NEWS sapi/phpdbg/phpdbg_bp.c sapi/phpdbg/phpdbg_print.c
sapi/phpdbg/phpdbg_prompt.c sapi/phpdbg/phpdbg_utils. h
| From: | Bob Weinand | Date: | Wed, 17 Feb 2016 19:27:46 +0000 |
| Subject: | com php-src: Fix crash when advancing inside an internal function: NEWS sapi/phpdbg/phpdbg_bp.c sapi/phpdbg/phpdbg_print.c sapi/phpdbg/phpdbg_prompt.c sapi/phpdbg/phpdbg_utils. h |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-91078@lists.php.net to get a copy of this message | ||
Commit: 055b4112188cccdc250790ab063479d2922f5fda
Author: Bob Weinand <bobwei9@hotmail.com> Wed, 17 Feb 2016 20:26:47 +0100
Parents: d2287529396539fd2cba6f449ae9679cac64c3b9
Branches: PHP-7.0
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=055b4112188cccdc250790ab063479d2922f5fda
Log:
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
Changed paths:
M NEWS
M sapi/phpdbg/phpdbg_bp.c
M sapi/phpdbg/phpdbg_print.c
M sapi/phpdbg/phpdbg_prompt.c
M sapi/phpdbg/phpdbg_utils.h
Diff:
diff --git a/NEWS b/NEWS
index 60c7574..9d3ddf4 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 eac67d4..5436bda 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 abfad02..00209cb 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 0314442..558ca46 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 2bd4f35..4ba7561 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; \