summaryrefslogtreecommitdiff
path: root/sapi/phpdbg/phpdbg_prompt.c
diff options
context:
space:
mode:
authorAnatol Belski <ab@php.net>2014-11-18 21:18:52 +0100
committerAnatol Belski <ab@php.net>2014-11-18 21:18:52 +0100
commitc6bad96f306df8e8b656472e618283ced5083cdb (patch)
tree7e5b52aa07777f0336b0944a228bf66f8f56b31f /sapi/phpdbg/phpdbg_prompt.c
parent4262663e4caa82ba17666781a95bdcb872b4e109 (diff)
parent64a39dc7b07d4b54d050a3a5c15045fe91c0b651 (diff)
downloadphp-git-c6bad96f306df8e8b656472e618283ced5083cdb.tar.gz
Merge remote-tracking branch 'origin/master' into native-tls
* origin/master: (398 commits) NEWS add test for bug #68381 Fixed bug #68381 Set FPM log level earlier during init proper dllexport move to size_t where zend_string is used internally fix some datatype mismatches return after the warning, to fix uninitialized salt usage fix datatype mismatches add missing type specifier fix datatype mismatches fix unsigned check "extern" shouldn't be used for definitions joined identical conditional blocks simplify fpm tests SEND_VAR_NO_REF optimization Add test for bug #68442 Add various tests for FPM - covering recent bugs (68420, 68421, 68423, 68428) - for UDS - for ping and status URI - for multi pool and multi mode Include small MIT FastCGI client library from https://github.com/adoy/PHP-FastCGI-Client Get rid of zend_free_op structure (use zval* instead). Get rid of useless TSRMLS arguments. Add new FPM test for IPv4/IPv6 ... Conflicts: win32/build/config.w32
Diffstat (limited to 'sapi/phpdbg/phpdbg_prompt.c')
-rw-r--r--sapi/phpdbg/phpdbg_prompt.c338
1 files changed, 209 insertions, 129 deletions
diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c
index 190907e687..aa431a8ae0 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"
@@ -43,6 +42,7 @@
#include "phpdbg_eol.h"
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
+extern int phpdbg_startup_run;
#ifdef HAVE_LIBDL
#ifdef PHP_WIN32
@@ -200,93 +200,128 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ *
return FAILURE;
} /* }}} */
-void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC) /* {{{ */
-{
- struct stat sb;
+struct phpdbg_init_state {
+ int line;
+ zend_bool in_code;
+ char *code;
+ size_t code_len;
+ const char *init_file;
+};
- if (init_file && VCWD_STAT(init_file, &sb) != -1) {
- FILE *fp = fopen(init_file, "r");
- if (fp) {
- int line = 1;
+static void phpdbg_line_init(char *cmd, struct phpdbg_init_state *state TSRMLS_DC) {
+ size_t cmd_len = strlen(cmd);
- char cmd[PHPDBG_MAX_CMD];
- size_t cmd_len = 0L;
- char *code = NULL;
- size_t code_len = 0L;
- zend_bool in_code = 0;
+ state->line++;
- while (fgets(cmd, PHPDBG_MAX_CMD, fp) != NULL) {
- cmd_len = strlen(cmd)-1;
-
- while (cmd_len > 0L && isspace(cmd[cmd_len-1]))
- cmd_len--;
-
- cmd[cmd_len] = '\0';
-
- if (*cmd && cmd_len > 0L && cmd[0] != '#') {
- if (cmd_len == 2) {
- if (memcmp(cmd, "<:", sizeof("<:")-1) == SUCCESS) {
- in_code = 1;
- goto next_line;
- } else {
- if (memcmp(cmd, ":>", sizeof(":>")-1) == SUCCESS) {
- in_code = 0;
- code[code_len] = '\0';
- {
- zend_eval_stringl(code, code_len, NULL, "phpdbginit code" TSRMLS_CC);
- }
- free(code);
- code = NULL;
- goto next_line;
- }
- }
- }
+ while (cmd_len > 0L && isspace(cmd[cmd_len-1])) {
+ cmd_len--;
+ }
- if (in_code) {
- if (code == NULL) {
- code = malloc(cmd_len + 1);
- } else code = realloc(code, code_len + cmd_len + 1);
+ cmd[cmd_len] = '\0';
- if (code) {
- memcpy(
- &code[code_len], cmd, cmd_len);
- code_len += cmd_len;
- }
- goto next_line;
- }
+ if (*cmd && cmd_len > 0L && cmd[0] != '#') {
+ if (cmd_len == 2) {
+ if (memcmp(cmd, "<:", sizeof("<:")-1) == SUCCESS) {
+ state->in_code = 1;
+ return;
+ } else {
+ if (memcmp(cmd, ":>", sizeof(":>")-1) == SUCCESS) {
+ state->in_code = 0;
+ state->code[state->code_len] = '\0';
+ zend_eval_stringl(state->code, state->code_len, NULL, "phpdbginit code" TSRMLS_CC);
+ free(state->code);
+ state->code = NULL;
+ return;
+ }
+ }
+ }
+
+ if (state->in_code) {
+ if (state->code == NULL) {
+ state->code = malloc(cmd_len + 1);
+ } else {
+ state->code = realloc(state->code, state->code_len + cmd_len + 1);
+ }
+
+ if (state->code) {
+ memcpy(&state->code[state->code_len], cmd, cmd_len);
+ state->code_len += cmd_len;
+ }
+
+ return;
+ }
- {
- char *input = phpdbg_read_input(cmd TSRMLS_CC);
- phpdbg_param_t stack;
+ zend_try {
+ char *input = phpdbg_read_input(cmd TSRMLS_CC);
+ phpdbg_param_t stack;
- phpdbg_init_param(&stack, STACK_PARAM);
+ phpdbg_init_param(&stack, STACK_PARAM);
- phpdbg_activate_err_buf(1 TSRMLS_CC);
+ phpdbg_activate_err_buf(1 TSRMLS_CC);
- if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) {
- switch (phpdbg_stack_execute(&stack, 1 /* allow_async_unsafe == 1 */ TSRMLS_CC)) {
- case FAILURE:
- phpdbg_activate_err_buf(0 TSRMLS_CC);
- if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) {
- phpdbg_output_err_buf("initfailure", "%b file=\"%s\" line=\"%d\" input=\"%s\"", "Unrecognized command in %s:%d: %s, %b!" TSRMLS_CC, init_file, line, input);
- }
- break;
+ if (phpdbg_do_parse(&stack, input TSRMLS_CC) <= 0) {
+ switch (phpdbg_stack_execute(&stack, 1 /* allow_async_unsafe == 1 */ TSRMLS_CC)) {
+ case FAILURE:
+ phpdbg_activate_err_buf(0 TSRMLS_CC);
+ if (phpdbg_call_register(&stack TSRMLS_CC) == FAILURE) {
+ if (state->init_file) {
+ phpdbg_output_err_buf("initfailure", "%b file=\"%s\" line=\"%d\" input=\"%s\"", "Unrecognized command in %s:%d: %s, %b!" TSRMLS_CC, state->init_file, state->line, input);
+ } else {
+ phpdbg_output_err_buf("initfailure", "%b line=\"%d\" input=\"%s\"", "Unrecognized command on line %d: %s, %b!" TSRMLS_CC, state->line, input);
}
}
+ 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);
- phpdbg_stack_free(&stack);
- phpdbg_destroy_input(&input TSRMLS_CC);
- }
- }
-next_line:
- line++;
+ 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();
+ }
+
+}
+
+void phpdbg_string_init(char *buffer TSRMLS_DC) {
+ struct phpdbg_init_state state = {0};
+ char *str = strtok(buffer, "\n");
+
+ while (str) {
+ phpdbg_line_init(str, &state TSRMLS_CC);
+
+ str = strtok(NULL, "\n");
+ }
+
+ if (state.code) {
+ free(state.code);
+ }
+}
+
+void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init TSRMLS_DC) /* {{{ */
+{
+ struct stat sb;
+
+ if (init_file && VCWD_STAT(init_file, &sb) != -1) {
+ FILE *fp = fopen(init_file, "r");
+ if (fp) {
+ char cmd[PHPDBG_MAX_CMD];
+ struct phpdbg_init_state state = {0};
+
+ state.init_file = init_file;
+
+ while (fgets(cmd, PHPDBG_MAX_CMD, fp) != NULL) {
+ phpdbg_line_init(cmd, &state TSRMLS_CC);
}
- if (code) {
- free(code);
+ if (state.code) {
+ free(state.code);
}
fclose(fp);
@@ -347,6 +382,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));
@@ -370,9 +410,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");
}
@@ -391,11 +433,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;
}
@@ -404,6 +441,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));
@@ -540,15 +578,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));
@@ -597,12 +638,17 @@ 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_QUITTING) {
+ zend_bailout();
+ }
+
+ if (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)) {
phpdbg_error("stop", "type=\"bailout\"", "Caught exit/error from VM");
restore = 0;
}
@@ -618,6 +664,10 @@ PHPDBG_COMMAND(run) /* {{{ */
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!");
}
@@ -645,12 +695,21 @@ PHPDBG_COMMAND(ev) /* {{{ */
zend_bool stepping = ((PHPDBG_G(flags) & PHPDBG_IS_STEPPING) == PHPDBG_IS_STEPPING);
zval retval;
+ zend_execute_data *original_execute_data = EG(current_execute_data);
+ zend_class_entry *original_scope = EG(scope);
+ zend_vm_stack original_stack = EG(vm_stack);
+ original_stack->top = EG(vm_stack_top);
+
+ PHPDBG_OUTPUT_BACKUP();
+
if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) {
phpdbg_try_access {
phpdbg_parse_variable(param->str, param->len, &EG(symbol_table).ht, 0, phpdbg_output_ev_variable, 0 TSRMLS_CC);
} phpdbg_catch_access {
phpdbg_error("signalsegv", "", "Could not fetch data, invalid data source");
} phpdbg_end_try_access();
+
+ PHPDBG_OUTPUT_BACKUP_RESTORE();
return SUCCESS;
}
@@ -672,6 +731,12 @@ PHPDBG_COMMAND(ev) /* {{{ */
phpdbg_out("\n");
zval_ptr_dtor(&retval);
}
+ } zend_catch {
+ EG(current_execute_data) = original_execute_data;
+ EG(scope) = original_scope;
+ EG(vm_stack_top) = original_stack->top;
+ EG(vm_stack_end) = original_stack->end;
+ EG(vm_stack) = original_stack;
} zend_end_try();
PHPDBG_G(flags) &= ~PHPDBG_IN_EVAL;
@@ -682,6 +747,8 @@ PHPDBG_COMMAND(ev) /* {{{ */
CG(unclean_shutdown) = 0;
+ PHPDBG_OUTPUT_BACKUP_RESTORE();
+
return SUCCESS;
} /* }}} */
@@ -1043,7 +1110,7 @@ PHPDBG_COMMAND(register) /* {{{ */
phpdbg_notice("register", "function=\"%s\"", "Registered %s", lcname);
} else {
- phpdbg_error("register", "type=\"notfoundc\" function=\"%s\"", "The requested function (%s) could not be found", param->str);
+ phpdbg_error("register", "type=\"notfound\" function=\"%s\"", "The requested function (%s) could not be found", param->str);
}
} else {
phpdbg_error("register", "type=\"inuse\" function=\"%s\"", "The requested name (%s) is already in use", lcname);
@@ -1056,8 +1123,9 @@ 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;
+ PHPDBG_G(flags) &= ~(PHPDBG_IS_RUNNING | PHPDBG_IS_CLEANING);
zend_bailout();
}
@@ -1067,8 +1135,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");
@@ -1079,6 +1148,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>");
@@ -1156,60 +1227,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) {
- do {
- phpdbg_init_param(&stack, STACK_PARAM);
+ if (!(input = phpdbg_read_input(NULL TSRMLS_CC))) {
+ break;
+ }
- 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);
@@ -1268,6 +1344,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_G(flags) & PHPDBG_IS_RUNNING)) {
+ zend_bailout();
+ }
+
PHPDBG_G(in_execution) = 1;
while (1) {
@@ -1413,7 +1493,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();
}
}