mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
Merge branch 'PHP-7.0' into PHP-7.1
(cherry picked from commit 37ae5f3931
)
This commit is contained in:
parent
a8a11b669d
commit
11e7447e04
@ -127,7 +127,7 @@ if (getenv('TEST_PHP_EXECUTABLE')) {
|
|||||||
$phpdbg = $cwd . '/sapi/phpdbg/phpdbg';
|
$phpdbg = $cwd . '/sapi/phpdbg/phpdbg';
|
||||||
|
|
||||||
if (file_exists($phpdbg)) {
|
if (file_exists($phpdbg)) {
|
||||||
putenv("TEST_PHP_CGI_EXECUTABLE=$phpdbg");
|
putenv("TEST_PHPDBG_EXECUTABLE=$phpdbg");
|
||||||
} else {
|
} else {
|
||||||
$phpdbg = null;
|
$phpdbg = null;
|
||||||
}
|
}
|
||||||
|
@ -127,6 +127,7 @@ static void php_phpdbg_destroy_file_source(zval *data) /* {{{ */
|
|||||||
if (source->buf) {
|
if (source->buf) {
|
||||||
efree(source->buf);
|
efree(source->buf);
|
||||||
}
|
}
|
||||||
|
efree(source->filename);
|
||||||
efree(source);
|
efree(source);
|
||||||
} /* }}} */
|
} /* }}} */
|
||||||
|
|
||||||
@ -373,7 +374,7 @@ static PHP_FUNCTION(phpdbg_break_file)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
phpdbg_set_breakpoint_file(file, line);
|
phpdbg_set_breakpoint_file(file, 0, line);
|
||||||
} /* }}} */
|
} /* }}} */
|
||||||
|
|
||||||
/* {{{ proto void phpdbg_break_method(string class, string method) */
|
/* {{{ proto void phpdbg_break_method(string class, string method) */
|
||||||
@ -1076,6 +1077,7 @@ const opt_struct OPTIONS[] = { /* {{{ */
|
|||||||
{'r', 0, "run"},
|
{'r', 0, "run"},
|
||||||
{'e', 0, "generate ext_stmt opcodes"},
|
{'e', 0, "generate ext_stmt opcodes"},
|
||||||
{'E', 0, "step-through-eval"},
|
{'E', 0, "step-through-eval"},
|
||||||
|
{'s', 1, "script from stdin"},
|
||||||
{'S', 1, "sapi-name"},
|
{'S', 1, "sapi-name"},
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
{'l', 1, "listen"},
|
{'l', 1, "listen"},
|
||||||
@ -1374,6 +1376,8 @@ int main(int argc, char **argv) /* {{{ */
|
|||||||
zend_bool ext_stmt = 0;
|
zend_bool ext_stmt = 0;
|
||||||
zend_bool is_exit;
|
zend_bool is_exit;
|
||||||
int exit_status;
|
int exit_status;
|
||||||
|
char *read_from_stdin = NULL;
|
||||||
|
zend_string *backup_phpdbg_compile = NULL;
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
struct sigaction sigio_struct;
|
struct sigaction sigio_struct;
|
||||||
@ -1482,6 +1486,12 @@ phpdbg_main:
|
|||||||
|
|
||||||
/* begin phpdbg options */
|
/* begin phpdbg options */
|
||||||
|
|
||||||
|
case 's': { /* read script from stdin */
|
||||||
|
if (settings == NULL) {
|
||||||
|
read_from_stdin = strdup(php_optarg);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
case 'S': { /* set SAPI name */
|
case 'S': { /* set SAPI name */
|
||||||
sapi_name = strdup(php_optarg);
|
sapi_name = strdup(php_optarg);
|
||||||
} break;
|
} break;
|
||||||
@ -1593,8 +1603,10 @@ phpdbg_main:
|
|||||||
php_optarg = NULL;
|
php_optarg = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
quit_immediately = phpdbg_startup_run > 1;
|
||||||
|
|
||||||
/* set exec if present on command line */
|
/* set exec if present on command line */
|
||||||
if (argc > php_optind && (strcmp(argv[php_optind-1], "--") != SUCCESS)) {
|
if (!read_from_stdin && argc > php_optind && (strcmp(argv[php_optind-1], "--") != SUCCESS)) {
|
||||||
if (!exec && strlen(argv[php_optind])) {
|
if (!exec && strlen(argv[php_optind])) {
|
||||||
exec = strdup(argv[php_optind]);
|
exec = strdup(argv[php_optind]);
|
||||||
}
|
}
|
||||||
@ -1849,13 +1861,6 @@ phpdbg_main:
|
|||||||
if (init_file) {
|
if (init_file) {
|
||||||
phpdbg_init(init_file, init_file_len, init_file_default);
|
phpdbg_init(init_file, init_file_len, init_file_default);
|
||||||
}
|
}
|
||||||
if (bp_tmp) {
|
|
||||||
PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT;
|
|
||||||
phpdbg_string_init(bp_tmp);
|
|
||||||
free(bp_tmp);
|
|
||||||
bp_tmp = NULL;
|
|
||||||
PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT;
|
|
||||||
}
|
|
||||||
} zend_end_try();
|
} zend_end_try();
|
||||||
PHPDBG_G(flags) &= ~PHPDBG_IS_INITIALIZING;
|
PHPDBG_G(flags) &= ~PHPDBG_IS_INITIALIZING;
|
||||||
|
|
||||||
@ -1865,18 +1870,55 @@ phpdbg_main:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* auto compile */
|
/* auto compile */
|
||||||
if (PHPDBG_G(exec)) {
|
if (read_from_stdin) {
|
||||||
|
if (!read_from_stdin[0]) {
|
||||||
|
if (!quit_immediately) {
|
||||||
|
phpdbg_error("error", "", "Impossible to not specify a stdin delimiter without -rr");
|
||||||
|
PHPDBG_G(flags) |= PHPDBG_IS_QUITTING;
|
||||||
|
goto phpdbg_out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (show_banner || read_from_stdin[0]) {
|
||||||
|
phpdbg_notice("stdin", "delimiter=\"%s\"", "Reading input from stdin; put '%s' followed by a newline on an own line after code to end input", read_from_stdin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phpdbg_startup_run > 0) {
|
||||||
|
PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
zend_try {
|
||||||
|
phpdbg_param_t cmd;
|
||||||
|
cmd.str = read_from_stdin;
|
||||||
|
cmd.len = strlen(read_from_stdin);
|
||||||
|
PHPDBG_COMMAND_HANDLER(stdin)(&cmd);
|
||||||
|
} zend_end_try();
|
||||||
|
|
||||||
|
PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT;
|
||||||
|
} else if (PHPDBG_G(exec)) {
|
||||||
if (settings || phpdbg_startup_run > 0) {
|
if (settings || phpdbg_startup_run > 0) {
|
||||||
PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT;
|
PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
zend_try {
|
zend_try {
|
||||||
|
if (backup_phpdbg_compile) {
|
||||||
|
phpdbg_compile_stdin(backup_phpdbg_compile);
|
||||||
|
} else {
|
||||||
phpdbg_compile();
|
phpdbg_compile();
|
||||||
|
}
|
||||||
} zend_end_try();
|
} zend_end_try();
|
||||||
|
backup_phpdbg_compile = NULL;
|
||||||
|
|
||||||
PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT;
|
PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bp_tmp) {
|
||||||
|
PHPDBG_G(flags) |= PHPDBG_DISCARD_OUTPUT | PHPDBG_IS_INITIALIZING;
|
||||||
|
phpdbg_string_init(bp_tmp);
|
||||||
|
free(bp_tmp);
|
||||||
|
bp_tmp = NULL;
|
||||||
|
PHPDBG_G(flags) &= ~PHPDBG_DISCARD_OUTPUT & ~PHPDBG_IS_INITIALIZING;
|
||||||
|
}
|
||||||
|
|
||||||
if (settings == (void *) 0x1) {
|
if (settings == (void *) 0x1) {
|
||||||
if (PHPDBG_G(ops)) {
|
if (PHPDBG_G(ops)) {
|
||||||
phpdbg_print_opcodes(print_opline_func);
|
phpdbg_print_opcodes(print_opline_func);
|
||||||
@ -1898,7 +1940,6 @@ phpdbg_interact:
|
|||||||
do {
|
do {
|
||||||
zend_try {
|
zend_try {
|
||||||
if (phpdbg_startup_run) {
|
if (phpdbg_startup_run) {
|
||||||
quit_immediately = phpdbg_startup_run > 1;
|
|
||||||
phpdbg_startup_run = 0;
|
phpdbg_startup_run = 0;
|
||||||
if (quit_immediately) {
|
if (quit_immediately) {
|
||||||
PHPDBG_G(flags) = (PHPDBG_G(flags) & ~PHPDBG_HAS_PAGINATION) | PHPDBG_IS_INTERACTIVE | PHPDBG_PREVENT_INTERACTIVE;
|
PHPDBG_G(flags) = (PHPDBG_G(flags) & ~PHPDBG_HAS_PAGINATION) | PHPDBG_IS_INTERACTIVE | PHPDBG_PREVENT_INTERACTIVE;
|
||||||
@ -2073,6 +2114,12 @@ phpdbg_out:
|
|||||||
wrapper->wops->stream_opener = PHPDBG_G(orig_url_wrap_php);
|
wrapper->wops->stream_opener = PHPDBG_G(orig_url_wrap_php);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PHPDBG_G(exec) && !memcmp("-", PHPDBG_G(exec), 2)) { /* i.e. execution context has been read from stdin - back it up */
|
||||||
|
phpdbg_file_source *data = zend_hash_str_find_ptr(&PHPDBG_G(file_sources), PHPDBG_G(exec), PHPDBG_G(exec_len));
|
||||||
|
backup_phpdbg_compile = zend_string_alloc(data->len + 2, 1);
|
||||||
|
sprintf(ZSTR_VAL(backup_phpdbg_compile), "?>%.*s", (int) data->len, data->buf);
|
||||||
|
}
|
||||||
|
|
||||||
zend_try {
|
zend_try {
|
||||||
php_module_shutdown();
|
php_module_shutdown();
|
||||||
} zend_end_try();
|
} zend_end_try();
|
||||||
@ -2097,6 +2144,11 @@ phpdbg_out:
|
|||||||
free(sapi_name);
|
free(sapi_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (read_from_stdin) {
|
||||||
|
free(read_from_stdin);
|
||||||
|
read_from_stdin = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef ZTS
|
#ifdef ZTS
|
||||||
tsrm_shutdown();
|
tsrm_shutdown();
|
||||||
#endif
|
#endif
|
||||||
@ -2108,6 +2160,10 @@ phpdbg_out:
|
|||||||
goto phpdbg_main;
|
goto phpdbg_main;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (backup_phpdbg_compile) {
|
||||||
|
zend_string_free(backup_phpdbg_compile);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
if (address) {
|
if (address) {
|
||||||
free(address);
|
free(address);
|
||||||
|
@ -230,7 +230,7 @@ PHPDBG_API void phpdbg_export_breakpoints_to_string(char **str) /* {{{ */
|
|||||||
}
|
}
|
||||||
} /* }}} */
|
} /* }}} */
|
||||||
|
|
||||||
PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num) /* {{{ */
|
PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, size_t path_len, long line_num) /* {{{ */
|
||||||
{
|
{
|
||||||
php_stream_statbuf ssb;
|
php_stream_statbuf ssb;
|
||||||
char realpath[MAXPATHLEN];
|
char realpath[MAXPATHLEN];
|
||||||
@ -240,11 +240,12 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num) /* {
|
|||||||
|
|
||||||
HashTable *broken, *file_breaks = &PHPDBG_G(bp)[PHPDBG_BREAK_FILE];
|
HashTable *broken, *file_breaks = &PHPDBG_G(bp)[PHPDBG_BREAK_FILE];
|
||||||
phpdbg_breakfile_t new_break;
|
phpdbg_breakfile_t new_break;
|
||||||
size_t path_len = 0L;
|
|
||||||
|
|
||||||
|
if (!path_len) {
|
||||||
if (VCWD_REALPATH(path, realpath)) {
|
if (VCWD_REALPATH(path, realpath)) {
|
||||||
path = realpath;
|
path = realpath;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
path_len = strlen(path);
|
path_len = strlen(path);
|
||||||
|
|
||||||
phpdbg_debug("file path: %s, resolved path: %s, was compiled: %d\n", original_path, path, zend_hash_str_exists(&PHPDBG_G(file_sources), path, path_len));
|
phpdbg_debug("file path: %s, resolved path: %s, was compiled: %d\n", original_path, path, zend_hash_str_exists(&PHPDBG_G(file_sources), path, path_len));
|
||||||
@ -886,21 +887,13 @@ static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_file(zend_op_array *op_
|
|||||||
{
|
{
|
||||||
HashTable *breaks;
|
HashTable *breaks;
|
||||||
phpdbg_breakbase_t *brake;
|
phpdbg_breakbase_t *brake;
|
||||||
size_t path_len;
|
|
||||||
char realpath[MAXPATHLEN];
|
|
||||||
const char *path = ZSTR_VAL(op_array->filename);
|
|
||||||
|
|
||||||
if (VCWD_REALPATH(path, realpath)) {
|
|
||||||
path = realpath;
|
|
||||||
}
|
|
||||||
|
|
||||||
path_len = strlen(path);
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
phpdbg_debug("Op at: %.*s %d\n", path_len, path, (*EG(opline_ptr))->lineno);
|
phpdbg_debug("Op at: %.*s %d\n", ZSTR_LEN(op_array->filename), ZSTR_VAL(op_array->filename), (*EG(opline_ptr))->lineno);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!(breaks = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], path, path_len))) {
|
/* NOTE: realpath resolution should have happened at compile time - no reason to do it here again */
|
||||||
|
if (!(breaks = zend_hash_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], op_array->filename))) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ PHPDBG_API HashTable *phpdbg_resolve_pending_file_break_ex(const char *file, uin
|
|||||||
PHPDBG_API void phpdbg_resolve_pending_file_break(const char *file); /* }}} */
|
PHPDBG_API void phpdbg_resolve_pending_file_break(const char *file); /* }}} */
|
||||||
|
|
||||||
/* {{{ Breakpoint Creation API */
|
/* {{{ Breakpoint Creation API */
|
||||||
PHPDBG_API void phpdbg_set_breakpoint_file(const char* filename, long lineno);
|
PHPDBG_API void phpdbg_set_breakpoint_file(const char* filename, size_t path_len, long lineno);
|
||||||
PHPDBG_API void phpdbg_set_breakpoint_symbol(const char* func_name, size_t func_name_len);
|
PHPDBG_API void phpdbg_set_breakpoint_symbol(const char* func_name, size_t func_name_len);
|
||||||
PHPDBG_API void phpdbg_set_breakpoint_method(const char* class_name, const char* func_name);
|
PHPDBG_API void phpdbg_set_breakpoint_method(const char* class_name, const char* func_name);
|
||||||
PHPDBG_API void phpdbg_set_breakpoint_opcode(const char* opname, size_t opname_len);
|
PHPDBG_API void phpdbg_set_breakpoint_opcode(const char* opname, size_t opname_len);
|
||||||
|
@ -339,6 +339,7 @@ phpdbg_help_text_t phpdbg_help_text[] = {
|
|||||||
|
|
||||||
"**Starting and Stopping Execution**" CR
|
"**Starting and Stopping Execution**" CR
|
||||||
" **exec** set execution context" CR
|
" **exec** set execution context" CR
|
||||||
|
" **stdin** set executing script from stdin" CR
|
||||||
" **run** attempt execution" CR
|
" **run** attempt execution" CR
|
||||||
" **step** continue execution until other line is reached" CR
|
" **step** continue execution until other line is reached" CR
|
||||||
" **continue** continue execution" CR
|
" **continue** continue execution" CR
|
||||||
@ -387,6 +388,7 @@ phpdbg_help_text_t phpdbg_help_text[] = {
|
|||||||
" **-rr** Run execution context and quit after execution (not respecting breakpoints)" CR
|
" **-rr** Run execution context and quit after execution (not respecting breakpoints)" CR
|
||||||
" **-e** Generate extended information for debugger/profiler" CR
|
" **-e** Generate extended information for debugger/profiler" CR
|
||||||
" **-E** Enable step through eval, careful!" CR
|
" **-E** Enable step through eval, careful!" CR
|
||||||
|
" **-s** **-s=**, **-s**=foo Read code to execute from stdin with an optional delimiter" CR
|
||||||
" **-S** **-S**cli Override SAPI name, careful!" CR
|
" **-S** **-S**cli Override SAPI name, careful!" CR
|
||||||
" **-l** **-l**4000 Setup remote console ports" CR
|
" **-l** **-l**4000 Setup remote console ports" CR
|
||||||
" **-a** **-a**192.168.0.3 Setup remote console bind address" CR
|
" **-a** **-a**192.168.0.3 Setup remote console bind address" CR
|
||||||
@ -397,6 +399,13 @@ phpdbg_help_text_t phpdbg_help_text[] = {
|
|||||||
" **--** **--** arg1 arg2 Use to delimit phpdbg arguments and php $argv; append any $argv "
|
" **--** **--** arg1 arg2 Use to delimit phpdbg arguments and php $argv; append any $argv "
|
||||||
"argument after it" CR CR
|
"argument after it" CR CR
|
||||||
|
|
||||||
|
"**Reading from stdin**" CR CR
|
||||||
|
|
||||||
|
"The **-s** option allows inputting a script to execute directly from stdin. The given delimiter "
|
||||||
|
"(\"foo\" in the example) needs to be specified at the end of the input on its own line, followed by "
|
||||||
|
"a line break. If **-rr** has been specified, it is allowed to omit the delimiter (**-s=**) and "
|
||||||
|
"it will read until EOF. See also the help entry for the **stdin** command." CR CR
|
||||||
|
|
||||||
"**Remote Console Mode**" CR CR
|
"**Remote Console Mode**" CR CR
|
||||||
|
|
||||||
"This mode is enabled by specifying the **-a** option. Phpdbg will bind only to the loopback "
|
"This mode is enabled by specifying the **-a** option. Phpdbg will bind only to the loopback "
|
||||||
@ -635,6 +644,21 @@ phpdbg_help_text_t phpdbg_help_text[] = {
|
|||||||
" Set the execution context to **/tmp/script.php**"
|
" Set the execution context to **/tmp/script.php**"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{"stdin",
|
||||||
|
"The **stdin** command takes a string serving as delimiter. It will then read all the input from "
|
||||||
|
"stdin until encountering the given delimiter on a standalone line. It can also be passed at "
|
||||||
|
"startup using the **-s=** command line option (the delimiter then is optional if **-rr** is "
|
||||||
|
"also passed - in that case it will just read until EOF)." CR
|
||||||
|
"This input will be then compiled as PHP code and set as execution context." CR CR
|
||||||
|
|
||||||
|
"**Example**" CR CR
|
||||||
|
|
||||||
|
" $P stdin foo" CR
|
||||||
|
" <?php" CR
|
||||||
|
" echo \"Hello, world!\\n\";" CR
|
||||||
|
" foo"
|
||||||
|
},
|
||||||
|
|
||||||
//*********** Does F skip any breakpoints lower stack frames or only the current??
|
//*********** Does F skip any breakpoints lower stack frames or only the current??
|
||||||
{"finish",
|
{"finish",
|
||||||
"The **finish** command causes control to be passed back to the vm, continuing execution. Any "
|
"The **finish** command causes control to be passed back to the vm, continuing execution. Any "
|
||||||
|
@ -62,9 +62,15 @@ PHPDBG_LIST(lines) /* {{{ */
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
case FILE_PARAM: {
|
case FILE_PARAM: {
|
||||||
zend_string *file = zend_string_init(param->file.name, strlen(param->file.name), 0);
|
zend_string *file;
|
||||||
|
char resolved_path_buf[MAXPATHLEN];
|
||||||
|
const char *abspath = param->file.name;
|
||||||
|
if (VCWD_REALPATH(abspath, resolved_path_buf)) {
|
||||||
|
abspath = resolved_path_buf;
|
||||||
|
}
|
||||||
|
file = zend_string_init(abspath, strlen(abspath), 0);
|
||||||
phpdbg_list_file(file, param->file.line, 0, 0);
|
phpdbg_list_file(file, param->file.line, 0, 0);
|
||||||
efree(file);
|
zend_string_release(file);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
phpdbg_default_switch_case();
|
phpdbg_default_switch_case();
|
||||||
@ -127,16 +133,8 @@ void phpdbg_list_file(zend_string *filename, uint count, int offset, uint highli
|
|||||||
{
|
{
|
||||||
uint line, lastline;
|
uint line, lastline;
|
||||||
phpdbg_file_source *data;
|
phpdbg_file_source *data;
|
||||||
char resolved_path_buf[MAXPATHLEN];
|
|
||||||
const char *abspath;
|
|
||||||
|
|
||||||
if (VCWD_REALPATH(ZSTR_VAL(filename), resolved_path_buf)) {
|
if (!(data = zend_hash_find_ptr(&PHPDBG_G(file_sources), filename))) {
|
||||||
abspath = resolved_path_buf;
|
|
||||||
} else {
|
|
||||||
abspath = ZSTR_VAL(filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(data = zend_hash_str_find_ptr(&PHPDBG_G(file_sources), abspath, strlen(abspath)))) {
|
|
||||||
phpdbg_error("list", "type=\"unknownfile\"", "Could not find information about included file...");
|
phpdbg_error("list", "type=\"unknownfile\"", "Could not find information about included file...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -288,6 +286,7 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dataptr->filename = estrdup(dataptr->filename);
|
||||||
dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line);
|
dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line);
|
||||||
zend_hash_str_add_ptr(&PHPDBG_G(file_sources), filename, strlen(filename), dataptr);
|
zend_hash_str_add_ptr(&PHPDBG_G(file_sources), filename, strlen(filename), dataptr);
|
||||||
phpdbg_resolve_pending_file_break(filename);
|
phpdbg_resolve_pending_file_break(filename);
|
||||||
@ -306,6 +305,17 @@ zend_op_array *phpdbg_init_compile_file(zend_file_handle *file, int type) {
|
|||||||
|
|
||||||
if (VCWD_REALPATH(filename, resolved_path_buf)) {
|
if (VCWD_REALPATH(filename, resolved_path_buf)) {
|
||||||
filename = resolved_path_buf;
|
filename = resolved_path_buf;
|
||||||
|
|
||||||
|
if (file->opened_path) {
|
||||||
|
zend_string_release(file->opened_path);
|
||||||
|
file->opened_path = zend_string_init(filename, strlen(filename), 0);
|
||||||
|
} else {
|
||||||
|
if (file->free_filename) {
|
||||||
|
efree((char *) file->filename);
|
||||||
|
}
|
||||||
|
file->free_filename = 1;
|
||||||
|
file->filename = estrdup(filename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
op_array = PHPDBG_G(init_compile_file)(file, type);
|
op_array = PHPDBG_G(init_compile_file)(file, type);
|
||||||
@ -356,7 +366,7 @@ zend_op_array *phpdbg_compile_string(zval *source_string, char *filename) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fake_name = strpprintf(0, "%s\0%p", filename, op_array->opcodes);
|
fake_name = strpprintf(0, "%s%c%p", filename, 0, op_array->opcodes);
|
||||||
|
|
||||||
dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line);
|
dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line);
|
||||||
zend_hash_add_ptr(&PHPDBG_G(file_sources), fake_name, dataptr);
|
zend_hash_add_ptr(&PHPDBG_G(file_sources), fake_name, dataptr);
|
||||||
|
@ -26,7 +26,9 @@
|
|||||||
#include "zend_vm.h"
|
#include "zend_vm.h"
|
||||||
#include "zend_generators.h"
|
#include "zend_generators.h"
|
||||||
#include "zend_interfaces.h"
|
#include "zend_interfaces.h"
|
||||||
|
#include "zend_smart_str.h"
|
||||||
#include "phpdbg.h"
|
#include "phpdbg.h"
|
||||||
|
#include "phpdbg_io.h"
|
||||||
|
|
||||||
#include "phpdbg_help.h"
|
#include "phpdbg_help.h"
|
||||||
#include "phpdbg_print.h"
|
#include "phpdbg_print.h"
|
||||||
@ -68,6 +70,7 @@ extern int phpdbg_startup_run;
|
|||||||
/* {{{ command declarations */
|
/* {{{ command declarations */
|
||||||
const phpdbg_command_t phpdbg_prompt_commands[] = {
|
const phpdbg_command_t phpdbg_prompt_commands[] = {
|
||||||
PHPDBG_COMMAND_D(exec, "set execution context", 'e', NULL, "s", 0),
|
PHPDBG_COMMAND_D(exec, "set execution context", 'e', NULL, "s", 0),
|
||||||
|
PHPDBG_COMMAND_D(stdin, "read script from stdin", 0 , NULL, "s", 0),
|
||||||
PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, 0, PHPDBG_ASYNC_SAFE),
|
PHPDBG_COMMAND_D(step, "step through execution", 's', NULL, 0, PHPDBG_ASYNC_SAFE),
|
||||||
PHPDBG_COMMAND_D(continue, "continue execution", 'c', NULL, 0, PHPDBG_ASYNC_SAFE),
|
PHPDBG_COMMAND_D(continue, "continue execution", 'c', NULL, 0, PHPDBG_ASYNC_SAFE),
|
||||||
PHPDBG_COMMAND_D(run, "attempt execution", 'r', NULL, "|s", 0),
|
PHPDBG_COMMAND_D(run, "attempt execution", 'r', NULL, "|s", 0),
|
||||||
@ -459,6 +462,111 @@ PHPDBG_COMMAND(exec) /* {{{ */
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
} /* }}} */
|
} /* }}} */
|
||||||
|
|
||||||
|
PHPDBG_COMMAND(stdin)
|
||||||
|
{
|
||||||
|
smart_str code = {0};
|
||||||
|
char *buf;
|
||||||
|
char *sep = param->str;
|
||||||
|
int seplen = param->len;
|
||||||
|
int bytes = 0;
|
||||||
|
|
||||||
|
smart_str_appends(&code, "?>");
|
||||||
|
|
||||||
|
do {
|
||||||
|
PHPDBG_G(input_buflen) += bytes;
|
||||||
|
if (PHPDBG_G(input_buflen) <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sep && seplen) {
|
||||||
|
char *nl = buf = PHPDBG_G(input_buffer);
|
||||||
|
do {
|
||||||
|
if (buf == nl + seplen) {
|
||||||
|
if (!memcmp(sep, nl, seplen) && (*buf == '\n' || (*buf == '\r' && buf[1] == '\n'))) {
|
||||||
|
smart_str_appendl(&code, PHPDBG_G(input_buffer), nl - PHPDBG_G(input_buffer));
|
||||||
|
memmove(PHPDBG_G(input_buffer), ++buf, --PHPDBG_G(input_buflen));
|
||||||
|
goto exec_code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*buf == '\n') {
|
||||||
|
nl = buf + 1;
|
||||||
|
}
|
||||||
|
buf++;
|
||||||
|
} while (--PHPDBG_G(input_buflen));
|
||||||
|
if (buf != nl && buf <= nl + seplen) {
|
||||||
|
smart_str_appendl(&code, PHPDBG_G(input_buffer), nl - PHPDBG_G(input_buffer));
|
||||||
|
PHPDBG_G(input_buflen) = buf - nl;
|
||||||
|
memmove(PHPDBG_G(input_buffer), nl, PHPDBG_G(input_buflen));
|
||||||
|
} else {
|
||||||
|
PHPDBG_G(input_buflen) = 0;
|
||||||
|
smart_str_appendl(&code, PHPDBG_G(input_buffer), buf - PHPDBG_G(input_buffer));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
smart_str_appendl(&code, PHPDBG_G(input_buffer), PHPDBG_G(input_buflen));
|
||||||
|
PHPDBG_G(input_buflen) = 0;
|
||||||
|
}
|
||||||
|
} while ((bytes = phpdbg_mixed_read(PHPDBG_G(io)[PHPDBG_STDIN].fd, PHPDBG_G(input_buffer) + PHPDBG_G(input_buflen), PHPDBG_MAX_CMD - PHPDBG_G(input_buflen), -1)) > 0);
|
||||||
|
|
||||||
|
if (bytes < 0) {
|
||||||
|
PHPDBG_G(flags) |= PHPDBG_IS_QUITTING | PHPDBG_IS_DISCONNECTED;
|
||||||
|
zend_bailout();
|
||||||
|
}
|
||||||
|
|
||||||
|
exec_code:
|
||||||
|
smart_str_0(&code);
|
||||||
|
|
||||||
|
if (phpdbg_compile_stdin(code.s) == FAILURE) {
|
||||||
|
zend_exception_error(EG(exception), E_ERROR);
|
||||||
|
zend_bailout();
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
} /* }}} */
|
||||||
|
|
||||||
|
int phpdbg_compile_stdin(zend_string *code) {
|
||||||
|
zval zv;
|
||||||
|
|
||||||
|
ZVAL_STR(&zv, code);
|
||||||
|
|
||||||
|
PHPDBG_G(ops) = zend_compile_string(&zv, "-");
|
||||||
|
|
||||||
|
zend_string_release(code);
|
||||||
|
|
||||||
|
if (EG(exception)) {
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PHPDBG_G(exec)) {
|
||||||
|
efree(PHPDBG_G(exec));
|
||||||
|
}
|
||||||
|
PHPDBG_G(exec) = estrdup("-");
|
||||||
|
PHPDBG_G(exec_len) = 1;
|
||||||
|
{ /* remove leading ?> from source */
|
||||||
|
int i;
|
||||||
|
zend_string *source_path = zend_strpprintf(0, "-%c%p", 0, PHPDBG_G(ops)->opcodes);
|
||||||
|
phpdbg_file_source *data = zend_hash_find_ptr(&PHPDBG_G(file_sources), source_path);
|
||||||
|
dtor_func_t dtor = PHPDBG_G(file_sources).pDestructor;
|
||||||
|
PHPDBG_G(file_sources).pDestructor = NULL;
|
||||||
|
zend_hash_del(&PHPDBG_G(file_sources), source_path);
|
||||||
|
PHPDBG_G(file_sources).pDestructor = dtor;
|
||||||
|
zend_hash_str_update_ptr(&PHPDBG_G(file_sources), "-", 1, data);
|
||||||
|
zend_string_release(source_path);
|
||||||
|
|
||||||
|
efree(data->filename);
|
||||||
|
data->filename = estrdup("-");
|
||||||
|
|
||||||
|
for (i = 1; i <= data->lines; i++) {
|
||||||
|
data->line[i] -= 2;
|
||||||
|
}
|
||||||
|
data->len -= 2;
|
||||||
|
memmove(data->buf, data->buf + 2, data->len);
|
||||||
|
}
|
||||||
|
|
||||||
|
phpdbg_notice("compile", "context=\"-\"", "Successful compilation of stdin input");
|
||||||
|
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int phpdbg_compile(void) /* {{{ */
|
int phpdbg_compile(void) /* {{{ */
|
||||||
{
|
{
|
||||||
zend_file_handle fh;
|
zend_file_handle fh;
|
||||||
@ -1066,16 +1174,21 @@ PHPDBG_COMMAND(set) /* {{{ */
|
|||||||
PHPDBG_COMMAND(break) /* {{{ */
|
PHPDBG_COMMAND(break) /* {{{ */
|
||||||
{
|
{
|
||||||
if (!param) {
|
if (!param) {
|
||||||
|
if (PHPDBG_G(exec)) {
|
||||||
phpdbg_set_breakpoint_file(
|
phpdbg_set_breakpoint_file(
|
||||||
zend_get_executed_filename(),
|
zend_get_executed_filename(),
|
||||||
|
strlen(zend_get_executed_filename()),
|
||||||
zend_get_executed_lineno());
|
zend_get_executed_lineno());
|
||||||
|
} else {
|
||||||
|
phpdbg_error("inactive", "type=\"noexec\"", "Execution context not set!");
|
||||||
|
}
|
||||||
} else switch (param->type) {
|
} else switch (param->type) {
|
||||||
case ADDR_PARAM:
|
case ADDR_PARAM:
|
||||||
phpdbg_set_breakpoint_opline(param->addr);
|
phpdbg_set_breakpoint_opline(param->addr);
|
||||||
break;
|
break;
|
||||||
case NUMERIC_PARAM:
|
case NUMERIC_PARAM:
|
||||||
if (PHPDBG_G(exec)) {
|
if (PHPDBG_G(exec)) {
|
||||||
phpdbg_set_breakpoint_file(phpdbg_current_file(), param->num);
|
phpdbg_set_breakpoint_file(phpdbg_current_file(), strlen(phpdbg_current_file()), param->num);
|
||||||
} else {
|
} else {
|
||||||
phpdbg_error("inactive", "type=\"noexec\"", "Execution context not set!");
|
phpdbg_error("inactive", "type=\"noexec\"", "Execution context not set!");
|
||||||
}
|
}
|
||||||
@ -1090,7 +1203,7 @@ PHPDBG_COMMAND(break) /* {{{ */
|
|||||||
phpdbg_set_breakpoint_function_opline(param->str, param->num);
|
phpdbg_set_breakpoint_function_opline(param->str, param->num);
|
||||||
break;
|
break;
|
||||||
case FILE_PARAM:
|
case FILE_PARAM:
|
||||||
phpdbg_set_breakpoint_file(param->file.name, param->file.line);
|
phpdbg_set_breakpoint_file(param->file.name, 0, param->file.line);
|
||||||
break;
|
break;
|
||||||
case NUMERIC_FILE_PARAM:
|
case NUMERIC_FILE_PARAM:
|
||||||
phpdbg_set_breakpoint_file_opline(param->file.name, param->file.line);
|
phpdbg_set_breakpoint_file_opline(param->file.name, param->file.line);
|
||||||
|
@ -27,11 +27,13 @@ void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default);
|
|||||||
void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init);
|
void phpdbg_try_file_init(char *init_file, size_t init_file_len, zend_bool free_init);
|
||||||
int phpdbg_interactive(zend_bool allow_async_unsafe, char *input);
|
int phpdbg_interactive(zend_bool allow_async_unsafe, char *input);
|
||||||
int phpdbg_compile(void);
|
int phpdbg_compile(void);
|
||||||
|
int phpdbg_compile_stdin(zend_string *code);
|
||||||
void phpdbg_force_interruption(void);
|
void phpdbg_force_interruption(void);
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
/* {{{ phpdbg command handlers */
|
/* {{{ phpdbg command handlers */
|
||||||
PHPDBG_COMMAND(exec);
|
PHPDBG_COMMAND(exec);
|
||||||
|
PHPDBG_COMMAND(stdin);
|
||||||
PHPDBG_COMMAND(step);
|
PHPDBG_COMMAND(step);
|
||||||
PHPDBG_COMMAND(continue);
|
PHPDBG_COMMAND(continue);
|
||||||
PHPDBG_COMMAND(run);
|
PHPDBG_COMMAND(run);
|
||||||
|
16
sapi/phpdbg/tests/include_once.phpt
Normal file
16
sapi/phpdbg/tests/include_once.phpt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
--TEST--
|
||||||
|
include_once must include only once
|
||||||
|
--PHPDBG--
|
||||||
|
r
|
||||||
|
q
|
||||||
|
--EXPECTF--
|
||||||
|
[Successful compilation of %s]
|
||||||
|
prompt> 1
|
||||||
|
[Script ended normally]
|
||||||
|
prompt>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
include_once __DIR__.'/include.inc';
|
||||||
|
include_once __DIR__.'/include.inc';
|
||||||
|
|
19
sapi/phpdbg/tests/set_exception_handler.phpt
Normal file
19
sapi/phpdbg/tests/set_exception_handler.phpt
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
--TEST--
|
||||||
|
set_exception_handler() in phpdbg
|
||||||
|
--PHPDBG--
|
||||||
|
r
|
||||||
|
c
|
||||||
|
q
|
||||||
|
--EXPECTF--
|
||||||
|
[Successful compilation of %s]
|
||||||
|
prompt> [Uncaught Exception in %s on line 4: test]
|
||||||
|
>00004: throw new Exception("test");
|
||||||
|
00005:
|
||||||
|
prompt> EX
|
||||||
|
[Script ended normally]
|
||||||
|
prompt>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
set_exception_handler(function () { print "EX\n"; });
|
||||||
|
throw new Exception("test");
|
25
sapi/phpdbg/tests/stdin_001.phpt
Normal file
25
sapi/phpdbg/tests/stdin_001.phpt
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
--TEST--
|
||||||
|
Test stdin input with breakpoints
|
||||||
|
--PHPDBG--
|
||||||
|
stdin foo
|
||||||
|
<?php
|
||||||
|
|
||||||
|
echo "Hello, world!\n";
|
||||||
|
foo
|
||||||
|
b 3
|
||||||
|
r
|
||||||
|
c
|
||||||
|
r
|
||||||
|
q
|
||||||
|
--EXPECTF--
|
||||||
|
prompt> [Successful compilation of stdin input]
|
||||||
|
prompt> [Breakpoint #0 added at -:3]
|
||||||
|
prompt> [Breakpoint #0 at -:3, hits: 1]
|
||||||
|
>00003: echo "Hello, world!\n";
|
||||||
|
00004:
|
||||||
|
prompt> Hello, world!
|
||||||
|
[Script ended normally]
|
||||||
|
prompt> [Breakpoint #0 at -:3, hits: 1]
|
||||||
|
>00003: echo "Hello, world!\n";
|
||||||
|
00004:
|
||||||
|
prompt>
|
Loading…
Reference in New Issue
Block a user