summaryrefslogtreecommitdiff
path: root/sapi/phpdbg/phpdbg.c
diff options
context:
space:
mode:
authorAnatol Belski <ab@php.net>2015-07-21 12:27:50 +0200
committerAnatol Belski <ab@php.net>2015-07-21 12:27:50 +0200
commitb148ef44965651fcbe93e8ee35a14edc087ef17c (patch)
treef5c53fb3d448d0174610d077e0bf3c8bd76834b2 /sapi/phpdbg/phpdbg.c
parentad8a73dd55c087de465ad80e8715611693bb1460 (diff)
parent6065b29fe41f09e01dd06ba21980e0344f13230c (diff)
downloadphp-git-b148ef44965651fcbe93e8ee35a14edc087ef17c.tar.gz
Merge branch 'master' into PHP-7.0.0
* master: (204 commits) Reverted ad4533fdbabcc3e545277e30023b2fdce16297a0 update UPGRADING updated NEWS fix comment libwebp support for linux Replaced libvpx by libwebp (first draft; Windows only) update news with bug #70022 Change E_ERROR and some E_WARNING to E_RECOVERABLE_ERROR. Add tests for json_last_error()/json_last_error_msg() failures updated NEWS updated NEWS Exclude opcache from a few opcode related tests updated NEWS updated NEWS Fix #66387: Stack overflow with imagefilltoborder Fix various Windows issues (e.g. dir separators) Remove bogus exception_save() from FETCH_CLASS Fix readline/libedit build Do not use readline when not having a tty This is important for e.g. run-tests.php Add show_unexecuted option to phpdbg_end_oplog() ... Conflicts: Zend/tests/temporary_cleaning_001.phpt Zend/tests/temporary_cleaning_003.phpt Zend/tests/temporary_cleaning_004.phpt Zend/tests/temporary_cleaning_005.phpt Zend/zend_compile.c Zend/zend_compile.h sapi/phpdbg/phpdbg_opcode.c
Diffstat (limited to 'sapi/phpdbg/phpdbg.c')
-rw-r--r--sapi/phpdbg/phpdbg.c125
1 files changed, 96 insertions, 29 deletions
diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c
index 31dab3f274..d594601f29 100644
--- a/sapi/phpdbg/phpdbg.c
+++ b/sapi/phpdbg/phpdbg.c
@@ -111,6 +111,8 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */
pg->sigsafe_mem.mem = NULL;
pg->sigsegv_bailout = NULL;
+ pg->oplog_list = NULL;
+
#ifdef PHP_WIN32
pg->sigio_watcher_thread = INVALID_HANDLE_VALUE;
memset(&pg->swd, 0, sizeof(struct win32_sigio_watcher_data));
@@ -441,16 +443,54 @@ static PHP_FUNCTION(phpdbg_start_oplog)
PHPDBG_G(oplog_list)->start = PHPDBG_G(oplog_cur);
}
+static void phpdbg_oplog_fill_executable(zend_op_array *op_array, HashTable *insert_ht, zend_bool by_opcode) {
+ /* ignore RECV_* opcodes */
+ zend_op *cur = op_array->opcodes + op_array->num_args + !!(op_array->fn_flags & ZEND_ACC_VARIADIC);
+ zend_op *end = op_array->opcodes + op_array->last;
+
+ zend_long insert_idx;
+ zval zero;
+ ZVAL_LONG(&zero, 0);
+
+ /* ignore autogenerated return (well, not too precise with finally branches, but that's okay) */
+ if (op_array->last > 1 && (end - 1)->opcode == ZEND_RETURN && ((end - 2)->opcode == ZEND_RETURN || (end - 2)->opcode == ZEND_GENERATOR_RETURN || (end - 2)->opcode == ZEND_THROW)) {
+ end--;
+ }
+
+ for (; cur < end; cur++) {
+ if (cur->opcode == ZEND_NOP || cur->opcode == ZEND_OP_DATA || cur->opcode == ZEND_FE_FREE || cur->opcode == ZEND_FREE || cur->opcode == ZEND_ASSERT_CHECK
+ || cur->opcode == ZEND_DECLARE_CONST || cur->opcode == ZEND_DECLARE_CLASS || cur->opcode == ZEND_DECLARE_INHERITED_CLASS || cur->opcode == ZEND_DECLARE_FUNCTION
+ || cur->opcode == ZEND_DECLARE_INHERITED_CLASS_DELAYED || cur->opcode == ZEND_VERIFY_ABSTRACT_CLASS || cur->opcode == ZEND_ADD_TRAIT || cur->opcode == ZEND_BIND_TRAITS
+ || cur->opcode == ZEND_DECLARE_ANON_CLASS || cur->opcode == ZEND_DECLARE_ANON_INHERITED_CLASS || cur->opcode == ZEND_FAST_RET || cur->opcode == ZEND_TICKS
+ || cur->opcode == ZEND_EXT_STMT || cur->opcode == ZEND_EXT_FCALL_BEGIN || cur->opcode == ZEND_EXT_FCALL_END || cur->opcode == ZEND_EXT_NOP || cur->opcode == ZEND_BIND_GLOBAL) {
+ continue;
+ }
+
+ if (by_opcode) {
+ insert_idx = cur - op_array->opcodes;
+ } else {
+ insert_idx = cur->lineno;
+ }
+
+ if (cur->opcode == ZEND_NEW && (cur + 1)->opcode == ZEND_DO_FCALL) {
+ cur++;
+ }
+
+ zend_hash_index_update(insert_ht, insert_idx, &zero);
+ }
+}
+
/* {{{ proto void phpdbg_end_oplog() */
static PHP_FUNCTION(phpdbg_end_oplog)
{
- phpdbg_oplog_entry *cur = PHPDBG_G(oplog_list)->start;
- phpdbg_oplog_list *prev = PHPDBG_G(oplog_list)->prev;
+ phpdbg_oplog_entry *cur;
+ phpdbg_oplog_list *prev;
- HashTable *options;
+ HashTable *options = NULL;
zval *option_buffer;
zend_bool by_function = 0;
zend_bool by_opcode = 0;
+ zend_bool show_unexecuted = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|H", &options) == FAILURE) {
return;
@@ -461,6 +501,9 @@ static PHP_FUNCTION(phpdbg_end_oplog)
return;
}
+ cur = PHPDBG_G(oplog_list)->start;
+ prev = PHPDBG_G(oplog_list)->prev;
+
efree(PHPDBG_G(oplog_list));
PHPDBG_G(oplog_list) = prev;
@@ -474,6 +517,10 @@ static PHP_FUNCTION(phpdbg_end_oplog)
}
}
+ if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("show_unexecuted")))) {
+ show_unexecuted = zend_is_true(option_buffer);
+ }
+
array_init(return_value);
{
@@ -488,6 +535,9 @@ static PHP_FUNCTION(phpdbg_end_oplog)
do {
zend_op_array *op_array = cur->op_array;
+ zval zero;
+ ZVAL_LONG(&zero, 0);
+
if (op_array->filename != last_file) {
last_file = op_array->filename;
file_buf = zend_hash_find(Z_ARR_P(return_value), last_file);
@@ -495,28 +545,41 @@ static PHP_FUNCTION(phpdbg_end_oplog)
zval ht;
array_init(&ht);
file_buf = zend_hash_add_new(Z_ARR_P(return_value), last_file, &ht);
+
+ if (show_unexecuted) {
+ phpdbg_oplog_fill_executable(op_array, Z_ARR_P(file_buf), by_opcode);
+ }
}
+ insert_ht = Z_ARR_P(file_buf);
}
- insert_ht = Z_ARR_P(file_buf);
if (by_function) {
- if (op_array->function_name != last_function || op_array->scope != last_scope) {
+ if (op_array->function_name == NULL) {
+ if (last_function != NULL) {
+ insert_ht = Z_ARR_P(file_buf);
+ }
+ last_function = NULL;
+ } else if (op_array->function_name != last_function || op_array->scope != last_scope) {
zend_string *fn_name;
last_function = op_array->function_name;
last_scope = op_array->scope;
if (last_scope == NULL) {
fn_name = zend_string_copy(last_function);
} else {
- fn_name = strpprintf(ZSTR_LEN(last_function) + ZSTR_LEN(last_scope->name) + 2, "%.*s::%.*s", ZSTR_LEN(last_function), ZSTR_VAL(last_function), ZSTR_LEN(last_scope->name), ZSTR_VAL(last_scope->name));
+ fn_name = strpprintf(ZSTR_LEN(last_function) + ZSTR_LEN(last_scope->name) + 2, "%.*s::%.*s", ZSTR_LEN(last_scope->name), ZSTR_VAL(last_scope->name), ZSTR_LEN(last_function), ZSTR_VAL(last_function));
}
fn_buf = zend_hash_find(Z_ARR_P(return_value), fn_name);
if (!fn_buf) {
zval ht;
array_init(&ht);
fn_buf = zend_hash_add_new(Z_ARR_P(return_value), fn_name, &ht);
+
+ if (show_unexecuted) {
+ phpdbg_oplog_fill_executable(op_array, Z_ARR_P(fn_buf), by_opcode);
+ }
}
+ insert_ht = Z_ARR_P(fn_buf);
}
- insert_ht = Z_ARR_P(fn_buf);
}
if (by_opcode) {
@@ -528,9 +591,7 @@ static PHP_FUNCTION(phpdbg_end_oplog)
{
zval *num = zend_hash_index_find(insert_ht, insert_idx);
if (!num) {
- zval zv;
- ZVAL_LONG(&zv, 0);
- num = zend_hash_index_add_new(insert_ht, insert_idx, &zv);
+ num = zend_hash_index_add_new(insert_ht, insert_idx, &zero);
}
Z_LVAL_P(num)++;
}
@@ -709,6 +770,8 @@ static int php_sapi_phpdbg_deactivate(void) /* {{{ */
pg->prompt[1] = PHPDBG_G(prompt)[1];
memcpy(pg->colors, PHPDBG_G(colors), sizeof(pg->colors));
pg->eol = PHPDBG_G(eol);
+ pg->input_buflen = PHPDBG_G(input_buflen);
+ memcpy(pg->input_buffer, PHPDBG_G(input_buffer), pg->input_buflen);
pg->flags = PHPDBG_G(flags) & PHPDBG_PRESERVE_FLAGS_MASK;
}
@@ -1169,7 +1232,7 @@ int main(int argc, char **argv) /* {{{ */
char *php_optarg;
int php_optind, opt, show_banner = 1;
long cleaning = -1;
- zend_bool quit_immediately = 0;
+ volatile zend_bool quit_immediately = 0; /* somehow some gcc release builds will play a bit around with order in combination with setjmp..., hence volatile */
zend_bool remote = 0;
zend_phpdbg_globals *settings = NULL;
char *bp_tmp = NULL;
@@ -1390,11 +1453,8 @@ phpdbg_main:
}
/* set exec if present on command line */
- if (!exec && (argc > php_optind) && (strcmp(argv[php_optind-1], "--") != SUCCESS)) {
- if (strlen(argv[php_optind])) {
- if (exec) {
- free(exec);
- }
+ if (argc > php_optind && (strcmp(argv[php_optind-1], "--") != SUCCESS)) {
+ if (!exec && strlen(argv[php_optind])) {
exec = strdup(argv[php_optind]);
}
php_optind++;
@@ -1473,7 +1533,7 @@ phpdbg_main:
/* setup remote server if necessary */
if (cleaning <= 0 && listen > 0) {
server = phpdbg_open_socket(address, listen);
- if (-1 > server || phpdbg_remote_init(address, listen, server, &socket, &stream) == FAILURE) {
+ if (-1 > server || phpdbg_remote_init(address, listen, server, &socket, &stream) == FAILURE) {
exit(0);
}
@@ -1525,6 +1585,14 @@ phpdbg_main:
PHPDBG_G(sapi_name_ptr) = sapi_name;
+ if (exec) { /* set execution context */
+ PHPDBG_G(exec) = phpdbg_resolve_path(exec);
+ PHPDBG_G(exec_len) = PHPDBG_G(exec) ? strlen(PHPDBG_G(exec)) : 0;
+
+ free(exec);
+ exec = NULL;
+ }
+
php_output_activate();
php_output_deactivate();
@@ -1538,7 +1606,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 ? estrdup(exec) : estrdup("");
+ SG(request_info).argv[0] = PHPDBG_G(exec) ? estrdup(PHPDBG_G(exec)) : estrdup("");
php_hash_environment();
}
@@ -1599,14 +1667,6 @@ phpdbg_main:
php_stream_stdio_ops.write = phpdbg_stdiop_write;
#endif
- if (exec) { /* set execution context */
- PHPDBG_G(exec) = phpdbg_resolve_path(exec);
- PHPDBG_G(exec_len) = PHPDBG_G(exec) ? strlen(PHPDBG_G(exec)) : 0;
-
- free(exec);
- exec = NULL;
- }
-
if (oplog_file) { /* open oplog */
PHPDBG_G(oplog) = fopen(oplog_file, "w+");
if (!PHPDBG_G(oplog)) {
@@ -1654,7 +1714,7 @@ phpdbg_main:
/* auto compile */
if (PHPDBG_G(exec)) {
- if (settings) {
+ if (settings || phpdbg_startup_run > 0) {
PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT;
}
@@ -1674,6 +1734,8 @@ phpdbg_main:
goto phpdbg_out;
}
+ PG(during_request_startup) = 0;
+
phpdbg_fully_started = 1;
/* #ifndef for making compiler shutting up */
@@ -1771,7 +1833,7 @@ phpdbg_out:
{
int i;
/* free argv */
- for (i = SG(request_info).argc; --i;) {
+ for (i = SG(request_info).argc; i--;) {
efree(SG(request_info).argv[i]);
}
efree(SG(request_info).argv);
@@ -1813,7 +1875,9 @@ phpdbg_out:
} zend_end_try();
if ((PHPDBG_G(flags) & (PHPDBG_IS_QUITTING | PHPDBG_IS_RUNNING)) == PHPDBG_IS_RUNNING) {
- phpdbg_notice("stop", "type=\"normal\"", "Script ended normally");
+ if (!quit_immediately && !phpdbg_startup_run) {
+ phpdbg_notice("stop", "type=\"normal\"", "Script ended normally");
+ }
cleaning++;
}
@@ -1832,6 +1896,9 @@ phpdbg_out:
}
if ((cleaning > 0 || remote) && !quit_immediately) {
+ /* reset internal php_getopt state */
+ php_getopt(-1, argv, OPTIONS, NULL, &php_optind, 0, 0);
+
goto phpdbg_main;
}