From 5e16722309354a9750ea68e6951fb25a23158923 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Mon, 29 Jun 2015 01:41:04 +0200 Subject: [PATCH] Show exception source in phpdbg --- Zend/zend_exceptions.c | 23 ++++++++++++++--------- Zend/zend_exceptions.h | 1 + sapi/phpdbg/phpdbg_prompt.c | 11 ++++++++++- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index f157abb155..4140303332 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -55,11 +55,16 @@ static int zend_implement_throwable(zend_class_entry *interface, zend_class_entr } /* }}} */ -static inline zend_class_entry *zend_get_exception_base(zval *object) +static inline zend_class_entry *i_get_exception_base(zval *object) { return instanceof_function(Z_OBJCE_P(object), default_exception_ce) ? default_exception_ce : error_ce; } +ZEND_API zend_class_entry *zend_get_exception_base(zval *object) +{ + return i_get_exception_base(object); +} + void zend_exception_set_previous(zend_object *exception, zend_object *add_previous) { zval tmp, *previous, zv, *pzv, rv; @@ -76,7 +81,7 @@ void zend_exception_set_previous(zend_object *exception, zend_object *add_previo ZVAL_OBJ(&zv, exception); pzv = &zv; do { - base_ce = zend_get_exception_base(pzv); + base_ce = i_get_exception_base(pzv); previous = zend_read_property(base_ce, pzv, "previous", sizeof("previous")-1, 1, &rv); if (Z_TYPE_P(previous) == IS_NULL) { zend_update_property(base_ce, pzv, "previous", sizeof("previous")-1, &tmp); @@ -196,7 +201,7 @@ static zend_object *zend_default_exception_new_ex(zend_class_entry *class_type, } Z_SET_REFCOUNT(trace, 0); - base_ce = zend_get_exception_base(&obj); + base_ce = i_get_exception_base(&obj); if (EXPECTED(class_type != parse_error_ce || !(filename = zend_get_compiled_filename()))) { zend_update_property_string(base_ce, &obj, "file", sizeof("file")-1, zend_get_executed_filename()); @@ -243,7 +248,7 @@ ZEND_METHOD(exception, __construct) int argc = ZEND_NUM_ARGS(); object = getThis(); - base_ce = zend_get_exception_base(object); + base_ce = i_get_exception_base(object); if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, argc, "|SlO!", &message, &code, &previous, zend_ce_throwable) == FAILURE) { zend_class_entry *ce; @@ -325,9 +330,9 @@ ZEND_METHOD(error_exception, __construct) } #define GET_PROPERTY(object, name) \ - zend_read_property(zend_get_exception_base(object), (object), name, sizeof(name) - 1, 0, &rv) + zend_read_property(i_get_exception_base(object), (object), name, sizeof(name) - 1, 0, &rv) #define GET_PROPERTY_SILENT(object, name) \ - zend_read_property(zend_get_exception_base(object), (object), name, sizeof(name) - 1, 1, &rv) + zend_read_property(i_get_exception_base(object), (object), name, sizeof(name) - 1, 1, &rv) /* {{{ proto string Exception|Error::getFile() Get the file in which the exception occurred */ @@ -602,7 +607,7 @@ ZEND_METHOD(exception, getTraceAsString) DEFAULT_0_PARAMS; object = getThis(); - base_ce = zend_get_exception_base(object); + base_ce = i_get_exception_base(object); trace = zend_read_property(base_ce, object, "trace", sizeof("trace")-1, 1, &rv); if (Z_TYPE_P(trace) != IS_ARRAY) { @@ -731,7 +736,7 @@ ZEND_METHOD(exception, __toString) zval_dtor(&fname); exception = getThis(); - base_ce = zend_get_exception_base(exception); + base_ce = i_get_exception_base(exception); /* We store the result in the private property string so we can access * the result in uncaught exception handlers without memleaks. */ @@ -982,7 +987,7 @@ ZEND_API void zend_exception_error(zend_object *ex, int severity) /* {{{ */ if (Z_TYPE(tmp) != IS_STRING) { zend_error(E_WARNING, "%s::__toString() must return a string", ce_exception->name->val); } else { - zend_update_property_string(zend_get_exception_base(&exception), &exception, "string", sizeof("string")-1, EG(exception) ? ce_exception->name->val : Z_STRVAL(tmp)); + zend_update_property_string(i_get_exception_base(&exception), &exception, "string", sizeof("string")-1, EG(exception) ? ce_exception->name->val : Z_STRVAL(tmp)); } } zval_ptr_dtor(&tmp); diff --git a/Zend/zend_exceptions.h b/Zend/zend_exceptions.h index d22b99c262..944fe555ce 100644 --- a/Zend/zend_exceptions.h +++ b/Zend/zend_exceptions.h @@ -36,6 +36,7 @@ ZEND_API void zend_throw_exception_internal(zval *exception); void zend_register_default_exception(void); +ZEND_API zend_class_entry *zend_get_exception_base(zval *object); ZEND_API zend_class_entry *zend_exception_get_default(void); ZEND_API zend_class_entry *zend_get_error_exception(void); ZEND_API zend_class_entry *zend_get_error(void); diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index 3b1ec1f19a..fc63c32fa3 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -1443,6 +1443,9 @@ void phpdbg_execute_ex(zend_execute_data *execute_data) /* {{{ */ /* check for uncaught exceptions */ if (exception && PHPDBG_G(handled_exception) != exception) { zend_execute_data *prev_ex = execute_data; + zval zv, rv; + zend_string *file; + zend_long line; do { prev_ex = zend_generator_check_placeholder_frame(prev_ex); @@ -1457,7 +1460,13 @@ void phpdbg_execute_ex(zend_execute_data *execute_data) /* {{{ */ } while ((prev_ex = prev_ex->prev_execute_data)); PHPDBG_G(handled_exception) = exception; - phpdbg_error("exception", "name=\"%s\"", "Uncaught exception %s", exception->ce->name->val); + + ZVAL_OBJ(&zv, exception); + file = zval_get_string(zend_read_property(zend_get_exception_base(&zv), &zv, ZEND_STRL("file"), 1, &rv)); + line = zval_get_long(zend_read_property(zend_get_exception_base(&zv), &zv, ZEND_STRL("line"), 1, &rv)); + + phpdbg_error("exception", "name=\"%s\" file=\"%s\" line=\"%lld\"", "Uncaught exception %s in %s on line %lld", exception->ce->name->val, file->val, line); + zend_string_release(file); DO_INTERACTIVE(1); } ex_is_caught: -- 2.40.0