diff options
Diffstat (limited to 'sapi/phpdbg/phpdbg_print.c')
-rw-r--r-- | sapi/phpdbg/phpdbg_print.c | 125 |
1 files changed, 81 insertions, 44 deletions
diff --git a/sapi/phpdbg/phpdbg_print.c b/sapi/phpdbg/phpdbg_print.c index 70b8c2f807..034354a9e7 100644 --- a/sapi/phpdbg/phpdbg_print.c +++ b/sapi/phpdbg/phpdbg_print.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 7 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2015 The PHP Group | + | Copyright (c) 1997-2016 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -24,7 +24,7 @@ #include "phpdbg_opcode.h" #include "phpdbg_prompt.h" -ZEND_EXTERN_MODULE_GLOBALS(phpdbg); +ZEND_EXTERN_MODULE_GLOBALS(phpdbg) #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[8], flags) @@ -42,7 +42,7 @@ const phpdbg_command_t phpdbg_print_commands[] = { PHPDBG_PRINT(opline) /* {{{ */ { if (PHPDBG_G(in_execution) && EG(current_execute_data)) { - phpdbg_print_opline(EG(current_execute_data), 1); + phpdbg_print_opline(phpdbg_user_execute_data(EG(current_execute_data)), 1); } else { phpdbg_error("inactive", "type=\"execution\"", "Not Executing!"); } @@ -55,7 +55,6 @@ static inline void phpdbg_print_function_helper(zend_function *method) /* {{{ */ switch (method->type) { case ZEND_USER_FUNCTION: { zend_op_array* op_array = &(method->op_array); - HashTable vars; if (op_array) { zend_op *opline = &(op_array->opcodes[0]); @@ -81,22 +80,15 @@ static inline void phpdbg_print_function_helper(zend_function *method) /* {{{ */ op_array->last); } - zend_hash_init(&vars, op_array->last, NULL, NULL, 0); do { - char *decode = phpdbg_decode_opline(op_array, opline, &vars); - if (decode != NULL) { - phpdbg_writeln("print", "line=\"%u\" opnum=\"%u\" opcode=\"%s\" op=\"%s\"", " L%-4u #%-5u %-23s %s", - opline->lineno, - opcode, - phpdbg_decode_opcode(opline->opcode) + 5, /* remove ZEND_ prefix */ - decode); - free(decode); - } else { - phpdbg_error("print", "type=\"decodefailure\" opline=\"%16p\"", "Failed to decode opline %16p", opline); - } + char *decode = phpdbg_decode_opline(op_array, opline); + phpdbg_writeln("print", "line=\"%u\" opnum=\"%u\" op=\"%s\"", " L%-4u #%-5u %s", + opline->lineno, + opcode, + decode); + efree(decode); opline++; } while (opcode++ < end); - zend_hash_destroy(&vars); } } break; @@ -132,7 +124,7 @@ return SUCCESS; PHPDBG_PRINT(stack) /* {{{ */ { if (PHPDBG_G(in_execution) && EG(current_execute_data)) { - zend_op_array *ops = &EG(current_execute_data)->func->op_array; + zend_op_array *ops = &phpdbg_user_execute_data(EG(current_execute_data))->func->op_array; if (ops->function_name) { if (ops->scope) { phpdbg_notice("printinfo", "method=\"%s::%s\" num=\"%d\"", "Stack in %s::%s() (%d ops)", ZSTR_VAL(ops->scope->name), ZSTR_VAL(ops->function_name), ops->last); @@ -225,11 +217,13 @@ PHPDBG_PRINT(func) /* {{{ */ zend_string *lcname; /* search active scope if begins with period */ if (func_name[0] == '.') { - if (EG(scope)) { + zend_class_entry *scope = zend_get_executed_scope(); + + if (scope) { func_name++; func_name_len--; - func_table = &EG(scope)->function_table; + func_table = &scope->function_table; } else { phpdbg_error("inactive", "type=\"noclasses\"", "No active class"); return SUCCESS; @@ -274,23 +268,27 @@ void phpdbg_print_opcodes_function(const char *function, size_t len) { zend_function *func = zend_hash_str_find_ptr(EG(function_table), function, len); if (!func) { + zend_string *rt_name; + ZEND_HASH_FOREACH_STR_KEY_PTR(EG(class_table), rt_name, func) { + if (func->type == ZEND_USER_FUNCTION && *rt_name->val == '\0') { + if (func->op_array.function_name->len == len && !zend_binary_strcasecmp(function, len, func->op_array.function_name->val, func->op_array.function_name->len)) { + phpdbg_print_opcodes_function(rt_name->val, rt_name->len); + } + } + } ZEND_HASH_FOREACH_END(); + return; } - phpdbg_out("function name: %.*s\n", (int) len, function); + phpdbg_out("function name: %.*s\n", (int) ZSTR_LEN(func->op_array.function_name), ZSTR_VAL(func->op_array.function_name)); phpdbg_print_function_helper(func); } -void phpdbg_print_opcodes_method(const char *class, const char *function) { - zend_class_entry *ce; +static void phpdbg_print_opcodes_method_ce(zend_class_entry *ce, const char *function) { zend_function *func; - if (phpdbg_safe_class_lookup(class, strlen(class), &ce) != SUCCESS) { - return; - } - if (ce->type != ZEND_USER_CLASS) { - phpdbg_out("function name: %s::%s (internal)\n", class, function); + phpdbg_out("function name: %s::%s (internal)\n", ce->name->val, function); return; } @@ -298,20 +296,34 @@ void phpdbg_print_opcodes_method(const char *class, const char *function) { return; } - phpdbg_out("function name: %s::%s\n", class, function); + phpdbg_out("function name: %s::%s\n", ce->name->val, function); phpdbg_print_function_helper(func); } -void phpdbg_print_opcodes_class(const char *class) { +void phpdbg_print_opcodes_method(const char *class, const char *function) { zend_class_entry *ce; - zend_function *method; - zend_string *method_name; - zend_bool first = 1; if (phpdbg_safe_class_lookup(class, strlen(class), &ce) != SUCCESS) { + zend_string *rt_name; + ZEND_HASH_FOREACH_STR_KEY_PTR(EG(class_table), rt_name, ce) { + if (ce->type == ZEND_USER_CLASS && *rt_name->val == '\0') { + if (ce->name->len == strlen(class) && !zend_binary_strcasecmp(class, strlen(class), ce->name->val, ce->name->len)) { + phpdbg_print_opcodes_method_ce(ce, function); + } + } + } ZEND_HASH_FOREACH_END(); + return; } + phpdbg_print_opcodes_method_ce(ce, function); +} + +static void phpdbg_print_opcodes_ce(zend_class_entry *ce) { + zend_function *method; + zend_string *method_name; + zend_bool first = 1; + phpdbg_out("%s %s: %s\n", (ce->type == ZEND_USER_CLASS) ? "user" : "internal", @@ -341,16 +353,32 @@ void phpdbg_print_opcodes_class(const char *class) { phpdbg_out("\n"); ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, method_name, method) { - phpdbg_out("\nfunction name: %s\n", method_name); + phpdbg_out("\nfunction name: %s\n", ZSTR_VAL(method_name)); phpdbg_print_function_helper(method); } ZEND_HASH_FOREACH_END(); } +void phpdbg_print_opcodes_class(const char *class) { + zend_class_entry *ce; + + if (phpdbg_safe_class_lookup(class, strlen(class), &ce) != SUCCESS) { + zend_string *rt_name; + ZEND_HASH_FOREACH_STR_KEY_PTR(EG(class_table), rt_name, ce) { + if (ce->type == ZEND_USER_CLASS && *rt_name->val == '\0') { + if (ce->name->len == strlen(class) && !zend_binary_strcasecmp(class, strlen(class), ce->name->val, ce->name->len)) { + phpdbg_print_opcodes_ce(ce); + } + } + } ZEND_HASH_FOREACH_END(); + + return; + } + + phpdbg_print_opcodes_ce(ce); +} + PHPDBG_API void phpdbg_print_opcodes(char *function) { - char *method_name; - strtok(function, ":"); - if (function == NULL) { phpdbg_print_opcodes_main(); } else if (function[0] == '*' && function[1] == 0) { @@ -368,17 +396,26 @@ PHPDBG_API void phpdbg_print_opcodes(char *function) } } ZEND_HASH_FOREACH_END(); - ZEND_HASH_FOREACH_STR_KEY_PTR(EG(class_table), name, ce) { + ZEND_HASH_FOREACH_PTR(EG(class_table), ce) { if (ce->type == ZEND_USER_CLASS) { phpdbg_out("\n\n"); - phpdbg_print_opcodes_class(ZSTR_VAL(name)); + phpdbg_print_opcodes_ce(ce); } } ZEND_HASH_FOREACH_END(); - } else if ((method_name = strtok(NULL, ":")) == NULL) { - phpdbg_print_opcodes_function(function, strlen(function)); - } else if ((method_name + 1) == NULL) { - phpdbg_print_opcodes_class(function); } else { - phpdbg_print_opcodes_method(function, method_name); + function = zend_str_tolower_dup(function, strlen(function)); + + if (strstr(function, "::") == NULL) { + phpdbg_print_opcodes_function(function, strlen(function)); + } else { + char *method_name, *class_name = strtok(function, "::"); + if ((method_name = strtok(NULL, "::")) == NULL) { + phpdbg_print_opcodes_class(class_name); + } else { + phpdbg_print_opcodes_method(class_name, method_name); + } + } + + efree(function); } } |