diff options
Diffstat (limited to 'sapi/phpdbg/phpdbg.c')
| -rw-r--r-- | sapi/phpdbg/phpdbg.c | 176 | 
1 files changed, 120 insertions, 56 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;  	} | 
