summaryrefslogtreecommitdiff
path: root/sapi/phpdbg/phpdbg_print.c
diff options
context:
space:
mode:
authorRasmus Lerdorf <rasmus@php.net>2014-10-26 16:58:45 -0700
committerRasmus Lerdorf <rasmus@php.net>2014-10-26 16:58:45 -0700
commit8d84b1f67adb71bdb2394b62faad04b22f6226f3 (patch)
tree0c1c1ed2aaef8eee971575eb5e336631295f4951 /sapi/phpdbg/phpdbg_print.c
parentfb85d0322d39d49f37e32df6f68c9769f2cce0e4 (diff)
parent09da8952d0434b53e740ffaca66a8051cd39cf93 (diff)
downloadphp-git-8d84b1f67adb71bdb2394b62faad04b22f6226f3.tar.gz
Merge branch 'master' of git.php.net:php-src
* 'master' of git.php.net:php-src: (240 commits) Do not execute anything after quit or clean command Fix last commit, and do not output unnecessary information Stabilize execution, always run destructors and extended file breakpoints Fix nullptr dereference in clean without exec context remove dodgy param parser, bring userland breakpoint api inline with PHP7 disable output buffering by default Add question to reset execution in run/exec/clean - Updated to version 2014.9 (2014i) actually remove this disable output buffering, better breakpoint api for userland, remove hand parsing of params Fix phpdbg output when outputting via php with active output handlers Fixed Closure::call() NEWS/UPGRADING Set engine back to initial state after fatal-ed ev command Fix eventual stack overflow after clean cmd Fix listing of files with no absolute path updated libmagic.patch in master updated libmagic.patch in 5.6 updated libmagic.patch in 5.5 NEWS NEWS ...
Diffstat (limited to 'sapi/phpdbg/phpdbg_print.c')
-rw-r--r--sapi/phpdbg/phpdbg_print.c157
1 files changed, 83 insertions, 74 deletions
diff --git a/sapi/phpdbg/phpdbg_print.c b/sapi/phpdbg/phpdbg_print.c
index eba7ed7666..62a614281d 100644
--- a/sapi/phpdbg/phpdbg_print.c
+++ b/sapi/phpdbg/phpdbg_print.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 7 |
+ | PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -26,25 +26,25 @@
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
-#define PHPDBG_PRINT_COMMAND_D(f, h, a, m, l, s) \
- PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[9])
+#define PHPDBG_PRINT_COMMAND_D(f, h, a, m, l, s, flags) \
+ PHPDBG_COMMAND_D_EXP(f, h, a, m, l, s, &phpdbg_prompt_commands[9], flags)
const phpdbg_command_t phpdbg_print_commands[] = {
- PHPDBG_PRINT_COMMAND_D(exec, "print out the instructions in the execution context", 'e', print_exec, NULL, 0),
- PHPDBG_PRINT_COMMAND_D(opline, "print out the instruction in the current opline", 'o', print_opline, NULL, 0),
- PHPDBG_PRINT_COMMAND_D(class, "print out the instructions in the specified class", 'c', print_class, NULL, "s"),
- PHPDBG_PRINT_COMMAND_D(method, "print out the instructions in the specified method", 'm', print_method, NULL, "m"),
- PHPDBG_PRINT_COMMAND_D(func, "print out the instructions in the specified function", 'f', print_func, NULL, "s"),
- PHPDBG_PRINT_COMMAND_D(stack, "print out the instructions in the current stack", 's', print_stack, NULL, 0),
+ PHPDBG_PRINT_COMMAND_D(exec, "print out the instructions in the execution context", 'e', print_exec, NULL, 0, PHPDBG_ASYNC_SAFE),
+ PHPDBG_PRINT_COMMAND_D(opline, "print out the instruction in the current opline", 'o', print_opline, NULL, 0, PHPDBG_ASYNC_SAFE),
+ PHPDBG_PRINT_COMMAND_D(class, "print out the instructions in the specified class", 'c', print_class, NULL, "s", PHPDBG_ASYNC_SAFE),
+ PHPDBG_PRINT_COMMAND_D(method, "print out the instructions in the specified method", 'm', print_method, NULL, "m", PHPDBG_ASYNC_SAFE),
+ PHPDBG_PRINT_COMMAND_D(func, "print out the instructions in the specified function", 'f', print_func, NULL, "s", PHPDBG_ASYNC_SAFE),
+ PHPDBG_PRINT_COMMAND_D(stack, "print out the instructions in the current stack", 's', print_stack, NULL, 0, PHPDBG_ASYNC_SAFE),
PHPDBG_END_COMMAND
};
PHPDBG_PRINT(opline) /* {{{ */
{
- if (EG(in_execution) && EG(current_execute_data)) {
+ if (PHPDBG_G(in_execution) && EG(current_execute_data)) {
phpdbg_print_opline(EG(current_execute_data), 1 TSRMLS_CC);
} else {
- phpdbg_error("Not Executing!");
+ phpdbg_error("inactive", "type=\"execution\"", "Not Executing!");
}
return SUCCESS;
@@ -56,38 +56,39 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC)
case ZEND_USER_FUNCTION: {
zend_op_array* op_array = &(method->op_array);
HashTable vars;
-
+
if (op_array) {
zend_op *opline = &(op_array->opcodes[0]);
uint32_t opcode = 0,
end = op_array->last-1;
if (method->common.scope) {
- phpdbg_writeln("\tL%d-%d %s::%s() %s",
- op_array->line_start, op_array->line_end,
- method->common.scope->name,
- method->common.function_name,
- op_array->filename ? op_array->filename : "unknown");
+ phpdbg_writeln("printoplineinfo", "type=\"User\" startline=\"%d\" endline=\"%d\" method=\"%s::%s\" file=\"%s\"", "\tL%d-%d %s::%s() %s",
+ op_array->line_start,
+ op_array->line_end,
+ method->common.scope->name->val,
+ method->common.function_name->val,
+ op_array->filename ? op_array->filename->val : "unknown");
} else {
- phpdbg_writeln("\tL%d-%d %s() %s",
- method->common.function_name ? op_array->line_start : 0,
+ phpdbg_writeln("printoplineinfo", "type=\"User\" startline=\"%d\" endline=\"%d\" function=\"%s\" file=\"%s\"", "\tL%d-%d %s() %s",
+ method->common.function_name ? op_array->line_start : 0,
method->common.function_name ? op_array->line_end : 0,
- method->common.function_name ? method->common.function_name : "{main}",
- op_array->filename ? op_array->filename : "unknown");
+ method->common.function_name ? method->common.function_name->val : "{main}",
+ op_array->filename ? op_array->filename->val : "unknown");
}
zend_hash_init(&vars, op_array->last, NULL, NULL, 0);
do {
char *decode = phpdbg_decode_opline(op_array, opline, &vars TSRMLS_CC);
if (decode != NULL) {
- phpdbg_writeln("\t\tL%u\t%p %-30s %s",
+ phpdbg_writeln("print", "line=\"%u\" opline=\"%p\" opcode=\"%s\" op=\"%s\"", "\t\tL%u\t%p %-30s %s",
opline->lineno,
- opline,
+ opline,
phpdbg_decode_opcode(opline->opcode),
decode);
free(decode);
} else {
- phpdbg_error("\tFailed to decode opline %16p", opline);
+ phpdbg_error("print", "type=\"decodefailure\" opline=\"%16p\"", "\tFailed to decode opline %16p", opline);
}
opline++;
} while (opcode++ < end);
@@ -97,9 +98,9 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC)
default: {
if (method->common.scope) {
- phpdbg_writeln("\tInternal %s::%s()", method->common.scope->name, method->common.function_name);
+ phpdbg_writeln("printoplineinfo", "type=\"Internal\" method=\"%s::%s\"", "\tInternal %s::%s()", method->common.scope->name->val, method->common.function_name->val);
} else {
- phpdbg_writeln("\tInternal %s()", method->common.function_name);
+ phpdbg_writeln("printoplineinfo", "type=\"Internal\" function=\"%s\"", "\tInternal %s()", method->common.function_name->val);
}
}
}
@@ -108,17 +109,17 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC)
PHPDBG_PRINT(exec) /* {{{ */
{
if (PHPDBG_G(exec)) {
- if (!PHPDBG_G(ops)) {
+ if (!PHPDBG_G(ops) && !(PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER)) {
phpdbg_compile(TSRMLS_C);
}
if (PHPDBG_G(ops)) {
- phpdbg_notice("Context %s", PHPDBG_G(exec));
+ phpdbg_notice("printinfo", "file=\"%s\" num=\"%d\"", "Context %s (%d ops)", PHPDBG_G(exec), PHPDBG_G(ops)->last);
phpdbg_print_function_helper((zend_function*) PHPDBG_G(ops) TSRMLS_CC);
}
} else {
- phpdbg_error("No execution context set");
+ phpdbg_error("inactive", "type=\"nocontext\"", "No execution context set");
}
return SUCCESS;
@@ -126,25 +127,24 @@ return SUCCESS;
PHPDBG_PRINT(stack) /* {{{ */
{
- zend_op_array *ops = EG(active_op_array);
-
- if (EG(in_execution) && ops) {
+ if (PHPDBG_G(in_execution) && EG(current_execute_data)) {
+ zend_op_array *ops = &EG(current_execute_data)->func->op_array;
if (ops->function_name) {
if (ops->scope) {
- phpdbg_notice("Stack in %s::%s()", ops->scope->name, ops->function_name);
+ phpdbg_notice("printinfo", "method=\"%s::%s\" num=\"%d\"", "Stack in %s::%s() (%d ops)", ops->scope->name->val, ops->function_name->val, ops->last);
} else {
- phpdbg_notice("Stack in %s()", ops->function_name);
+ phpdbg_notice("printinfo", "function=\"%s\" num=\"%d\"", "Stack in %s() (%d ops)", ops->function_name->val, ops->last);
}
} else {
if (ops->filename) {
- phpdbg_notice("Stack in %s", ops->filename);
+ phpdbg_notice("printinfo", "file=\"%s\" num=\"%d\"", "Stack in %s (%d ops)", ops->filename->val, ops->last);
} else {
- phpdbg_notice("Stack @ %p", ops);
+ phpdbg_notice("printinfo", "opline=\"%p\" num=\"%d\"", "Stack @ %p (%d ops)", ops, ops->last);
}
}
phpdbg_print_function_helper((zend_function*) ops TSRMLS_CC);
} else {
- phpdbg_error("Not Executing!");
+ phpdbg_error("inactive", "type=\"execution\"", "Not Executing!");
}
return SUCCESS;
@@ -152,32 +152,33 @@ PHPDBG_PRINT(stack) /* {{{ */
PHPDBG_PRINT(class) /* {{{ */
{
- zend_class_entry **ce;
+ zend_class_entry *ce;
- if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) {
- phpdbg_notice("%s %s: %s",
- ((*ce)->type == ZEND_USER_CLASS) ?
+ if (phpdbg_safe_class_lookup(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) {
+ phpdbg_notice("printinfo", "type=\"%s\" flag=\"%s\" class=\"%s\" num=\"%d\"", "%s %s: %s (%d methods)",
+ (ce->type == ZEND_USER_CLASS) ?
"User" : "Internal",
- ((*ce)->ce_flags & ZEND_ACC_INTERFACE) ?
+ (ce->ce_flags & ZEND_ACC_INTERFACE) ?
"Interface" :
- ((*ce)->ce_flags & ZEND_ACC_ABSTRACT) ?
+ (ce->ce_flags & ZEND_ACC_ABSTRACT) ?
"Abstract Class" :
"Class",
- (*ce)->name);
+ ce->name->val,
+ zend_hash_num_elements(&ce->function_table));
+
+ phpdbg_xml("<printmethods %r>");
- phpdbg_writeln("Methods (%d):", zend_hash_num_elements(&(*ce)->function_table));
- if (zend_hash_num_elements(&(*ce)->function_table)) {
- HashPosition position;
+ if (zend_hash_num_elements(&ce->function_table)) {
zend_function *method;
- for (zend_hash_internal_pointer_reset_ex(&(*ce)->function_table, &position);
- zend_hash_get_current_data_ex(&(*ce)->function_table, (void**) &method, &position) == SUCCESS;
- zend_hash_move_forward_ex(&(*ce)->function_table, &position)) {
+ ZEND_HASH_FOREACH_PTR(&ce->function_table, method) {
phpdbg_print_function_helper(method TSRMLS_CC);
- }
+ } ZEND_HASH_FOREACH_END();
}
+
+ phpdbg_xml("</printmethods>");
} else {
- phpdbg_error("The class %s could not be found", param->str);
+ phpdbg_error("print", "type=\"noclass\" class=\"%s\"", "The class %s could not be found", param->str);
}
return SUCCESS;
@@ -185,25 +186,27 @@ PHPDBG_PRINT(class) /* {{{ */
PHPDBG_PRINT(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 *fbc;
- char *lcname = zend_str_tolower_dup(param->method.name, strlen(param->method.name));
+ zend_string *lcname = zend_string_alloc(strlen(param->method.name), 0);
+ zend_str_tolower_copy(lcname->val, param->method.name, lcname->len);
- if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) {
- phpdbg_notice("%s Method %s",
+ if ((fbc = zend_hash_find_ptr(&ce->function_table, lcname))) {
+ phpdbg_notice("printinfo", "type=\"%s\" flags=\"Method\" symbol=\"%s\" num=\"%d\"", "%s Method %s (%d ops)",
(fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal",
- fbc->common.function_name);
+ fbc->common.function_name->val,
+ (fbc->type == ZEND_USER_FUNCTION) ? fbc->op_array.last : 0);
phpdbg_print_function_helper(fbc TSRMLS_CC);
} else {
- phpdbg_error("The method %s could not be found", param->method.name);
+ phpdbg_error("print", "type=\"nomethod\" method=\"%s::%s\"", "The method %s::%s could not be found", param->method.class, param->method.name);
}
- efree(lcname);
+ zend_string_release(lcname);
} else {
- phpdbg_error("The class %s could not be found", param->method.class);
+ phpdbg_error("print", "type=\"noclass\" class=\"%s\"", "The class %s could not be found", param->method.class);
}
return SUCCESS;
@@ -215,7 +218,7 @@ PHPDBG_PRINT(func) /* {{{ */
zend_function* fbc;
const char *func_name = param->str;
size_t func_name_len = param->len;
- char *lcname;
+ zend_string *lcname;
/* search active scope if begins with period */
if (func_name[0] == '.') {
if (EG(scope)) {
@@ -224,28 +227,34 @@ PHPDBG_PRINT(func) /* {{{ */
func_table = &EG(scope)->function_table;
} else {
- phpdbg_error("No active class");
+ phpdbg_error("inactive", "type=\"noclasses\"", "No active class");
return SUCCESS;
}
} else if (!EG(function_table)) {
- phpdbg_error("No function table loaded");
+ phpdbg_error("inactive", "type=\"function_table\"", "No function table loaded");
return SUCCESS;
} else {
func_table = EG(function_table);
}
- lcname = zend_str_tolower_dup(func_name, func_name_len);
+ lcname = zend_string_alloc(func_name_len, 0);
+ zend_str_tolower_copy(lcname->val, func_name, lcname->len);
- if (zend_hash_find(func_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) {
- phpdbg_notice("%s %s %s",
- (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal",
- (fbc->common.scope) ? "Method" : "Function",
- fbc->common.function_name);
+ phpdbg_try_access {
+ if ((fbc = zend_hash_find_ptr(func_table, lcname))) {
+ phpdbg_notice("printinfo", "type=\"%s\" flags=\"%s\" symbol=\"%s\" num=\"%d\"", "%s %s %s (%d ops)",
+ (fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal",
+ (fbc->common.scope) ? "Method" : "Function",
+ fbc->common.function_name->val,
+ (fbc->type == ZEND_USER_FUNCTION) ? fbc->op_array.last : 0);
- phpdbg_print_function_helper(fbc TSRMLS_CC);
- } else {
- phpdbg_error("The function %s could not be found", func_name);
- }
+ phpdbg_print_function_helper(fbc TSRMLS_CC);
+ } else {
+ phpdbg_error("print", "type=\"nofunction\" function=\"%s\"", "The function %s could not be found", func_name);
+ }
+ } phpdbg_catch_access {
+ phpdbg_error("signalsegv", "function=\"%.*s\"", "Couldn't fetch function %.*s, invalid data source", (int) func_name_len, func_name);
+ } phpdbg_end_try_access();
efree(lcname);