diff options
-rw-r--r-- | sapi/phpdbg/phpdbg.c | 18 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_frame.c | 7 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_list.c | 14 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_prompt.c | 18 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_utils.h | 25 |
5 files changed, 74 insertions, 8 deletions
diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c index d70e512751..3de0cc4524 100644 --- a/sapi/phpdbg/phpdbg.c +++ b/sapi/phpdbg/phpdbg.c @@ -469,13 +469,11 @@ static void php_sapi_phpdbg_log_message(char *message TSRMLS_DC) /* {{{ */ case E_COMPILE_ERROR: case E_USER_ERROR: case E_PARSE: - case E_RECOVERABLE_ERROR: - if (!(PHPDBG_G(flags) & PHPDBG_IN_EVAL)) { - const char *file_char = zend_get_executed_filename(TSRMLS_C); - zend_string *file = zend_string_init(file_char, strlen(file_char), 0); - phpdbg_list_file(file, 3, zend_get_executed_lineno(TSRMLS_C) - 1, zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC); - efree(file); - } + case E_RECOVERABLE_ERROR: { + const char *file_char = zend_get_executed_filename(TSRMLS_C); + zend_string *file = zend_string_init(file_char, strlen(file_char), 0); + phpdbg_list_file(file, 3, zend_get_executed_lineno(TSRMLS_C) - 1, zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC); + efree(file); do { switch (phpdbg_interactive(1 TSRMLS_CC)) { @@ -486,6 +484,7 @@ static void php_sapi_phpdbg_log_message(char *message TSRMLS_DC) /* {{{ */ return; } } while (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)); + } } } else fprintf(stdout, "%s\n", message); @@ -1521,6 +1520,11 @@ phpdbg_out: efree(SG(request_info).argv); } +#ifndef _WIN32 + /* reset it... else we risk a stack overflow upon next run (when clean'ing) */ + php_stream_stdio_ops.write = PHPDBG_G(php_stdiop_write); +#endif + #ifndef ZTS /* force cleanup of auto and core globals */ zend_hash_clean(CG(auto_globals)); diff --git a/sapi/phpdbg/phpdbg_frame.c b/sapi/phpdbg/phpdbg_frame.c index 4429a7fb73..08a6bec994 100644 --- a/sapi/phpdbg/phpdbg_frame.c +++ b/sapi/phpdbg/phpdbg_frame.c @@ -25,6 +25,7 @@ #include "phpdbg_list.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +ZEND_EXTERN_MODULE_GLOBALS(output); void phpdbg_restore_frame(TSRMLS_D) /* {{{ */ { @@ -174,8 +175,12 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ zval *file, *line; int i = 0, limit = num; + PHPDBG_OUTPUT_BACKUP(); + if (limit < 0) { phpdbg_error("backtrace", "type=\"minnum\"", "Invalid backtrace size %d", limit); + + PHPDBG_OUTPUT_BACKUP_RESTORE(); return; } @@ -218,4 +223,6 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */ phpdbg_xml("</backtrace>"); zval_dtor(&zbacktrace); + + PHPDBG_OUTPUT_BACKUP_RESTORE(); } /* }}} */ diff --git a/sapi/phpdbg/phpdbg_list.c b/sapi/phpdbg/phpdbg_list.c index de03a3651e..dd3db355fe 100644 --- a/sapi/phpdbg/phpdbg_list.c +++ b/sapi/phpdbg/phpdbg_list.c @@ -126,8 +126,16 @@ void phpdbg_list_file(zend_string *filename, uint count, int offset, uint highli { uint line, lastline; phpdbg_file_source *data; + char resolved_path_buf[MAXPATHLEN]; + const char *abspath; - if (!(data = zend_hash_find_ptr(&PHPDBG_G(file_sources), filename))) { + if (VCWD_REALPATH(filename->val, resolved_path_buf)) { + abspath = resolved_path_buf; + } else { + abspath = filename->val; + } + + if (!(data = zend_hash_str_find_ptr(&PHPDBG_G(file_sources), abspath, strlen(abspath)))) { phpdbg_error("list", "type=\"unknownfile\"", "Could not find information about included file..."); return; } @@ -230,6 +238,7 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type TSRMLS_DC) { char *filename = (char *)(file->opened_path ? file->opened_path : file->filename); uint line; char *bufptr, *endptr; + char resolved_path_buf[MAXPATHLEN]; zend_stream_fixup(file, &data.buf, &data.len TSRMLS_CC); @@ -256,6 +265,9 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type TSRMLS_DC) { fake.opened_path = file->opened_path; *(dataptr = emalloc(sizeof(phpdbg_file_source) + sizeof(uint) * data.len)) = data; + if (VCWD_REALPATH(filename, resolved_path_buf)) { + filename = resolved_path_buf; + } for (line = 0, bufptr = data.buf - 1, endptr = data.buf + data.len; ++bufptr < endptr;) { if (*bufptr == '\n') { diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index 190907e687..f1b1db12fc 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -43,6 +43,7 @@ #include "phpdbg_eol.h" ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +ZEND_EXTERN_MODULE_GLOBALS(output); #ifdef HAVE_LIBDL #ifdef PHP_WIN32 @@ -645,12 +646,21 @@ PHPDBG_COMMAND(ev) /* {{{ */ zend_bool stepping = ((PHPDBG_G(flags) & PHPDBG_IS_STEPPING) == PHPDBG_IS_STEPPING); 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); + original_stack->top = EG(vm_stack_top); + + PHPDBG_OUTPUT_BACKUP(); + if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) { phpdbg_try_access { phpdbg_parse_variable(param->str, param->len, &EG(symbol_table).ht, 0, phpdbg_output_ev_variable, 0 TSRMLS_CC); } phpdbg_catch_access { phpdbg_error("signalsegv", "", "Could not fetch data, invalid data source"); } phpdbg_end_try_access(); + + PHPDBG_OUTPUT_BACKUP_RESTORE(); return SUCCESS; } @@ -672,6 +682,12 @@ PHPDBG_COMMAND(ev) /* {{{ */ phpdbg_out("\n"); zval_ptr_dtor(&retval); } + } zend_catch { + 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; } zend_end_try(); PHPDBG_G(flags) &= ~PHPDBG_IN_EVAL; @@ -682,6 +698,8 @@ PHPDBG_COMMAND(ev) /* {{{ */ CG(unclean_shutdown) = 0; + PHPDBG_OUTPUT_BACKUP_RESTORE(); + return SUCCESS; } /* }}} */ diff --git a/sapi/phpdbg/phpdbg_utils.h b/sapi/phpdbg/phpdbg_utils.h index 83dc8e9694..feb5470b69 100644 --- a/sapi/phpdbg/phpdbg_utils.h +++ b/sapi/phpdbg/phpdbg_utils.h @@ -94,4 +94,29 @@ int phpdbg_is_auto_global(char *name, int len TSRMLS_DC); PHPDBG_API void phpdbg_xml_var_dump(zval *zv TSRMLS_DC); +#ifdef ZTS +#define PHPDBG_OUTPUT_BACKUP_DEFINES() \ + zend_output_globals *output_globals_ptr; \ + zend_output_globals original_output_globals; \ + output_globals_ptr = (zend_output_globals *) (*((void ***) tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(output_globals_id)]; +#else +#define PHPDBG_OUTPUT_BACKUP_DEFINES() \ + zend_output_globals *output_globals_ptr; \ + zend_output_globals original_output_globals; \ + output_globals_ptr = &output_globals; +#endif + +#define PHPDBG_OUTPUT_BACKUP_SWAP() \ + original_output_globals = *output_globals_ptr; \ + memset(output_globals_ptr, 0, sizeof(zend_output_globals)); \ + php_output_activate(TSRMLS_C); + +#define PHPDBG_OUTPUT_BACKUP() \ + PHPDBG_OUTPUT_BACKUP_DEFINES() \ + PHPDBG_OUTPUT_BACKUP_SWAP() + +#define PHPDBG_OUTPUT_BACKUP_RESTORE() \ + php_output_deactivate(TSRMLS_C); \ + *output_globals_ptr = original_output_globals; + #endif /* PHPDBG_UTILS_H */ |