diff options
Diffstat (limited to 'sapi')
| -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  | 
