diff options
author | Bob Weinand <bobwei9@hotmail.com> | 2014-10-27 00:34:56 +0100 |
---|---|---|
committer | Bob Weinand <bobwei9@hotmail.com> | 2014-10-27 00:34:56 +0100 |
commit | 09da8952d0434b53e740ffaca66a8051cd39cf93 (patch) | |
tree | 0c1c1ed2aaef8eee971575eb5e336631295f4951 | |
parent | 9e62255c6264e3ead2b08e0fdbf5ac4d252d30bf (diff) | |
parent | 50756b515c76bb9c43a01bfce03207906f596005 (diff) | |
download | php-git-09da8952d0434b53e740ffaca66a8051cd39cf93.tar.gz |
Merge remote-tracking branch 'origin/PHP-5.6'
Conflicts:
sapi/phpdbg/phpdbg.c
sapi/phpdbg/phpdbg_bp.c
sapi/phpdbg/phpdbg_list.c
sapi/phpdbg/phpdbg_parser.c
sapi/phpdbg/phpdbg_parser.h
sapi/phpdbg/phpdbg_prompt.c
-rw-r--r-- | sapi/phpdbg/phpdbg.c | 176 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg.h | 101 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_bp.c | 131 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_bp.h | 26 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_cmd.c | 82 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_cmd.h | 1 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_io.c | 53 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_io.h | 2 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_list.c | 1 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_out.c | 2 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_parser.c | 250 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_parser.h | 18 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_prompt.c | 144 | ||||
-rw-r--r-- | sapi/phpdbg/tests/commands/0104_clean.test | 1 |
14 files changed, 571 insertions, 417 deletions
diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c index 052ead7d0b..299216fcff 100644 --- a/sapi/phpdbg/phpdbg.c +++ b/sapi/phpdbg/phpdbg.c @@ -45,6 +45,7 @@ #endif /* }}} */ ZEND_DECLARE_MODULE_GLOBALS(phpdbg); +int phpdbg_startup_run = 0; static PHP_INI_MH(OnUpdateEol) { @@ -184,7 +185,8 @@ static void php_phpdbg_destroy_registered(zval *data) /* {{{ */ static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */ { - zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], 8, NULL, php_phpdbg_destroy_bp_file, 0); + zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], 8, NULL, php_phpdbg_destroy_bp_file, 0); + zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], 8, NULL, php_phpdbg_destroy_bp_file, 0); zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], 8, NULL, php_phpdbg_destroy_bp_symbol, 0); zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], 8, NULL, php_phpdbg_destroy_bp_methods, 0); zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], 8, NULL, php_phpdbg_destroy_bp_methods, 0); @@ -214,8 +216,8 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */ zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]); zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]); zend_hash_destroy(&PHPDBG_G(seek)); - zend_hash_destroy(&PHPDBG_G(registered)); zend_hash_destroy(&PHPDBG_G(file_sources)); + zend_hash_destroy(&PHPDBG_G(registered)); zend_hash_destroy(&PHPDBG_G(watchpoints)); zend_llist_destroy(&PHPDBG_G(watchlist_mem)); @@ -301,9 +303,9 @@ static PHP_FUNCTION(phpdbg_exec) instructs phpdbg to insert a breakpoint at the next opcode */ static PHP_FUNCTION(phpdbg_break_next) { - if (zend_parse_parameters_none() == FAILURE) { - return; - } + if (zend_parse_parameters_none() == FAILURE && EG(current_execute_data)) { + return; + } phpdbg_set_breakpoint_opline_ex((phpdbg_opline_ptr_t) EG(current_execute_data)->opline + 1 TSRMLS_CC); } /* }}} */ @@ -312,8 +314,8 @@ static PHP_FUNCTION(phpdbg_break_next) static PHP_FUNCTION(phpdbg_break_file) { char *file = NULL; - size_t flen = 0; - long line; + size_t flen = 0; + long line; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &file, &flen, &line) == FAILURE) { return; @@ -325,10 +327,8 @@ static PHP_FUNCTION(phpdbg_break_file) /* {{{ proto void phpdbg_break_method(string class, string method) */ static PHP_FUNCTION(phpdbg_break_method) { - char *class = NULL, - *method = NULL; - size_t clen = 0, - mlen = 0; + char *class = NULL, *method = NULL; + size_t clen = 0, mlen = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &class, &clen, &method, &mlen) == FAILURE) { return; @@ -355,6 +355,7 @@ static PHP_FUNCTION(phpdbg_break_function) static PHP_FUNCTION(phpdbg_clear) { zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE]); + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING]); zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM]); zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE]); zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE]); @@ -529,21 +530,38 @@ static void php_sapi_phpdbg_log_message(char *message TSRMLS_DC) /* {{{ */ case PHPDBG_NEXT: return; } - } while (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)); + } while (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)); } - } - } else fprintf(stdout, "%s\n", message); + } else { + fprintf(stdout, "%s\n", message); + } } /* }}} */ static int php_sapi_phpdbg_deactivate(TSRMLS_D) /* {{{ */ { + if ((PHPDBG_G(flags) & PHPDBG_IS_STOPPING) == PHPDBG_IS_CLEANING) { + zend_phpdbg_globals *pg = PHPDBG_G(backup) = calloc(1, sizeof(zend_phpdbg_globals)); + + php_phpdbg_globals_ctor(pg); + + pg->exec = strndup(PHPDBG_G(exec), PHPDBG_G(exec_len)); + pg->exec_len = PHPDBG_G(exec_len); + pg->oplog = PHPDBG_G(oplog); + pg->prompt[0] = PHPDBG_G(prompt)[0]; + pg->prompt[1] = PHPDBG_G(prompt)[1]; + memcpy(pg->colors, PHPDBG_G(colors), sizeof(pg->colors)); + pg->eol = PHPDBG_G(eol); + pg->flags = PHPDBG_G(flags) & PHPDBG_PRESERVE_FLAGS_MASK; + } + fflush(stdout); if(SG(request_info).argv0) { free(SG(request_info).argv0); SG(request_info).argv0 = NULL; } + return SUCCESS; } /* }}} */ @@ -774,7 +792,7 @@ static void phpdbg_welcome(zend_bool cleaning TSRMLS_DC) /* {{{ */ phpdbg_writeln("intro", "help=\"help\"", "To get help using phpdbg type \"help\" and press enter"); phpdbg_notice("intro", "report=\"%s\"", "Please report bugs to <%s>", PHPDBG_ISSUES); phpdbg_xml("</intros>"); - } else { + } else if (phpdbg_startup_run == 0) { if (!(PHPDBG_G(flags) & PHPDBG_WRITE_XML)) { phpdbg_notice(NULL, NULL, "Clean Execution Environment"); } @@ -798,7 +816,7 @@ static inline void phpdbg_sigint_handler(int signo) /* {{{ */ if (PHPDBG_G(flags) & PHPDBG_IS_INTERACTIVE) { /* we quit remote consoles on recv SIGINT */ if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) { - PHPDBG_G(flags) |= PHPDBG_IS_QUITTING; + PHPDBG_G(flags) |= PHPDBG_IS_STOPPING; zend_bailout(); } } else { @@ -982,8 +1000,7 @@ int main(int argc, char **argv) /* {{{ */ zend_ulong zend_extensions_len = 0L; zend_bool ini_ignore; char *ini_override; - char *exec; - size_t exec_len; + char *exec = NULL; char *init_file; size_t init_file_len; zend_bool init_file_default; @@ -992,10 +1009,10 @@ int main(int argc, char **argv) /* {{{ */ zend_ulong flags; char *php_optarg; int php_optind, opt, show_banner = 1; - long cleaning = 0; + long cleaning = -1; zend_bool remote = 0; - int run = 0; int step = 0; + zend_phpdbg_globals *settings = NULL; #ifdef _WIN32 char *bp_tmp_file = NULL; @@ -1070,8 +1087,6 @@ phpdbg_main: ini_override = NULL; zend_extensions = NULL; zend_extensions_len = 0L; - exec = NULL; - exec_len = 0; init_file = NULL; init_file_len = 0; init_file_default = 1; @@ -1081,14 +1096,16 @@ phpdbg_main: php_optarg = NULL; php_optind = 1; opt = 0; - run = 0; step = 0; sapi_name = NULL; + if (settings) { + exec = settings->exec; + } while ((opt = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) { switch (opt) { case 'r': - run++; + phpdbg_startup_run++; break; case 'n': ini_ignore = 1; @@ -1227,10 +1244,8 @@ phpdbg_main: } /* set exec if present on command line */ - if ((argc > php_optind) && (strcmp(argv[php_optind-1],"--") != SUCCESS)) - { - exec_len = strlen(argv[php_optind]); - if (exec_len) { + if (!exec && (argc > php_optind) && (strcmp(argv[php_optind-1], "--") != SUCCESS)) { + if (strlen(argv[php_optind])) { if (exec) { free(exec); } @@ -1298,21 +1313,32 @@ phpdbg_main: void (*_free)(void*); void* (*_realloc)(void*, size_t); -#ifndef _WIN32 - /* setup remote server if necessary */ - if (!cleaning && listen > 0) { - server = phpdbg_open_socket(address, listen TSRMLS_CC); - if (-1 > server || phpdbg_remote_init(address, listen, server, &socket, &stream TSRMLS_CC) == FAILURE) { - exit(0); + /* set flags from command line */ + PHPDBG_G(flags) = flags; + + if (settings) { +#ifdef ZTS + *((zend_phpdbg_globals *) (*((void ***) tsrm_ls))[TSRM_UNSHUFFLE_RSRC_ID(phpdbg_globals_id)]) = *settings; +#else + phpdbg_globals = *settings; +#endif } - sigaction(SIGIO, &sigio_struct, NULL); + /* setup remote server if necessary */ + if (!cleaning && listen > 0) { + server = phpdbg_open_socket(address, listen TSRMLS_CC); + if (-1 > server || phpdbg_remote_init(address, listen, server, &socket, &stream TSRMLS_CC) == FAILURE) { + exit(0); + } - /* set remote flag to stop service shutting down upon quit */ - remote = 1; - } +#ifndef _WIN32 + sigaction(SIGIO, &sigio_struct, NULL); #endif + /* set remote flag to stop service shutting down upon quit */ + remote = 1; + } + mm_heap = phpdbg_mm_get_heap(); zend_mm_get_custom_handlers(mm_heap, &_malloc, &_free, &_realloc); @@ -1366,7 +1392,7 @@ phpdbg_main: for (i = SG(request_info).argc; --i;) { SG(request_info).argv[i] = estrdup(argv[php_optind - 1 + i]); } - SG(request_info).argv[i] = exec ? estrndup(exec, exec_len) : estrdup(""); + SG(request_info).argv[i] = exec ? estrdup(exec) : estrdup(""); php_hash_environment(TSRMLS_C); } @@ -1387,9 +1413,6 @@ phpdbg_main: PG(modules_activated) = 0; - /* set flags from command line */ - PHPDBG_G(flags) = flags; - #ifndef _WIN32 /* setup io here */ if (remote) { @@ -1435,6 +1458,7 @@ phpdbg_main: PHPDBG_G(exec_len) = strlen(PHPDBG_G(exec)); free(exec); + exec = NULL; } if (oplog_file) { /* open oplog */ @@ -1456,21 +1480,20 @@ phpdbg_main: /* Make stdin, stdout and stderr accessible from PHP scripts */ phpdbg_register_file_handles(TSRMLS_C); - if (show_banner) { + if (show_banner && cleaning < 2) { /* print blurb */ - phpdbg_welcome((cleaning > 0) TSRMLS_CC); + phpdbg_welcome(cleaning == 1 TSRMLS_CC); } - /* auto compile */ - if (PHPDBG_G(exec)) { - phpdbg_compile(TSRMLS_C); - } + cleaning = -1; /* initialize from file */ PHPDBG_G(flags) |= PHPDBG_IS_INITIALIZING; zend_try { phpdbg_init(init_file, init_file_len, init_file_default TSRMLS_CC); + PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT; phpdbg_try_file_init(bp_tmp_file, strlen(bp_tmp_file), 0 TSRMLS_CC); + PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT; } zend_end_try(); PHPDBG_G(flags) &= ~PHPDBG_IS_INITIALIZING; @@ -1479,18 +1502,29 @@ phpdbg_main: goto phpdbg_out; } + /* auto compile */ + if (PHPDBG_G(exec)) { + if (settings) { + PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT; + } + phpdbg_compile(TSRMLS_C); + PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT; + } + /* step from here, not through init */ if (step) { PHPDBG_G(flags) |= PHPDBG_IS_STEPPING; } - if (run) { - /* no need to try{}, run does it ... */ - PHPDBG_COMMAND_HANDLER(run)(NULL TSRMLS_CC); - if (run > 1) { + if (phpdbg_startup_run) { + zend_try { + PHPDBG_COMMAND_HANDLER(run)(NULL TSRMLS_CC); + } zend_end_try(); + if (phpdbg_startup_run > 1) { /* if -r is on the command line more than once just quit */ goto phpdbg_out; } + phpdbg_startup_run = 0; } /* #ifndef for making compiler shutting up */ @@ -1504,7 +1538,9 @@ phpdbg_interact: } zend_catch { if ((PHPDBG_G(flags) & PHPDBG_IS_CLEANING)) { FILE *bp_tmp_fp = fopen(bp_tmp_file, "w"); + PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT; phpdbg_export_breakpoints(bp_tmp_fp TSRMLS_CC); + PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT; fclose(bp_tmp_fp); cleaning = 1; } else { @@ -1535,8 +1571,13 @@ phpdbg_interact: } #endif } zend_end_try(); - } while(!cleaning && !(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)); - + } while (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)); + + + if (PHPDBG_G(exec) && (PHPDBG_G(flags) & PHPDBG_IS_CLEANING)) { + exec = strdup(PHPDBG_G(exec)); /* preserve exec, don't reparse that from cmd */ + } + /* this must be forced */ CG(unclean_shutdown) = 0; @@ -1558,6 +1599,11 @@ phpdbg_out: phpdbg_out: #endif + if (cleaning <= 0) { + PHPDBG_G(flags) &= ~PHPDBG_IS_CLEANING; + cleaning = -1; + } + { int i; /* free argv */ @@ -1591,7 +1637,25 @@ phpdbg_out: /* this is just helpful */ PG(report_memleaks) = 0; - php_request_shutdown((void*)0); + if ((PHPDBG_G(flags) & (PHPDBG_IS_CLEANING | PHPDBG_IS_RUNNING)) == PHPDBG_IS_CLEANING) { + php_free_shutdown_functions(TSRMLS_C); + zend_objects_store_mark_destructed(&EG(objects_store) TSRMLS_CC); + } + + /* sapi_module.deactivate is where to backup things, last chance before mm_shutdown... */ + + zend_try { + php_request_shutdown(NULL); + } zend_end_try(); + + if ((PHPDBG_G(flags) & (PHPDBG_IS_QUITTING | PHPDBG_IS_RUNNING)) == PHPDBG_IS_RUNNING) { + phpdbg_notice("stop", "type=\"normal\"", "Script ended normally"); + cleaning++; + } + + if ((PHPDBG_G(flags) & PHPDBG_IS_STOPPING) == PHPDBG_IS_CLEANING) { + settings = PHPDBG_G(backup); + } php_output_deactivate(TSRMLS_C); @@ -1603,7 +1667,7 @@ phpdbg_out: } - if (cleaning || remote) { + if (cleaning > 0 || remote) { goto phpdbg_main; } diff --git a/sapi/phpdbg/phpdbg.h b/sapi/phpdbg/phpdbg.h index f3e8ba3107..60bc31a405 100644 --- a/sapi/phpdbg/phpdbg.h +++ b/sapi/phpdbg/phpdbg.h @@ -139,6 +139,7 @@ static zend_always_inline void *zend_hash_index_add_mem(HashTable *ht, zend_ulon #include "phpdbg_utils.h" #include "phpdbg_btree.h" #include "phpdbg_watch.h" +#include "phpdbg_bp.h" #ifdef PHP_WIN32 # include "phpdbg_sigio_win32.h" #endif @@ -154,70 +155,64 @@ int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC); BEGIN: DO NOT CHANGE DO NOT CHANGE DO NOT CHANGE */ -/* {{{ tables */ -#define PHPDBG_BREAK_FILE 0 -#define PHPDBG_BREAK_SYM 1 -#define PHPDBG_BREAK_OPLINE 2 -#define PHPDBG_BREAK_METHOD 3 -#define PHPDBG_BREAK_COND 4 -#define PHPDBG_BREAK_OPCODE 5 -#define PHPDBG_BREAK_FUNCTION_OPLINE 6 -#define PHPDBG_BREAK_METHOD_OPLINE 7 -#define PHPDBG_BREAK_FILE_OPLINE 8 -#define PHPDBG_BREAK_MAP 9 -#define PHPDBG_BREAK_TABLES 10 /* }}} */ - /* {{{ flags */ -#define PHPDBG_HAS_FILE_BP (1<<1) -#define PHPDBG_HAS_SYM_BP (1<<2) -#define PHPDBG_HAS_OPLINE_BP (1<<3) -#define PHPDBG_HAS_METHOD_BP (1<<4) -#define PHPDBG_HAS_COND_BP (1<<5) -#define PHPDBG_HAS_OPCODE_BP (1<<6) -#define PHPDBG_HAS_FUNCTION_OPLINE_BP (1<<7) -#define PHPDBG_HAS_METHOD_OPLINE_BP (1<<8) -#define PHPDBG_HAS_FILE_OPLINE_BP (1<<9) /* }}} */ +#define PHPDBG_HAS_FILE_BP (1ULL<<1) +#define PHPDBG_HAS_PENDING_FILE_BP (1ULL<<2) +#define PHPDBG_HAS_SYM_BP (1ULL<<3) +#define PHPDBG_HAS_OPLINE_BP (1ULL<<4) +#define PHPDBG_HAS_METHOD_BP (1ULL<<5) +#define PHPDBG_HAS_COND_BP (1ULL<<6) +#define PHPDBG_HAS_OPCODE_BP (1ULL<<7) +#define PHPDBG_HAS_FUNCTION_OPLINE_BP (1ULL<<8) +#define PHPDBG_HAS_METHOD_OPLINE_BP (1ULL<<9) +#define PHPDBG_HAS_FILE_OPLINE_BP (1ULL<<10) /* }}} */ /* END: DO NOT CHANGE DO NOT CHANGE DO NOT CHANGE */ -#define PHPDBG_IN_COND_BP (1<<10) -#define PHPDBG_IN_EVAL (1<<11) +#define PHPDBG_IN_COND_BP (1ULL<<11) +#define PHPDBG_IN_EVAL (1ULL<<12) + +#define PHPDBG_IS_STEPPING (1ULL<<13) +#define PHPDBG_STEP_OPCODE (1ULL<<14) +#define PHPDBG_IS_QUIET (1ULL<<15) +#define PHPDBG_IS_QUITTING (1ULL<<16) +#define PHPDBG_IS_COLOURED (1ULL<<17) +#define PHPDBG_IS_CLEANING (1ULL<<18) +#define PHPDBG_IS_RUNNING (1ULL<<19) -#define PHPDBG_IS_STEPPING (1<<12) -#define PHPDBG_STEP_OPCODE (1<<13) -#define PHPDBG_IS_QUIET (1<<14) -#define PHPDBG_IS_QUITTING (1<<15) -#define PHPDBG_IS_COLOURED (1<<16) -#define PHPDBG_IS_CLEANING (1<<17) +#define PHPDBG_IN_UNTIL (1ULL<<20) +#define PHPDBG_IN_FINISH (1ULL<<21) +#define PHPDBG_IN_LEAVE (1ULL<<22) -#define PHPDBG_IN_UNTIL (1<<18) -#define PHPDBG_IN_FINISH (1<<19) -#define PHPDBG_IN_LEAVE (1<<20) +#define PHPDBG_IS_REGISTERED (1ULL<<23) +#define PHPDBG_IS_STEPONEVAL (1ULL<<24) +#define PHPDBG_IS_INITIALIZING (1ULL<<25) +#define PHPDBG_IS_SIGNALED (1ULL<<26) +#define PHPDBG_IS_INTERACTIVE (1ULL<<27) +#define PHPDBG_IS_BP_ENABLED (1ULL<<28) +#define PHPDBG_IS_REMOTE (1ULL<<29) +#define PHPDBG_IS_DISCONNECTED (1ULL<<30) +#define PHPDBG_WRITE_XML (1ULL<<31) -#define PHPDBG_IS_REGISTERED (1<<21) -#define PHPDBG_IS_STEPONEVAL (1<<22) -#define PHPDBG_IS_INITIALIZING (1<<23) -#define PHPDBG_IS_SIGNALED (1<<24) -#define PHPDBG_IS_INTERACTIVE (1<<25) -#define PHPDBG_IS_BP_ENABLED (1<<26) -#define PHPDBG_IS_REMOTE (1<<27) -#define PHPDBG_IS_DISCONNECTED (1<<28) -#define PHPDBG_WRITE_XML (1<<29) +#define PHPDBG_SHOW_REFCOUNTS (1ULL<<32) -#define PHPDBG_SHOW_REFCOUNTS (1<<30) +#define PHPDBG_IN_SIGNAL_HANDLER (1ULL<<33) -#define PHPDBG_IN_SIGNAL_HANDLER (1<<30) +#define PHPDBG_DISCARD_OUTPUT (1ULL<<34) -#define PHPDBG_SEEK_MASK (PHPDBG_IN_UNTIL|PHPDBG_IN_FINISH|PHPDBG_IN_LEAVE) -#define PHPDBG_BP_RESOLVE_MASK (PHPDBG_HAS_FUNCTION_OPLINE_BP|PHPDBG_HAS_METHOD_OPLINE_BP|PHPDBG_HAS_FILE_OPLINE_BP) -#define PHPDBG_BP_MASK (PHPDBG_HAS_FILE_BP|PHPDBG_HAS_SYM_BP|PHPDBG_HAS_METHOD_BP|PHPDBG_HAS_OPLINE_BP|PHPDBG_HAS_COND_BP|PHPDBG_HAS_OPCODE_BP|PHPDBG_HAS_FUNCTION_OPLINE_BP|PHPDBG_HAS_METHOD_OPLINE_BP|PHPDBG_HAS_FILE_OPLINE_BP) +#define PHPDBG_SEEK_MASK (PHPDBG_IN_UNTIL | PHPDBG_IN_FINISH | PHPDBG_IN_LEAVE) +#define PHPDBG_BP_RESOLVE_MASK (PHPDBG_HAS_FUNCTION_OPLINE_BP | PHPDBG_HAS_METHOD_OPLINE_BP | PHPDBG_HAS_FILE_OPLINE_BP) +#define PHPDBG_BP_MASK (PHPDBG_HAS_FILE_BP | PHPDBG_HAS_SYM_BP | PHPDBG_HAS_METHOD_BP | PHPDBG_HAS_OPLINE_BP | PHPDBG_HAS_COND_BP | PHPDBG_HAS_OPCODE_BP | PHPDBG_HAS_FUNCTION_OPLINE_BP | PHPDBG_HAS_METHOD_OPLINE_BP | PHPDBG_HAS_FILE_OPLINE_BP) +#define PHPDBG_IS_STOPPING (PHPDBG_IS_QUITTING | PHPDBG_IS_CLEANING) + +#define PHPDBG_PRESERVE_FLAGS_MASK (PHPDBG_SHOW_REFCOUNTS | PHPDBG_IS_STEPONEVAL | PHPDBG_IS_BP_ENABLED | PHPDBG_STEP_OPCODE | PHPDBG_IS_QUIET | PHPDBG_IS_COLOURED) #ifndef _WIN32 -# define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET|PHPDBG_IS_COLOURED|PHPDBG_IS_BP_ENABLED) +# define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET | PHPDBG_IS_COLOURED | PHPDBG_IS_BP_ENABLED) #else -# define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET|PHPDBG_IS_BP_ENABLED) +# define PHPDBG_DEFAULT_FLAGS (PHPDBG_IS_QUIET | PHPDBG_IS_BP_ENABLED) #endif /* }}} */ /* {{{ output descriptors */ @@ -280,6 +275,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) FILE *ptr; int fd; } io[PHPDBG_IO_FDS]; /* io */ + int eol; /* type of line ending to use */ size_t (*php_stdiop_write)(php_stream *, const char *, size_t TSRMLS_DC); int in_script_xml; /* in <stream> output mode */ struct { @@ -305,17 +301,18 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg) JMP_BUF *sigsegv_bailout; /* bailout address for accesibility probing */ - zend_ulong flags; /* phpdbg flags */ + uint64_t flags; /* phpdbg flags */ char *socket_path; /* phpdbg.path ini setting */ char *sapi_name_ptr; /* store sapi name to free it if necessary to not leak memory */ int socket_fd; /* file descriptor to socket (wait command) (-1 if unused) */ int socket_server_fd; /* file descriptor to master socket (wait command) (-1 if unused) */ #ifdef PHP_WIN32 - HANDLE sigio_watcher_thread; /* sigio watcher thread handle */ + HANDLE sigio_watcher_thread; /* sigio watcher thread handle */ struct win32_sigio_watcher_data swd; #endif - int8_t eol; + + struct _zend_phpdbg_globals *backup; /* backup of data to store */ ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */ #endif diff --git a/sapi/phpdbg/phpdbg_bp.c b/sapi/phpdbg/phpdbg_bp.c index aaeaee13fd..f6610cd0ca 100644 --- a/sapi/phpdbg/phpdbg_bp.c +++ b/sapi/phpdbg/phpdbg_bp.c @@ -207,48 +207,111 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML { php_stream_statbuf ssb; char realpath[MAXPATHLEN]; + const char *original_path = path; + zend_bool pending; - if (php_stream_stat_path(path, &ssb) != FAILURE) { - if (ssb.sb.st_mode & (S_IFREG|S_IFLNK)) { - HashTable *broken; - phpdbg_breakfile_t new_break; - size_t path_len = 0L; + HashTable *broken, *file_breaks = &PHPDBG_G(bp)[PHPDBG_BREAK_FILE]; + phpdbg_breakfile_t new_break; + size_t path_len = 0L; - if (VCWD_REALPATH(path, realpath)) { - path = realpath; + if (VCWD_REALPATH(path, realpath)) { + path = realpath; + } + path_len = strlen(path); + + if (!zend_hash_str_exists(&PHPDBG_G(file_sources), path, path_len)) { + if (php_stream_stat_path(path, &ssb) == FAILURE) { + if (original_path[0] == '/') { + phpdbg_error("breakpoint", "type=\"nofile\" add=\"fail\" file=\"%s\"", "Cannot stat %s, it does not exist", original_path); + return; } + + file_breaks = &PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING]; + path = original_path; path_len = strlen(path); + pending = 1; + } else if (!(ssb.sb.st_mode & (S_IFREG|S_IFLNK))) { + phpdbg_error("breakpoint", "type=\"notregular\" add=\"fail\" file=\"%s\"", "Cannot set breakpoint in %s, it is not a regular file", path); + return; + } + } - if (!(broken = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], path, path_len))) { - HashTable breaks; + if (!(broken = zend_hash_str_find_ptr(file_breaks, path, path_len))) { + HashTable breaks; + zend_hash_init(&breaks, 8, NULL, phpdbg_file_breaks_dtor, 0); - zend_hash_init(&breaks, 8, NULL, phpdbg_file_breaks_dtor, 0); + broken = zend_hash_str_add_mem(file_breaks, path, path_len, &breaks, sizeof(HashTable)); + } - broken = zend_hash_str_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], path, path_len, &breaks, sizeof(HashTable)); - } + if (!zend_hash_index_exists(broken, line_num)) { + PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_FILE); + new_break.filename = estrndup(path, path_len); + new_break.line = line_num; + + zend_hash_index_update_mem(broken, line_num, &new_break, sizeof(phpdbg_breakfile_t)); - if (!zend_hash_index_exists(broken, line_num)) { - PHPDBG_G(flags) |= PHPDBG_HAS_FILE_BP; + if (pending) { + PHPDBG_G(flags) |= PHPDBG_HAS_PENDING_FILE_BP; - PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_FILE); - new_break.filename = estrndup(path, path_len); - new_break.line = line_num; + phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" file=\"%s\" line=\"%ld\" pending=\"pending\"", "Pending breakpoint #%d added at %s:%ld", new_break.id, new_break.filename, new_break.line); + } else { + PHPDBG_G(flags) |= PHPDBG_HAS_FILE_BP; - zend_hash_index_update_mem(broken, line_num, &new_break, sizeof(phpdbg_breakfile_t)); + phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" file=\"%s\" line=\"%ld\"", "Breakpoint #%d added at %s:%ld", new_break.id, new_break.filename, new_break.line); + } - phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" file=\"%s\" line=\"%ld\"", "Breakpoint #%d added at %s:%ld", new_break.id, new_break.filename, new_break.line); + PHPDBG_BREAK_MAPPING(new_break.id, broken); + } else { + phpdbg_error("breakpoint", "type=\"exists\" add=\"fail\" file=\"%s\" line=\"%ld\"", "Breakpoint at %s:%ld exists", path, line_num); + } +} /* }}} */ - PHPDBG_BREAK_MAPPING(new_break.id, broken); - } else { - phpdbg_error("breakpoint", "type=\"exists\" add=\"fail\" file=\"%s\" line=\"%ld\"", "Breakpoint at %s:%ld exists", path, line_num); +PHPDBG_API void phpdbg_resolve_pending_file_break(const char *file TSRMLS_DC) /* {{{ */ +{ + HashTable *fileht; + uint filelen = strlen(file); + zend_string *cur; + + ZEND_HASH_FOREACH_STR_KEY_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], cur, fileht) { + if (cur->len < filelen && file[filelen - cur->len - 1] == '/' && !memcmp(file + filelen - cur->len, cur->val, cur->len)) { + phpdbg_breakfile_t *brake, new_brake; + HashTable *master; + dtor_func_t dtor; + + PHPDBG_G(flags) |= PHPDBG_HAS_FILE_BP; + + if (!(master = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], file, filelen))) { + dtor = PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING].pDestructor; + PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING].pDestructor = NULL; + fileht = zend_hash_str_add_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], file, filelen, fileht, sizeof(HashTable)); } - } else { - phpdbg_error("breakpoint", "type=\"notregular\" add=\"fail\" file=\"%s\"", "Cannot set breakpoint in %s, it is not a regular file", path); + ZEND_HASH_FOREACH_PTR(fileht, brake) { + new_brake = *brake; + new_brake.filename = estrndup(file, filelen); + PHPDBG_BREAK_UNMAPPING(brake->id); + + if (master) { + zend_hash_index_update_mem(master, brake->line, &new_brake, sizeof(phpdbg_breakfile_t)); + PHPDBG_BREAK_MAPPING(brake->id, master); + } else { + efree((char *) brake->filename); + *brake = new_brake; + PHPDBG_BREAK_MAPPING(brake->id, fileht); + } + } ZEND_HASH_FOREACH_END(); + + zend_hash_del(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], cur); + + if (!master) { + PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING].pDestructor = dtor; + } + + if (!zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING])) { + PHPDBG_G(flags) &= ~PHPDBG_HAS_PENDING_FILE_BP; + } } - } else { - phpdbg_error("breakpoint", "type=\"nofile\" add=\"fail\" file=\"%s\"", "Cannot stat %s, it does not exist", path); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ PHPDBG_API void phpdbg_set_breakpoint_symbol(const char *name, size_t name_len TSRMLS_DC) /* {{{ */ @@ -1048,6 +1111,7 @@ PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */ PHPDBG_API void phpdbg_clear_breakpoints(TSRMLS_D) /* {{{ */ { zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE]); + zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING]); zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM]); zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]); zend_hash_clean(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE]); @@ -1283,7 +1347,20 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : ""); } ZEND_HASH_FOREACH_END(); } ZEND_HASH_FOREACH_END(); + } if ((PHPDBG_G(flags) & PHPDBG_HAS_PENDING_FILE_BP)) { + HashTable *points; + + phpdbg_out(SEPARATE "\n"); + phpdbg_out("Pending File Breakpoints:\n"); + ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING], points) { + phpdbg_breakfile_t *brake; + ZEND_HASH_FOREACH_PTR(points, brake) { + phpdbg_writeln("file", "id=\"%d\" name=\"%s\" line=\"%lu\" disabled=\"%s\" pending=\"pending\"", "#%d\t\t%s:%lu%s", + brake->id, brake->filename, brake->line, + ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : ""); + } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); } break; case PHPDBG_BREAK_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP)) { diff --git a/sapi/phpdbg/phpdbg_bp.h b/sapi/phpdbg/phpdbg_bp.h index 4090d90f91..a8d2316a3f 100644 --- a/sapi/phpdbg/phpdbg_bp.h +++ b/sapi/phpdbg/phpdbg_bp.h @@ -23,16 +23,17 @@ /* {{{ defines */ #define PHPDBG_BREAK_FILE 0 -#define PHPDBG_BREAK_SYM 1 -#define PHPDBG_BREAK_OPLINE 2 -#define PHPDBG_BREAK_METHOD 3 -#define PHPDBG_BREAK_COND 4 -#define PHPDBG_BREAK_OPCODE 5 -#define PHPDBG_BREAK_FUNCTION_OPLINE 6 -#define PHPDBG_BREAK_METHOD_OPLINE 7 -#define PHPDBG_BREAK_FILE_OPLINE 8 -#define PHPDBG_BREAK_MAP 9 -#define PHPDBG_BREAK_TABLES 10 /* }}} */ +#define PHPDBG_BREAK_FILE_PENDING 1 +#define PHPDBG_BREAK_SYM 2 +#define PHPDBG_BREAK_OPLINE 3 +#define PHPDBG_BREAK_METHOD 4 +#define PHPDBG_BREAK_COND 5 +#define PHPDBG_BREAK_OPCODE 6 +#define PHPDBG_BREAK_FUNCTION_OPLINE 7 +#define PHPDBG_BREAK_METHOD_OPLINE 8 +#define PHPDBG_BREAK_FILE_OPLINE 9 +#define PHPDBG_BREAK_MAP 10 +#define PHPDBG_BREAK_TABLES 11 /* }}} */ /* {{{ */ typedef struct _zend_op *phpdbg_opline_ptr_t; /* }}} */ @@ -116,10 +117,11 @@ typedef struct _phpdbg_breakcond_t { zend_op_array *ops; } phpdbg_breakcond_t; -/* {{{ Opline breaks API */ +/* {{{ Resolving breaks API */ PHPDBG_API void phpdbg_resolve_op_array_breaks(zend_op_array *op_array TSRMLS_DC); PHPDBG_API int phpdbg_resolve_op_array_break(phpdbg_breakopline_t *brake, zend_op_array *op_array TSRMLS_DC); -PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRMLS_DC); /* }}} */ +PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRMLS_DC); +PHPDBG_API void phpdbg_resolve_pending_file_break(const char *file TSRMLS_DC); /* }}} */ /* {{{ Breakpoint Creation API */ PHPDBG_API void phpdbg_set_breakpoint_file(const char* filename, long lineno TSRMLS_DC); diff --git a/sapi/phpdbg/phpdbg_cmd.c b/sapi/phpdbg/phpdbg_cmd.c index d91acb1d17..5c74adfdcd 100644 --- a/sapi/phpdbg/phpdbg_cmd.c +++ b/sapi/phpdbg/phpdbg_cmd.c @@ -703,80 +703,30 @@ PHPDBG_API int phpdbg_stack_execute(phpdbg_param_t *stack, zend_bool allow_async PHPDBG_API char *phpdbg_read_input(char *buffered TSRMLS_DC) /* {{{ */ { + char buf[PHPDBG_MAX_CMD]; char *cmd = NULL; char *buffer = NULL; - if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { + if ((PHPDBG_G(flags) & (PHPDBG_IS_STOPPING | PHPDBG_IS_RUNNING)) != PHPDBG_IS_STOPPING) { if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE) && (buffered == NULL) && !phpdbg_active_sigsafe_mem(TSRMLS_C)) { fflush(PHPDBG_G(io)[PHPDBG_STDOUT].ptr); } if (buffered == NULL) { - if (0) { -disconnect: - PHPDBG_G(flags) |= (PHPDBG_IS_QUITTING|PHPDBG_IS_DISCONNECTED); - zend_bailout(); - return NULL; - } - #define USE_LIB_STAR (defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT)) - /* note: EOF makes readline write prompt again in local console mode - and ignored if compiled without readline */ - /* strongly assuming to be in blocking mode... */ #if USE_LIB_STAR readline: if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) #endif { - char buf[PHPDBG_MAX_CMD]; - int bytes = PHPDBG_G(input_buflen), len = 0; - if (PHPDBG_G(input_buflen)) { - memcpy(buf, PHPDBG_G(input_buffer), bytes); - } - phpdbg_write("prompt", "", "%s", phpdbg_get_prompt(TSRMLS_C)); - PHPDBG_G(last_was_newline) = 1; - - do { - int i; - if (bytes <= 0) { - continue; - } - - for (i = len; i < len + bytes; i++) { - if (buf[i] == '\x03') { - if (i != len + bytes - 1) { - memmove(buf + i, buf + i + 1, len + bytes - i - 1); - } - len--; - i--; - continue; - } - if (buf[i] == '\n') { - PHPDBG_G(input_buflen) = len + bytes - 1 - i; - if (PHPDBG_G(input_buflen)) { - memcpy(PHPDBG_G(input_buffer), buf + i + 1, PHPDBG_G(input_buflen)); - } - if (i != PHPDBG_MAX_CMD - 1) { - buf[i + 1] = 0; - } - cmd = buf; - goto end; - } - } - len += bytes; - /* XXX export the timeout through INI??*/ - } while ((bytes = phpdbg_mixed_read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len, -1 TSRMLS_CC)) > 0); - - if (bytes <= 0) { - goto disconnect; - } - - cmd = buf; + phpdbg_consume_stdin_line(cmd = buf TSRMLS_CC); } #if USE_LIB_STAR else { cmd = readline(phpdbg_get_prompt(TSRMLS_C)); + PHPDBG_G(last_was_newline) = 1; } if (!cmd) { @@ -790,8 +740,7 @@ readline: } else { cmd = buffered; } -end: - PHPDBG_G(last_was_newline) = 1; + buffer = estrdup(cmd); #if USE_LIB_STAR @@ -829,3 +778,24 @@ PHPDBG_API void phpdbg_destroy_input(char **input TSRMLS_DC) /*{{{ */ { efree(*input); } /* }}} */ + +PHPDBG_API int phpdbg_ask_user_permission(const char *question TSRMLS_DC) { + if (!(PHPDBG_G(flags) & PHPDBG_WRITE_XML)) { + char buf[PHPDBG_MAX_CMD]; + phpdbg_out("%s", question); + phpdbg_out(" (type y or n): "); + + while (1) { + phpdbg_consume_stdin_line(buf TSRMLS_CC); + if (buf[1] == '\n' && (buf[0] == 'y' || buf[0] == 'n')) { + if (buf[0] == 'y') { + return SUCCESS; + } + return FAILURE; + } + phpdbg_out("Please enter either y (yes) or n (no): "); + } + } + + return SUCCESS; +} diff --git a/sapi/phpdbg/phpdbg_cmd.h b/sapi/phpdbg/phpdbg_cmd.h index 4049cd9295..a79641c080 100644 --- a/sapi/phpdbg/phpdbg_cmd.h +++ b/sapi/phpdbg/phpdbg_cmd.h @@ -131,6 +131,7 @@ typedef struct { */ PHPDBG_API char* phpdbg_read_input(char *buffered TSRMLS_DC); PHPDBG_API void phpdbg_destroy_input(char** TSRMLS_DC); +PHPDBG_API int phpdbg_ask_user_permission(const char *question TSRMLS_DC); /** * Stack Management diff --git a/sapi/phpdbg/phpdbg_io.c b/sapi/phpdbg/phpdbg_io.c index 97f0356285..6908a687d7 100644 --- a/sapi/phpdbg/phpdbg_io.c +++ b/sapi/phpdbg/phpdbg_io.c @@ -47,6 +47,55 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +/* is easy to generalize ... but not needed for now */ +PHPDBG_API int phpdbg_consume_stdin_line(char *buf TSRMLS_DC) { + int bytes = PHPDBG_G(input_buflen), len = 0; + + if (PHPDBG_G(input_buflen)) { + memcpy(buf, PHPDBG_G(input_buffer), bytes); + } + + PHPDBG_G(last_was_newline) = 1; + + do { + int i; + if (bytes <= 0) { + continue; + } + + for (i = len; i < len + bytes; i++) { + if (buf[i] == '\x03') { + if (i != len + bytes - 1) { + memmove(buf + i, buf + i + 1, len + bytes - i - 1); + } + len--; + i--; + continue; + } + if (buf[i] == '\n') { + PHPDBG_G(input_buflen) = len + bytes - 1 - i; + if (PHPDBG_G(input_buflen)) { + memcpy(PHPDBG_G(input_buffer), buf + i + 1, PHPDBG_G(input_buflen)); + } + if (i != PHPDBG_MAX_CMD - 1) { + buf[i + 1] = 0; + } + return i; + } + } + + len += bytes; + } while ((bytes = phpdbg_mixed_read(PHPDBG_G(io)[PHPDBG_STDIN].fd, buf + len, PHPDBG_MAX_CMD - len, -1 TSRMLS_CC)) > 0); + + if (bytes <= 0) { + PHPDBG_G(flags) |= PHPDBG_IS_QUITTING | PHPDBG_IS_DISCONNECTED; + zend_bailout(); + return 0; + } + + return bytes; +} + PHPDBG_API int phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo TSRMLS_DC) { int got_now, i = len, j; char *p = ptr; @@ -138,6 +187,10 @@ PHPDBG_API int phpdbg_mixed_read(int sock, char *ptr, int len, int tmo TSRMLS_DC PHPDBG_API int phpdbg_mixed_write(int sock, const char *ptr, int len TSRMLS_DC) { + if (PHPDBG_G(flags) & PHPDBG_DISCARD_OUTPUT) { + return 0; + } + if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE) { return phpdbg_send_bytes(sock, ptr, len); } diff --git a/sapi/phpdbg/phpdbg_io.h b/sapi/phpdbg/phpdbg_io.h index 3ac8f4112d..a5659e88c6 100644 --- a/sapi/phpdbg/phpdbg_io.h +++ b/sapi/phpdbg/phpdbg_io.h @@ -21,6 +21,8 @@ #include "phpdbg.h" +PHPDBG_API int phpdbg_consume_stdin_line(char *buf TSRMLS_DC); + PHPDBG_API int phpdbg_consume_bytes(int sock, char *ptr, int len, int tmo TSRMLS_DC); PHPDBG_API int phpdbg_send_bytes(int sock, const char *ptr, int len); PHPDBG_API int phpdbg_mixed_read(int sock, char *ptr, int len, int tmo TSRMLS_DC); diff --git a/sapi/phpdbg/phpdbg_list.c b/sapi/phpdbg/phpdbg_list.c index dd3db355fe..f201be9850 100644 --- a/sapi/phpdbg/phpdbg_list.c +++ b/sapi/phpdbg/phpdbg_list.c @@ -279,6 +279,7 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type TSRMLS_DC) { dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line); zend_hash_str_add_ptr(&PHPDBG_G(file_sources), filename, strlen(filename), dataptr); + phpdbg_resolve_pending_file_break(filename TSRMLS_CC); ret = PHPDBG_G(compile_file)(&fake, type TSRMLS_CC); diff --git a/sapi/phpdbg/phpdbg_out.c b/sapi/phpdbg/phpdbg_out.c index 4d70381533..302c075f78 100644 --- a/sapi/phpdbg/phpdbg_out.c +++ b/sapi/phpdbg/phpdbg_out.c @@ -1118,6 +1118,8 @@ PHPDBG_API int phpdbg_vprint(int type TSRMLS_DC, int fd, const char *tag, const } if (PHPDBG_G(err_buf).active && type != P_STDOUT && type != P_STDERR) { + phpdbg_free_err_buf(TSRMLS_C); + PHPDBG_G(err_buf).type = type; PHPDBG_G(err_buf).fd = fd; PHPDBG_G(err_buf).tag = estrdup(tag); diff --git a/sapi/phpdbg/phpdbg_parser.c b/sapi/phpdbg/phpdbg_parser.c index 8bb9103a98..b4da3ed593 100644 --- a/sapi/phpdbg/phpdbg_parser.c +++ b/sapi/phpdbg/phpdbg_parser.c @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 2.6. */ +/* A Bison parser, made by GNU Bison 2.7.12-4996. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -44,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.6" +#define YYBISON_VERSION "2.7.12-4996" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -69,8 +69,7 @@ #define yynerrs phpdbg_nerrs /* Copy the first part of user declarations. */ - -/* Line 336 of yacc.c */ +/* Line 371 of yacc.c */ #line 1 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" @@ -98,9 +97,8 @@ static int yyerror(void ***tsrm_ls, const char *msg); ZEND_EXTERN_MODULE_GLOBALS(phpdbg); - -/* Line 336 of yacc.c */ -#line 104 "sapi/phpdbg/phpdbg_parser.c" +/* Line 371 of yacc.c */ +#line 102 "sapi/phpdbg/phpdbg_parser.c" # ifndef YY_NULL # if defined __cplusplus && 201103L <= __cplusplus @@ -120,8 +118,8 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); /* In a future release of Bison, this section will be replaced by #include "phpdbg_parser.h". */ -#ifndef PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H -# define PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H +#ifndef YY_PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H_INCLUDED +# define YY_PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H_INCLUDED /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -130,8 +128,7 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); extern int phpdbg_debug; #endif /* "%code requires" blocks. */ - -/* Line 350 of yacc.c */ +/* Line 387 of yacc.c */ #line 31 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" #include "phpdbg.h" @@ -141,9 +138,8 @@ typedef void* yyscan_t; #endif - -/* Line 350 of yacc.c */ -#line 147 "sapi/phpdbg/phpdbg_parser.c" +/* Line 387 of yacc.c */ +#line 143 "sapi/phpdbg/phpdbg_parser.c" /* Tokens. */ #ifndef YYTOKENTYPE @@ -217,13 +213,12 @@ int phpdbg_parse (); #endif #endif /* ! YYPARSE_PARAM */ -#endif /* !PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H */ +#endif /* !YY_PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H_INCLUDED */ /* Copy the second part of user declarations. */ - -/* Line 353 of yacc.c */ -#line 227 "sapi/phpdbg/phpdbg_parser.c" +/* Line 390 of yacc.c */ +#line 222 "sapi/phpdbg/phpdbg_parser.c" #ifdef short # undef short @@ -276,24 +271,33 @@ typedef short int yytype_int16; # if defined YYENABLE_NLS && YYENABLE_NLS # if ENABLE_NLS # include <libintl.h> /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) # endif # endif # ifndef YY_ -# define YY_(msgid) msgid +# define YY_(Msgid) Msgid +# endif +#endif + +#ifndef __attribute__ +/* This feature is available in gcc versions 2.5 and later. */ +# if (! defined __GNUC__ || __GNUC__ < 2 \ + || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)) +# define __attribute__(Spec) /* empty */ # endif #endif /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) +# define YYUSE(E) ((void) (E)) #else -# define YYUSE(e) /* empty */ +# define YYUSE(E) /* empty */ #endif + /* Identity function, used to suppress warnings about constant conditions. */ #ifndef lint -# define YYID(n) (n) +# define YYID(N) (N) #else #if (defined __STDC__ || defined __C99__FUNC__ \ || defined __cplusplus || defined _MSC_VER) @@ -621,10 +625,10 @@ static const yytype_uint8 yytable[] = 32, 36, 39, 40, 0, 0, 41, 42, 27 }; -#define yypact_value_is_default(yystate) \ - ((yystate) == (-16)) +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-16))) -#define yytable_value_is_error(yytable_value) \ +#define yytable_value_is_error(Yytable_value) \ YYID (0) static const yytype_int8 yycheck[] = @@ -691,47 +695,18 @@ do \ } \ while (YYID (0)) - +/* Error token number */ #define YYTERROR 1 #define YYERRCODE 256 -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) - - /* This macro is provided for backward compatibility. */ - #ifndef YY_LOCATION_PRINT # define YY_LOCATION_PRINT(File, Loc) ((void) 0) #endif /* YYLEX -- calling `yylex' with the right arguments. */ - #ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) #else @@ -793,11 +768,7 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, tsrm_ls) # else YYUSE (yyoutput); # endif - switch (yytype) - { - default: - break; - } + YYUSE (yytype); } @@ -1040,7 +1011,6 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, { YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ const char *yyformat = YY_NULL; @@ -1103,11 +1073,13 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, break; } yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } } } } @@ -1127,10 +1099,12 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, # undef YYCASE_ } - yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } if (*yymsg_alloc < yysize) { @@ -1188,12 +1162,7 @@ yydestruct (yymsg, yytype, yyvaluep, tsrm_ls) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - switch (yytype) - { - - default: - break; - } + YYUSE (yytype); } @@ -1228,8 +1197,31 @@ yyparse (tsrm_ls) /* The lookahead symbol. */ int yychar; + +#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +/* Default value used for initialization, for pacifying older GCCs + or non-GCC compilers. */ +static YYSTYPE yyval_default; +# define YY_INITIAL_VALUE(Value) = Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + /* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; +YYSTYPE yylval YY_INITIAL_VALUE(yyval_default); /* Number of syntax errors so far. */ int yynerrs; @@ -1260,7 +1252,7 @@ YYSTYPE yylval; int yyn; int yyresult; /* Lookahead token as an internal (translated) token number. */ - int yytoken; + int yytoken = 0; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; @@ -1278,9 +1270,8 @@ YYSTYPE yylval; Keep to zero when no symbol should be popped. */ int yylen = 0; - yytoken = 0; - yyss = yyssa; - yyvs = yyvsa; + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); @@ -1289,14 +1280,6 @@ YYSTYPE yylval; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - yyssp = yyss; - yyvsp = yyvs; - goto yysetstate; /*------------------------------------------------------------. @@ -1437,7 +1420,9 @@ yybackup: yychar = YYEMPTY; yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END goto yynewstate; @@ -1474,36 +1459,31 @@ yyreduce: switch (yyn) { case 3: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 68 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(1) - (1)])); } break; case 5: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 73 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(1) - (1)])); } break; case 6: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 74 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(2) - (2)])); } break; case 7: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 75 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (2)]); } break; case 8: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 79 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = FILE_PARAM; @@ -1513,8 +1493,7 @@ yyreduce: break; case 9: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 84 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = NUMERIC_FILE_PARAM; @@ -1524,8 +1503,7 @@ yyreduce: break; case 10: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 89 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = FILE_PARAM; @@ -1540,8 +1518,7 @@ yyreduce: break; case 11: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 99 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = NUMERIC_FILE_PARAM; @@ -1556,8 +1533,7 @@ yyreduce: break; case 12: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 109 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = METHOD_PARAM; @@ -1567,8 +1543,7 @@ yyreduce: break; case 13: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 114 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = NUMERIC_METHOD_PARAM; @@ -1579,8 +1554,7 @@ yyreduce: break; case 14: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 120 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = NUMERIC_FUNCTION_PARAM; @@ -1591,8 +1565,7 @@ yyreduce: break; case 15: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 126 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = COND_PARAM; @@ -1602,64 +1575,55 @@ yyreduce: break; case 16: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 131 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 17: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 132 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 18: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 133 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 19: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 134 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 20: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 135 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 21: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 136 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 22: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 137 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval) = (yyvsp[(1) - (1)]); } break; case 23: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 141 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { PHPDBG_G(req_id) = (yyvsp[(1) - (1)]).num; } break; case 25: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 146 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = EVAL_PARAM; @@ -1669,8 +1633,7 @@ yyreduce: break; case 26: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 151 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = SHELL_PARAM; @@ -1680,8 +1643,7 @@ yyreduce: break; case 27: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 156 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = RUN_PARAM; @@ -1690,8 +1652,7 @@ yyreduce: break; case 28: - -/* Line 1803 of yacc.c */ +/* Line 1802 of yacc.c */ #line 160 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" { (yyval).type = RUN_PARAM; @@ -1701,9 +1662,8 @@ yyreduce: break; - -/* Line 1803 of yacc.c */ -#line 1707 "sapi/phpdbg/phpdbg_parser.c" +/* Line 1802 of yacc.c */ +#line 1667 "sapi/phpdbg/phpdbg_parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1866,7 +1826,9 @@ yyerrlab1: YY_STACK_PRINT (yyss, yyssp); } + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END /* Shift the error token. */ @@ -1932,8 +1894,7 @@ yyreturn: } - -/* Line 2049 of yacc.c */ +/* Line 2050 of yacc.c */ #line 167 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" @@ -1960,4 +1921,3 @@ int phpdbg_do_parse(phpdbg_param_t *stack, char *input TSRMLS_DC) { return yyparse(NULL); #endif } - diff --git a/sapi/phpdbg/phpdbg_parser.h b/sapi/phpdbg/phpdbg_parser.h index e8ab7a6503..8d4aeacc31 100644 --- a/sapi/phpdbg/phpdbg_parser.h +++ b/sapi/phpdbg/phpdbg_parser.h @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 2.6. */ +/* A Bison parser, made by GNU Bison 2.7.12-4996. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,8 +30,8 @@ This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ -#ifndef PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H -# define PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H +#ifndef YY_PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H_INCLUDED +# define YY_PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H_INCLUDED /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -40,8 +40,7 @@ extern int phpdbg_debug; #endif /* "%code requires" blocks. */ - -/* Line 2056 of yacc.c */ +/* Line 2060 of yacc.c */ #line 31 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y" #include "phpdbg.h" @@ -51,9 +50,8 @@ typedef void* yyscan_t; #endif - -/* Line 2056 of yacc.c */ -#line 57 "sapi/phpdbg/phpdbg_parser.h" +/* Line 2060 of yacc.c */ +#line 55 "sapi/phpdbg/phpdbg_parser.h" /* Tokens. */ #ifndef YYTOKENTYPE @@ -127,4 +125,4 @@ int phpdbg_parse (); #endif #endif /* ! YYPARSE_PARAM */ -#endif /* !PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H */ +#endif /* !YY_PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H_INCLUDED */ diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index f1b1db12fc..7ce0cea363 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -29,7 +29,6 @@ #include "phpdbg_print.h" #include "phpdbg_info.h" #include "phpdbg_break.h" -#include "phpdbg_bp.h" #include "phpdbg_opcode.h" #include "phpdbg_list.h" #include "phpdbg_utils.h" @@ -44,6 +43,7 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg); ZEND_EXTERN_MODULE_GLOBALS(output); +extern int phpdbg_startup_run; #ifdef HAVE_LIBDL #ifdef PHP_WIN32 @@ -256,7 +256,7 @@ void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_ goto next_line; } - { + zend_try { char *input = phpdbg_read_input(cmd TSRMLS_CC); phpdbg_param_t stack; @@ -280,7 +280,12 @@ void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_ phpdbg_stack_free(&stack); phpdbg_destroy_input(&input TSRMLS_CC); - } + } zend_catch { + PHPDBG_G(flags) &= ~(PHPDBG_IS_RUNNING | PHPDBG_IS_CLEANING); + if (PHPDBG_G(flags) & PHPDBG_IS_QUITTING) { + zend_bailout(); + } + } zend_end_try(); } next_line: line++; @@ -348,6 +353,11 @@ PHPDBG_COMMAND(exec) /* {{{ */ size_t res_len = strlen(res); if ((res_len != PHPDBG_G(exec_len)) || (memcmp(res, PHPDBG_G(exec), res_len) != SUCCESS)) { + if (PHPDBG_G(in_execution)) { + if (phpdbg_ask_user_permission("Do you really want to stop execution to set a new execution context?" TSRMLS_CC) == FAILURE) { + return FAILURE; + } + } if (PHPDBG_G(exec)) { phpdbg_notice("exec", "type=\"unset\" context=\"%s\"", "Unsetting old execution context: %s", PHPDBG_G(exec)); @@ -371,9 +381,11 @@ PHPDBG_COMMAND(exec) /* {{{ */ phpdbg_notice("exec", "type=\"set\" context=\"%s\"", "Set execution context: %s", PHPDBG_G(exec)); - if (phpdbg_compile(TSRMLS_C) == FAILURE) { - phpdbg_error("compile", "type=\"compilefailure\" context=\"%s\"", "Failed to compile %s", PHPDBG_G(exec)); + if (PHPDBG_G(in_execution)) { + phpdbg_clean(1 TSRMLS_CC); } + + phpdbg_compile(TSRMLS_C); } else { phpdbg_notice("exec", "type=\"unchanged\"", "Execution context not changed"); } @@ -392,11 +404,6 @@ int phpdbg_compile(TSRMLS_D) /* {{{ */ if (!PHPDBG_G(exec)) { phpdbg_error("inactive", "type=\"nocontext\"", "No execution context"); - return SUCCESS; - } - - if (PHPDBG_G(in_execution)) { - phpdbg_error("inactive", "type=\"isrunning\"", "Cannot compile while in execution"); return FAILURE; } @@ -405,6 +412,7 @@ int phpdbg_compile(TSRMLS_D) /* {{{ */ zend_destroy_file_handle(&fh TSRMLS_CC); phpdbg_notice("compile", "context=\"%s\"", "Successful compilation of %s", PHPDBG_G(exec)); + return SUCCESS; } else { phpdbg_error("compile", "type=\"openfailure\" context=\"%s\"", "Could not open file %s", PHPDBG_G(exec)); @@ -541,15 +549,18 @@ static inline void phpdbg_handle_exception(TSRMLS_D) /* }}} */ PHPDBG_COMMAND(run) /* {{{ */ { - if (PHPDBG_G(in_execution)) { - phpdbg_error("inactive", "type=\"isrunning\"", "Cannot start another execution while one is in progress"); - return SUCCESS; - } - if (PHPDBG_G(ops) || PHPDBG_G(exec)) { zend_execute_data *ex = EG(current_execute_data); zend_bool restore = 1; + if (PHPDBG_G(in_execution)) { + if (phpdbg_ask_user_permission("Do you really want to restart execution?" TSRMLS_CC) == SUCCESS) { + phpdbg_startup_run++; + phpdbg_clean(1 TSRMLS_CC); + } + return SUCCESS; + } + if (!PHPDBG_G(ops)) { if (phpdbg_compile(TSRMLS_C) == FAILURE) { phpdbg_error("compile", "type=\"compilefailure\" context=\"%s\"", "Failed to compile %s, cannot run", PHPDBG_G(exec)); @@ -598,12 +609,13 @@ PHPDBG_COMMAND(run) /* {{{ */ zend_try { PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE; + PHPDBG_G(flags) |= PHPDBG_IS_RUNNING; zend_execute(PHPDBG_G(ops), &PHPDBG_G(retval) TSRMLS_CC); PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE; - phpdbg_notice("stop", "type=\"normal\"", "Script ended normally"); } zend_catch { PHPDBG_G(in_execution) = 0; - if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { + + if (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)) { phpdbg_error("stop", "type=\"bailout\"", "Caught exit/error from VM"); restore = 0; } @@ -618,7 +630,11 @@ PHPDBG_COMMAND(run) /* {{{ */ if (EG(exception)) { phpdbg_handle_exception(TSRMLS_C); } + + phpdbg_clean(1 TSRMLS_CC); } + + PHPDBG_G(flags) &= ~PHPDBG_IS_RUNNING; } else { phpdbg_error("inactive", "type=\"nocontext\"", "Nothing to execute!"); } @@ -1074,7 +1090,7 @@ PHPDBG_COMMAND(register) /* {{{ */ PHPDBG_COMMAND(quit) /* {{{ */ { /* don't allow this to loop, ever ... */ - if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { + if (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)) { PHPDBG_G(flags) |= PHPDBG_IS_QUITTING; zend_bailout(); } @@ -1085,8 +1101,9 @@ PHPDBG_COMMAND(quit) /* {{{ */ PHPDBG_COMMAND(clean) /* {{{ */ { if (PHPDBG_G(in_execution)) { - phpdbg_error("inactive", "type=\"isrunning\"", "Cannot clean environment while executing"); - return SUCCESS; + if (phpdbg_ask_user_permission("Do you really want to clean your current environment?" TSRMLS_CC) == FAILURE) { + return SUCCESS; + } } phpdbg_out("Cleaning Execution Environment\n"); @@ -1097,6 +1114,8 @@ PHPDBG_COMMAND(clean) /* {{{ */ phpdbg_writeln("clean", "constants=\"%d\"", "Constants %d", zend_hash_num_elements(EG(zend_constants))); phpdbg_writeln("clean", "includes=\"%d\"", "Includes %d", zend_hash_num_elements(&EG(included_files))); + PHPDBG_G(flags) &= ~PHPDBG_IS_RUNNING; + phpdbg_clean(1 TSRMLS_CC); phpdbg_xml("</cleaninfo>"); @@ -1174,60 +1193,65 @@ int phpdbg_interactive(zend_bool allow_async_unsafe TSRMLS_DC) /* {{{ */ PHPDBG_G(flags) |= PHPDBG_IS_INTERACTIVE; - input = phpdbg_read_input(NULL TSRMLS_CC); + while (ret == SUCCESS || ret == FAILURE) { + if ((PHPDBG_G(flags) & (PHPDBG_IS_STOPPING | PHPDBG_IS_RUNNING)) == PHPDBG_IS_STOPPING) { + zend_bailout(); + } + + if (!(input = phpdbg_read_input(NULL TSRMLS_CC))) { + break; + } - if (input) { - do { - phpdbg_init_param(&stack, STACK_PARAM); - if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) { - phpdbg_activate_err_buf(1 TSRMLS_CC); + phpdbg_init_param(&stack, STACK_PARAM); + + if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) { + phpdbg_activate_err_buf(1 TSRMLS_CC); #ifdef PHP_WIN32 #define PARA ((phpdbg_param_t *)stack.next)->type - if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE && (RUN_PARAM == PARA || EVAL_PARAM == PARA)) { - sigio_watcher_start(); - } + if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE && (RUN_PARAM == PARA || EVAL_PARAM == PARA)) { + sigio_watcher_start(); + } #endif - switch (ret = phpdbg_stack_execute(&stack, allow_async_unsafe TSRMLS_CC)) { - case FAILURE: - if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { - if (!allow_async_unsafe || phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { - phpdbg_output_err_buf(NULL, "%b", "%b" TSRMLS_CC); - } + switch (ret = phpdbg_stack_execute(&stack, allow_async_unsafe TSRMLS_CC)) { + case FAILURE: + if (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)) { + if (!allow_async_unsafe || phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) { + phpdbg_output_err_buf(NULL, "%b", "%b" TSRMLS_CC); } - break; + } + break; - case PHPDBG_LEAVE: - case PHPDBG_FINISH: - case PHPDBG_UNTIL: - case PHPDBG_NEXT: { - phpdbg_activate_err_buf(0 TSRMLS_CC); - phpdbg_free_err_buf(TSRMLS_C); - if (!PHPDBG_G(in_execution) && !(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) { - phpdbg_error("command", "type=\"noexec\"", "Not running"); - } - goto out; + case PHPDBG_LEAVE: + case PHPDBG_FINISH: + case PHPDBG_UNTIL: + case PHPDBG_NEXT: { + phpdbg_activate_err_buf(0 TSRMLS_CC); + phpdbg_free_err_buf(TSRMLS_C); + if (!PHPDBG_G(in_execution) && !(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)) { + phpdbg_error("command", "type=\"noexec\"", "Not running"); } + break; } + } - phpdbg_activate_err_buf(0 TSRMLS_CC); - phpdbg_free_err_buf(TSRMLS_C); + phpdbg_activate_err_buf(0 TSRMLS_CC); + phpdbg_free_err_buf(TSRMLS_C); #ifdef PHP_WIN32 - if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE && (RUN_PARAM == PARA || EVAL_PARAM == PARA)) { - sigio_watcher_stop(); - } + if (PHPDBG_G(flags) & PHPDBG_IS_REMOTE && (RUN_PARAM == PARA || EVAL_PARAM == PARA)) { + sigio_watcher_stop(); + } #undef PARA #endif - } + } - phpdbg_stack_free(&stack); - phpdbg_destroy_input(&input TSRMLS_CC); - PHPDBG_G(req_id) = 0; - } while ((input = phpdbg_read_input(NULL TSRMLS_CC))); + phpdbg_stack_free(&stack); + phpdbg_destroy_input(&input TSRMLS_CC); + PHPDBG_G(req_id) = 0; + input = NULL; } -out: if (input) { phpdbg_stack_free(&stack); phpdbg_destroy_input(&input TSRMLS_CC); @@ -1286,6 +1310,10 @@ void phpdbg_execute_ex(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */ zend_hash_init(&vars, execute_data->func->op_array.last, NULL, NULL, 0); + if ((PHPDBG_G(flags) & (PHPDBG_IS_STOPPING | PHPDBG_IS_RUNNING)) == PHPDBG_IS_STOPPING) { + zend_bailout(); + } + PHPDBG_G(in_execution) = 1; while (1) { @@ -1431,7 +1459,7 @@ void phpdbg_force_interruption(TSRMLS_D) { next: PHPDBG_G(flags) &= ~PHPDBG_IN_SIGNAL_HANDLER; - if (PHPDBG_G(flags) & PHPDBG_IS_QUITTING) { + if (PHPDBG_G(flags) & PHPDBG_IS_STOPPING) { zend_bailout(); } } diff --git a/sapi/phpdbg/tests/commands/0104_clean.test b/sapi/phpdbg/tests/commands/0104_clean.test index d50903c479..2c7660ad60 100644 --- a/sapi/phpdbg/tests/commands/0104_clean.test +++ b/sapi/phpdbg/tests/commands/0104_clean.test @@ -9,7 +9,6 @@ #Functions %d #Constants %d #Includes %d -#[Nothing to execute!] ################################################# clean quit |