summaryrefslogtreecommitdiff
path: root/sapi/phpdbg/phpdbg_list.c
diff options
context:
space:
mode:
authorSTANLEY SUFFICOOL <ssufficool@php.net>2014-10-24 20:00:48 -0700
committerSTANLEY SUFFICOOL <ssufficool@php.net>2014-10-24 20:00:48 -0700
commite33ba844e52c5dc8e2fb1658a51bec611e78f7ba (patch)
tree2e6f416aac4b0a5668976db500ada1bdcc2b399e /sapi/phpdbg/phpdbg_list.c
parent5f91b0a3c717f109ffb7dc684d5a3fa8905b82ec (diff)
parent0a5b7d1316a778dc06a638869c8df8d4c989ddf0 (diff)
downloadphp-git-e33ba844e52c5dc8e2fb1658a51bec611e78f7ba.tar.gz
Merge branch 'master' of https://git.php.net/push/php-src
* 'master' of https://git.php.net/push/php-src: (164 commits) refix the broken place fix infinite loop fix datatype mismatch warnings fix datatype mismatches fix datatype mismatches fix datatype mismatches fix datatype mismatch warnings fix datatype mismatch warnings fix datatype mismatch warnings fix datatype mismatch warning fix datatype mismatches fix datatype mismatch warnings Re-add phpdbg to travis Added some NEWS Make xml valid (missing space between attrs) Fix info classes file name in xml Add note about <eval> tag for errors in xml.md Name the tag <eval> if the error id during ev cmd Do not print out xml as PHP print... Fix output to wrong function ...
Diffstat (limited to 'sapi/phpdbg/phpdbg_list.c')
-rw-r--r--sapi/phpdbg/phpdbg_list.c235
1 files changed, 149 insertions, 86 deletions
diff --git a/sapi/phpdbg/phpdbg_list.c b/sapi/phpdbg/phpdbg_list.c
index eac17ba6a7..de03a3651e 100644
--- a/sapi/phpdbg/phpdbg_list.c
+++ b/sapi/phpdbg/phpdbg_list.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -34,35 +34,37 @@
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
-#define PHPDBG_LIST_COMMAND_D(f, h, a, m, l, s) \
- PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[13])
+#define PHPDBG_LIST_COMMAND_D(f, h, a, m, l, s, flags) \
+ PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[13], flags)
const phpdbg_command_t phpdbg_list_commands[] = {
- PHPDBG_LIST_COMMAND_D(lines, "lists the specified lines", 'l', list_lines, NULL, "l"),
- PHPDBG_LIST_COMMAND_D(class, "lists the specified class", 'c', list_class, NULL, "s"),
- PHPDBG_LIST_COMMAND_D(method, "lists the specified method", 'm', list_method, NULL, "m"),
- PHPDBG_LIST_COMMAND_D(func, "lists the specified function", 'f', list_func, NULL, "s"),
+ PHPDBG_LIST_COMMAND_D(lines, "lists the specified lines", 'l', list_lines, NULL, "l", PHPDBG_ASYNC_SAFE),
+ PHPDBG_LIST_COMMAND_D(class, "lists the specified class", 'c', list_class, NULL, "s", PHPDBG_ASYNC_SAFE),
+ PHPDBG_LIST_COMMAND_D(method, "lists the specified method", 'm', list_method, NULL, "m", PHPDBG_ASYNC_SAFE),
+ PHPDBG_LIST_COMMAND_D(func, "lists the specified function", 'f', list_func, NULL, "s", PHPDBG_ASYNC_SAFE),
PHPDBG_END_COMMAND
};
PHPDBG_LIST(lines) /* {{{ */
{
if (!PHPDBG_G(exec) && !zend_is_executing(TSRMLS_C)) {
- phpdbg_error("Not executing, and execution context not set");
+ phpdbg_error("inactive", "type=\"execution\"", "Not executing, and execution context not set");
return SUCCESS;
}
switch (param->type) {
- case NUMERIC_PARAM:
- phpdbg_list_file(phpdbg_current_file(TSRMLS_C),
- (param->num < 0 ? 1 - param->num : param->num),
- (param->num < 0 ? param->num : 0) + zend_get_executed_lineno(TSRMLS_C),
- 0 TSRMLS_CC);
- break;
-
- case FILE_PARAM:
- phpdbg_list_file(param->file.name, param->file.line, 0, 0 TSRMLS_CC);
- break;
+ case NUMERIC_PARAM: {
+ const char *char_file = phpdbg_current_file(TSRMLS_C);
+ zend_string *file = zend_string_init(char_file, strlen(char_file), 0);
+ phpdbg_list_file(file, param->num < 0 ? 1 - param->num : param->num, (param->num < 0 ? param->num : 0) + zend_get_executed_lineno(TSRMLS_C), 0 TSRMLS_CC);
+ efree(file);
+ } break;
+
+ case FILE_PARAM: {
+ zend_string *file = zend_string_init(param->file.name, strlen(param->file.name), 0);
+ phpdbg_list_file(file, param->file.line, 0, 0 TSRMLS_CC);
+ efree(file);
+ } break;
phpdbg_default_switch_case();
}
@@ -79,21 +81,21 @@ PHPDBG_LIST(func) /* {{{ */
PHPDBG_LIST(method) /* {{{ */
{
- zend_class_entry **ce;
+ zend_class_entry *ce;
- if (zend_lookup_class(param->method.class, strlen(param->method.class), &ce TSRMLS_CC) == SUCCESS) {
+ if (phpdbg_safe_class_lookup(param->method.class, strlen(param->method.class), &ce TSRMLS_CC) == SUCCESS) {
zend_function *function;
char *lcname = zend_str_tolower_dup(param->method.name, strlen(param->method.name));
- if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**) &function) == SUCCESS) {
+ if ((function = zend_hash_str_find_ptr(&ce->function_table, lcname, strlen(lcname)))) {
phpdbg_list_function(function TSRMLS_CC);
} else {
- phpdbg_error("Could not find %s::%s", param->method.class, param->method.name);
+ phpdbg_error("list", "type=\"notfound\" method=\"%s::%s\"", "Could not find %s::%s", param->method.class, param->method.name);
}
efree(lcname);
} else {
- phpdbg_error("Could not find the class %s", param->method.class);
+ phpdbg_error("list", "type=\"notfound\" class=\"%s\"", "Could not find the class %s", param->method.class);
}
return SUCCESS;
@@ -101,82 +103,69 @@ PHPDBG_LIST(method) /* {{{ */
PHPDBG_LIST(class) /* {{{ */
{
- zend_class_entry **ce;
-
- if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) {
- if ((*ce)->type == ZEND_USER_CLASS) {
- if ((*ce)->info.user.filename) {
- phpdbg_list_file(
- (*ce)->info.user.filename,
- (*ce)->info.user.line_end - (*ce)->info.user.line_start + 1,
- (*ce)->info.user.line_start, 0 TSRMLS_CC
- );
+ zend_class_entry *ce;
+
+ if (phpdbg_safe_class_lookup(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) {
+ if (ce->type == ZEND_USER_CLASS) {
+ if (ce->info.user.filename) {
+ phpdbg_list_file(ce->info.user.filename, ce->info.user.line_end - ce->info.user.line_start + 1, ce->info.user.line_start, 0 TSRMLS_CC);
} else {
- phpdbg_error("The source of the requested class (%s) cannot be found", (*ce)->name);
+ phpdbg_error("list", "type=\"nosource\" class=\"%s\"", "The source of the requested class (%s) cannot be found", ce->name);
}
} else {
- phpdbg_error("The class requested (%s) is not user defined", (*ce)->name);
+ phpdbg_error("list", "type=\"internalclass\" class=\"%s\"", "The class requested (%s) is not user defined", ce->name);
}
} else {
- phpdbg_error("The requested class (%s) could not be found", param->str);
+ phpdbg_error("list", "type=\"notfound\" class=\"%s\"", "The requested class (%s) could not be found", param->str);
}
return SUCCESS;
} /* }}} */
-void phpdbg_list_file(const char *filename, long count, long offset, int highlight TSRMLS_DC) /* {{{ */
+void phpdbg_list_file(zend_string *filename, uint count, int offset, uint highlight TSRMLS_DC) /* {{{ */
{
- struct stat st;
- char *opened = NULL;
- char buffer[8096] = {0,};
- long line = 0;
-
- php_stream *stream = NULL;
-
- if (VCWD_STAT(filename, &st) == FAILURE) {
- phpdbg_error("Failed to stat file %s", filename);
- return;
- }
+ uint line, lastline;
+ phpdbg_file_source *data;
- stream = php_stream_open_wrapper(filename, "rb", USE_PATH, &opened);
-
- if (!stream) {
- phpdbg_error("Failed to open file %s to list", filename);
+ if (!(data = zend_hash_find_ptr(&PHPDBG_G(file_sources), filename))) {
+ phpdbg_error("list", "type=\"unknownfile\"", "Could not find information about included file...");
return;
}
-
+
if (offset < 0) {
count += offset;
offset = 0;
}
-
- while (php_stream_gets(stream, buffer, sizeof(buffer)) != NULL) {
- long linelen = strlen(buffer);
-
- ++line;
-
- if (offset <= line) {
- if (!highlight) {
- phpdbg_write("%05ld: %s", line, buffer);
- } else {
- if (highlight != line) {
- phpdbg_write(" %05ld: %s", line, buffer);
- } else {
- phpdbg_write(">%05ld: %s", line, buffer);
- }
- }
- if (buffer[linelen - 1] != '\n') {
- phpdbg_write("\n");
+ lastline = offset + count;
+
+ if (lastline > data->lines) {
+ lastline = data->lines;
+ }
+
+ phpdbg_xml("<list %r file=\"%s\">", filename);
+
+ for (line = offset; line < lastline;) {
+ uint linestart = data->line[line++];
+ uint linelen = data->line[line] - linestart;
+ char *buffer = data->buf + linestart;
+
+ if (!highlight) {
+ phpdbg_write("line", "line=\"%u\" code=\"%.*s\"", " %05u: %.*s", line, linelen, buffer);
+ } else {
+ if (highlight != line) {
+ phpdbg_write("line", "line=\"%u\" code=\"%.*s\"", " %05u: %.*s", line, linelen, buffer);
+ } else {
+ phpdbg_write("line", "line=\"%u\" code=\"%.*s\" current=\"current\"", ">%05u: %.*s", line, linelen, buffer);
}
}
- if (count > 0 && count + offset - 1 < line) {
- break;
+ if (*(buffer + linelen - 1) != '\n' || !linelen) {
+ phpdbg_out("\n");
}
}
-
- php_stream_close(stream);
+
+ phpdbg_xml("</list>");
} /* }}} */
void phpdbg_list_function(const zend_function *fbc TSRMLS_DC) /* {{{ */
@@ -184,14 +173,13 @@ void phpdbg_list_function(const zend_function *fbc TSRMLS_DC) /* {{{ */
const zend_op_array *ops;
if (fbc->type != ZEND_USER_FUNCTION) {
- phpdbg_error("The function requested (%s) is not user defined", fbc->common.function_name);
+ phpdbg_error("list", "type=\"internalfunction\" function=\"%s\"", "The function requested (%s) is not user defined", fbc->common.function_name);
return;
}
- ops = (zend_op_array*)fbc;
+ ops = (zend_op_array *) fbc;
- phpdbg_list_file(ops->filename,
- ops->line_end - ops->line_start + 1, ops->line_start, 0 TSRMLS_CC);
+ phpdbg_list_file(ops->filename, ops->line_end - ops->line_start + 1, ops->line_start, 0 TSRMLS_CC);
} /* }}} */
void phpdbg_list_function_byname(const char *str, size_t len TSRMLS_DC) /* {{{ */
@@ -209,11 +197,11 @@ void phpdbg_list_function_byname(const char *str, size_t len TSRMLS_DC) /* {{{ *
func_table = &EG(scope)->function_table;
} else {
- phpdbg_error("No active class");
+ phpdbg_error("inactive", "type=\"noclasses\"", "No active class");
return;
}
} else if (!EG(function_table)) {
- phpdbg_error("No function table loaded");
+ phpdbg_error("inactive", "type=\"function_table\"", "No function table loaded");
return;
} else {
func_table = EG(function_table);
@@ -222,12 +210,87 @@ void phpdbg_list_function_byname(const char *str, size_t len TSRMLS_DC) /* {{{ *
/* use lowercase names, case insensitive */
func_name = zend_str_tolower_dup(func_name, func_name_len);
- if (zend_hash_find(func_table, func_name, func_name_len+1, (void**)&fbc) == SUCCESS) {
- phpdbg_list_function(fbc TSRMLS_CC);
- } else {
- phpdbg_error("Function %s not found", func_name);
- }
+ phpdbg_try_access {
+ if ((fbc = zend_hash_str_find_ptr(func_table, func_name, func_name_len))) {
+ phpdbg_list_function(fbc TSRMLS_CC);
+ } else {
+ phpdbg_error("list", "type=\"nofunction\" function=\"%s\"", "Function %s not found", func_name);
+ }
+ } phpdbg_catch_access {
+ phpdbg_error("signalsegv", "function=\"%s\"", "Could not list function %s, invalid data source", func_name);
+ } phpdbg_end_try_access();
efree(func_name);
} /* }}} */
+zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type TSRMLS_DC) {
+ phpdbg_file_source data, *dataptr;
+ zend_file_handle fake = {{0}};
+ zend_op_array *ret;
+ char *filename = (char *)(file->opened_path ? file->opened_path : file->filename);
+ uint line;
+ char *bufptr, *endptr;
+
+ zend_stream_fixup(file, &data.buf, &data.len TSRMLS_CC);
+
+ data.filename = filename;
+ data.line[0] = 0;
+
+ if (file->handle.stream.mmap.old_closer) {
+ /* do not unmap */
+ file->handle.stream.closer = file->handle.stream.mmap.old_closer;
+ }
+
+#if HAVE_MMAP
+ if (file->handle.stream.mmap.map) {
+ data.map = file->handle.stream.mmap.map;
+ }
+#endif
+
+ fake.type = ZEND_HANDLE_MAPPED;
+ fake.handle.stream.mmap.buf = data.buf;
+ fake.handle.stream.mmap.len = data.len;
+ fake.free_filename = 0;
+ fake.opened_path = file->opened_path;
+ fake.filename = filename;
+ fake.opened_path = file->opened_path;
+
+ *(dataptr = emalloc(sizeof(phpdbg_file_source) + sizeof(uint) * data.len)) = data;
+
+ for (line = 0, bufptr = data.buf - 1, endptr = data.buf + data.len; ++bufptr < endptr;) {
+ if (*bufptr == '\n') {
+ dataptr->line[++line] = (uint)(bufptr - data.buf) + 1;
+ }
+ }
+ dataptr->lines = ++line;
+ dataptr->line[line] = endptr - data.buf;
+ dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line);
+
+ zend_hash_str_add_ptr(&PHPDBG_G(file_sources), filename, strlen(filename), dataptr);
+
+ ret = PHPDBG_G(compile_file)(&fake, type TSRMLS_CC);
+
+ fake.opened_path = NULL;
+ zend_file_handle_dtor(&fake TSRMLS_CC);
+
+ return ret;
+}
+
+void phpdbg_free_file_source(phpdbg_file_source *data) {
+#if HAVE_MMAP
+ if (data->map) {
+ munmap(data->map, data->len + ZEND_MMAP_AHEAD);
+ } else
+#endif
+ if (data->buf) {
+ efree(data->buf);
+ }
+
+ efree(data);
+}
+
+void phpdbg_init_list(TSRMLS_D) {
+ PHPDBG_G(compile_file) = zend_compile_file;
+ zend_hash_init(&PHPDBG_G(file_sources), 1, NULL, (dtor_func_t) phpdbg_free_file_source, 0);
+ zend_compile_file = phpdbg_compile_file;
+}