1
0
mirror of https://github.com/php/php-src.git synced 2026-03-30 12:13:02 +02:00

- Fix conflict

This commit is contained in:
Felipe Pena
2013-11-17 09:28:14 -02:00
9 changed files with 546 additions and 498 deletions

View File

@@ -45,32 +45,42 @@ static void phpdbg_class_breaks_dtor(void *data) /* {{{ */
void phpdbg_set_breakpoint_file(const char *path, long line_num TSRMLS_DC) /* {{{ */
{
phpdbg_breakfile_t new_break;
zend_llist *break_files_ptr;
size_t path_len = strlen(path);
struct stat sb;
new_break.filename = estrndup(path, path_len);
new_break.line = line_num;
if (VCWD_STAT(path, &sb) != FAILURE) {
if (sb.st_mode & S_IFREG|S_IFLNK) {
phpdbg_breakfile_t new_break;
zend_llist *break_files_ptr;
size_t path_len = strlen(path);
PHPDBG_G(flags) |= PHPDBG_HAS_FILE_BP;
new_break.filename = estrndup(path, path_len);
new_break.line = line_num;
if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE],
new_break.filename, path_len, (void**)&break_files_ptr) == FAILURE) {
zend_llist break_files;
PHPDBG_G(flags) |= PHPDBG_HAS_FILE_BP;
zend_llist_init(&break_files, sizeof(phpdbg_breakfile_t),
phpdbg_llist_breakfile_dtor, 0);
if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE],
new_break.filename, path_len, (void**)&break_files_ptr) == FAILURE) {
zend_llist break_files;
zend_hash_update(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE],
new_break.filename, path_len, &break_files, sizeof(zend_llist),
(void**)&break_files_ptr);
}
zend_llist_init(&break_files, sizeof(phpdbg_breakfile_t),
phpdbg_llist_breakfile_dtor, 0);
new_break.id = PHPDBG_G(bp_count)++;
zend_llist_add_element(break_files_ptr, &new_break);
zend_hash_update(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE],
new_break.filename, path_len, &break_files, sizeof(zend_llist),
(void**)&break_files_ptr);
}
phpdbg_notice("Breakpoint #%d added at %s:%ld",
new_break.id, new_break.filename, new_break.line);
new_break.id = PHPDBG_G(bp_count)++;
zend_llist_add_element(break_files_ptr, &new_break);
phpdbg_notice("Breakpoint #%d added at %s:%ld",
new_break.id, new_break.filename, new_break.line);
} else {
phpdbg_error("Cannot set breakpoint in %s, it is not a regular file", path);
}
} else {
phpdbg_error("Cannot stat %s, it does not exist", path);
}
} /* }}} */
void phpdbg_set_breakpoint_symbol(const char *name TSRMLS_DC) /* {{{ */

View File

@@ -29,15 +29,11 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
PHPDBG_BREAK(file) /* {{{ */
{
switch (param->type) {
case EMPTY_PARAM:
phpdbg_error("No expression provided");
break;
case FILE_PARAM:
phpdbg_set_breakpoint_file(param->file.name, param->file.line TSRMLS_CC);
break;
default:
phpdbg_error("Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC));
break;
phpdbg_default_switch_case();
}
return SUCCESS;
@@ -46,16 +42,11 @@ PHPDBG_BREAK(file) /* {{{ */
PHPDBG_BREAK(method) /* {{{ */
{
switch (param->type) {
case EMPTY_PARAM:
phpdbg_error("No expression provided");
break;
case METHOD_PARAM:
phpdbg_set_breakpoint_method(param->method.class, param->method.name TSRMLS_CC);
break;
default:
phpdbg_error("Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC));
break;
phpdbg_default_switch_case();
}
return SUCCESS;
@@ -64,16 +55,11 @@ PHPDBG_BREAK(method) /* {{{ */
PHPDBG_BREAK(address) /* {{{ */
{
switch (param->type) {
case EMPTY_PARAM:
phpdbg_error("No expression provided");
break;
case ADDR_PARAM:
phpdbg_set_breakpoint_opline(param->addr TSRMLS_CC);
break;
default:
phpdbg_error(
"Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC));
return FAILURE;
phpdbg_default_switch_case();
}
return SUCCESS;
@@ -81,34 +67,30 @@ PHPDBG_BREAK(address) /* {{{ */
PHPDBG_BREAK(on) /* {{{ */
{
if (param->type == STR_PARAM) {
phpdbg_set_breakpoint_expression(param->str, param->len TSRMLS_CC);
} else {
phpdbg_error(
"Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC));
return FAILURE;
}
switch (param->type) {
case STR_PARAM:
phpdbg_set_breakpoint_expression(param->str, param->len TSRMLS_CC);
break;
phpdbg_default_switch_case();
}
return SUCCESS;
} /* }}} */
PHPDBG_BREAK(lineno) /* {{{ */
{
if (!PHPDBG_G(exec)) {
phpdbg_error("Not file context found!");
return SUCCESS;
}
switch (param->type) {
case EMPTY_PARAM:
phpdbg_error("No expression provided!");
break;
case NUMERIC_PARAM:
phpdbg_set_breakpoint_file(phpdbg_current_file(TSRMLS_C), param->num TSRMLS_CC);
break;
default:
phpdbg_error(
"Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC));
return FAILURE;
case NUMERIC_PARAM: {
if (PHPDBG_G(exec)) {
phpdbg_set_breakpoint_file(phpdbg_current_file(TSRMLS_C), param->num TSRMLS_CC);
} else {
phpdbg_error(
"Execution context not set !");
}
} break;
phpdbg_default_switch_case();
}
return SUCCESS;
@@ -117,15 +99,11 @@ PHPDBG_BREAK(lineno) /* {{{ */
PHPDBG_BREAK(func) /* {{{ */
{
switch (param->type) {
case EMPTY_PARAM:
phpdbg_error("No expression provided!");
break;
case STR_PARAM:
phpdbg_set_breakpoint_symbol(param->str TSRMLS_CC);
break;
default:
phpdbg_error("Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC));
break;
phpdbg_default_switch_case();
}
return SUCCESS;

View File

@@ -94,6 +94,8 @@ PHPDBG_HELP(print) /* {{{ */
phpdbg_writeln("Will print the instructions for the global function my_function");
phpdbg_writeln("\t%sprint opline", PROMPT);
phpdbg_writeln("Will print the instruction for the current opline");
phpdbg_writeln("\t%sprint exec", PROMPT);
phpdbg_writeln("Will print the instructions for the execution context");
phpdbg_writeln(EMPTY);
phpdbg_writeln("Specific printers loaded are show below:");
phpdbg_notice("Commands");

View File

@@ -31,44 +31,6 @@
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
static inline void i_phpdbg_list_func(const char *str, size_t len TSRMLS_DC)
{
HashTable *func_table = EG(function_table);
zend_function* fbc;
char *func_name = str;
size_t func_name_len = len;
/* search active scope if begins with period */
if (func_name[0] == '.') {
if (EG(scope)) {
func_name++;
func_name_len--;
func_table = &EG(scope)->function_table;
} else {
phpdbg_error("No active class");
return;
}
} else if (!EG(function_table)) {
phpdbg_error("No function table loaded");
return;
} else {
func_table = EG(function_table);
}
/* 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);
}
efree(func_name);
}
PHPDBG_LIST(lines) /* {{{ */
{
if (!PHPDBG_G(exec) || !zend_is_executing(TSRMLS_C)) {
@@ -81,10 +43,10 @@ PHPDBG_LIST(lines) /* {{{ */
case EMPTY_PARAM:
phpdbg_list_file(phpdbg_current_file(TSRMLS_C),
param->type == EMPTY_PARAM ? 0 : param->num,
zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC);
zend_get_executed_lineno(TSRMLS_C), 0 TSRMLS_CC);
break;
case FILE_PARAM:
phpdbg_list_file(param->file.name, param->file.line, 0 TSRMLS_CC);
phpdbg_list_file(param->file.name, param->file.line, 0, 0 TSRMLS_CC);
break;
default:
phpdbg_error("Unsupported parameter type (%s) for function",
@@ -96,12 +58,13 @@ PHPDBG_LIST(lines) /* {{{ */
PHPDBG_LIST(func) /* {{{ */
{
if (param->type == STR_PARAM) {
i_phpdbg_list_func(
param->str, param->len TSRMLS_CC);
} else {
phpdbg_error(
"Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC));
switch (param->type) {
case STR_PARAM:
phpdbg_list_function_byname(
param->str, param->len TSRMLS_CC);
break;
phpdbg_default_switch_case();
}
return SUCCESS;
@@ -109,28 +72,29 @@ PHPDBG_LIST(func) /* {{{ */
PHPDBG_LIST(method) /* {{{ */
{
if (param->type == METHOD_PARAM) {
zend_class_entry **ce;
switch (param->type) {
case METHOD_PARAM: {
zend_class_entry **ce;
if (zend_lookup_class(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_lookup_class(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) {
phpdbg_list_function(
function TSRMLS_CC);
if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**) &function) == SUCCESS) {
phpdbg_list_function(
function TSRMLS_CC);
} else {
phpdbg_error("Could not find ::%s in %s", param->method.name, param->method.class);
}
efree(lcname);
} else {
phpdbg_error("Could not find ::%s in %s", param->method.name, param->method.class);
phpdbg_error("Could not find the class %s", param->method.class);
}
} break;
efree(lcname);
} else {
phpdbg_error("Could not find the class %s", param->method.class);
}
} else {
phpdbg_error(
"Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC));
phpdbg_default_switch_case();
}
return SUCCESS;
@@ -138,59 +102,36 @@ PHPDBG_LIST(method) /* {{{ */
PHPDBG_LIST(class) /* {{{ */
{
if (param->type == STR_PARAM) {
zend_class_entry **ce;
switch (param->type) {
case STR_PARAM: {
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 TSRMLS_CC
);
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
);
} else {
phpdbg_error("The source of the requested class (%s) cannot be found", (*ce)->name);
}
} else {
phpdbg_error("The source of the requested class (%s) cannot be found", (*ce)->name);
phpdbg_error("The class requested (%s) is not user defined", (*ce)->name);
}
} else {
phpdbg_error("The class requested (%s) is not user defined", (*ce)->name);
phpdbg_error("The requested class (%s) could not be found", param->str);
}
} else {
phpdbg_error("The requested class (%s) could not be found", param->str);
}
} else {
phpdbg_error(
"Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC));
} break;
phpdbg_default_switch_case();
}
return SUCCESS;
} /* }}} */
void phpdbg_list_dispatch(phpdbg_param_t *param TSRMLS_DC) /* {{{ */
{
switch (param->type) {
case NUMERIC_PARAM:
case EMPTY_PARAM:
return PHPDBG_LIST_HANDLER(lines)(param TSRMLS_CC);
case FILE_PARAM:
return PHPDBG_LIST_HANDLER(lines)(param TSRMLS_CC);
case STR_PARAM: {
i_phpdbg_list_func(param->str, param->len TSRMLS_CC);
} break;
case METHOD_PARAM:
return PHPDBG_LIST_HANDLER(method)(param TSRMLS_CC);
default:
phpdbg_error(
"Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC));
break;
}
} /* }}} */
void phpdbg_list_file(const char *filename, long count, long offset TSRMLS_DC) /* {{{ */
void phpdbg_list_file(const char *filename, long count, long offset, int highlight TSRMLS_DC) /* {{{ */
{
unsigned char *mem, *pos, *last_pos, *end_pos;
struct stat st;
@@ -202,12 +143,13 @@ void phpdbg_list_file(const char *filename, long count, long offset TSRMLS_DC) /
int all_content = (count == 0);
unsigned int line = 0, displayed = 0;
if (VCWD_STAT(filename, &st) == -1) {
if (VCWD_STAT(filename, &st) == FAILURE) {
phpdbg_error("Failed to stat file %s", filename);
return;
}
#ifndef _WIN32
if ((fd = VCWD_OPEN(filename, O_RDONLY)) == -1) {
if ((fd = VCWD_OPEN(filename, O_RDONLY)) == FAILURE) {
phpdbg_error("Failed to open file %s to list", filename);
return;
}
@@ -249,7 +191,13 @@ void phpdbg_list_file(const char *filename, long count, long offset TSRMLS_DC) /
if (!offset || offset <= line) {
/* Without offset, or offset reached */
phpdbg_writeln("%05u: %.*s", line, (int)(pos - last_pos), last_pos);
if (!highlight) {
phpdbg_writeln("%05u: %.*s", line, (int)(pos - last_pos), last_pos);
} else {
if (highlight != line) {
phpdbg_writeln(" %05u: %.*s", line, (int)(pos - last_pos), last_pos);
} else phpdbg_writeln(">%05u: %.*s", line, (int)(pos - last_pos), last_pos);
}
++displayed;
}
@@ -284,6 +232,44 @@ void phpdbg_list_function(const zend_function *fbc TSRMLS_DC) /* {{{ */
ops = (zend_op_array*)fbc;
phpdbg_list_file(ops->filename,
ops->line_end - ops->line_start + 1, ops->line_start TSRMLS_CC);
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)
{
HashTable *func_table = EG(function_table);
zend_function* fbc;
char *func_name = (char*) str;
size_t func_name_len = len;
/* search active scope if begins with period */
if (func_name[0] == '.') {
if (EG(scope)) {
func_name++;
func_name_len--;
func_table = &EG(scope)->function_table;
} else {
phpdbg_error("No active class");
return;
}
} else if (!EG(function_table)) {
phpdbg_error("No function table loaded");
return;
} else {
func_table = EG(function_table);
}
/* 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);
}
efree(func_name);
}

View File

@@ -41,9 +41,9 @@ PHPDBG_LIST(class);
PHPDBG_LIST(method);
PHPDBG_LIST(func);
void phpdbg_list_function_byname(const char *, size_t TSRMLS_DC);
void phpdbg_list_function(const zend_function* TSRMLS_DC);
void phpdbg_list_file(const char*, long, long TSRMLS_DC);
void phpdbg_list_dispatch(phpdbg_param_t *param TSRMLS_DC);
void phpdbg_list_file(const char*, long, long, int TSRMLS_DC);
static const phpdbg_command_t phpdbg_list_commands[] = {
PHPDBG_LIST_EX_D(lines, "lists the specified lines", 'l'),

View File

@@ -57,7 +57,7 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC)
phpdbg_writeln(
"\t#%d-%d %s() %s",
op_array->line_start, op_array->line_end,
method->common.function_name,
method->common.function_name ? method->common.function_name : "{main}",
op_array->filename ? op_array->filename : "unknown");
}
@@ -86,43 +86,62 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC)
}
}
PHPDBG_PRINT(exec) /* {{{ */
{
if (PHPDBG_G(exec)) {
if (!PHPDBG_G(ops)) {
phpdbg_compile(TSRMLS_C);
}
if (PHPDBG_G(ops)) {
phpdbg_notice(
"Context %s", PHPDBG_G(exec));
phpdbg_print_function_helper((zend_function*) PHPDBG_G(ops) TSRMLS_CC);
}
} else {
phpdbg_error("No execution context set");
}
return SUCCESS;
} /* }}} */
PHPDBG_PRINT(class) /* {{{ */
{
zend_class_entry **ce;
if (param->type == STR_PARAM) {
if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) {
phpdbg_notice(
"%s %s: %s",
((*ce)->type == ZEND_USER_CLASS) ?
"User" : "Internal",
((*ce)->ce_flags & ZEND_ACC_INTERFACE) ?
"Interface" :
((*ce)->ce_flags & ZEND_ACC_ABSTRACT) ?
"Abstract Class" :
"Class",
(*ce)->name);
phpdbg_writeln("Methods (%d):", zend_hash_num_elements(&(*ce)->function_table));
if (zend_hash_num_elements(&(*ce)->function_table)) {
HashPosition position;
zend_function *method;
switch (param->type) {
case STR_PARAM: {
if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) {
phpdbg_notice(
"%s %s: %s",
((*ce)->type == ZEND_USER_CLASS) ?
"User" : "Internal",
((*ce)->ce_flags & ZEND_ACC_INTERFACE) ?
"Interface" :
((*ce)->ce_flags & ZEND_ACC_ABSTRACT) ?
"Abstract Class" :
"Class",
(*ce)->name);
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)) {
phpdbg_print_function_helper(method TSRMLS_CC);
phpdbg_writeln("Methods (%d):", zend_hash_num_elements(&(*ce)->function_table));
if (zend_hash_num_elements(&(*ce)->function_table)) {
HashPosition position;
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)) {
phpdbg_print_function_helper(method TSRMLS_CC);
}
}
} else {
phpdbg_error(
"The class %s could not be found", param->str);
}
} else {
phpdbg_error(
"Cannot find class %s", param->str);
return FAILURE;
}
} else {
phpdbg_error(
"Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC));
return FAILURE;
} break;
phpdbg_default_switch_case();
}
return SUCCESS;
@@ -130,33 +149,34 @@ PHPDBG_PRINT(class) /* {{{ */
PHPDBG_PRINT(method) /* {{{ */
{
if (param->type == METHOD_PARAM) {
zend_class_entry **ce;
if (zend_lookup_class(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));
switch (param->type) {
case METHOD_PARAM: {
zend_class_entry **ce;
if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) {
phpdbg_notice(
"%s Method %s",
(fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal",
fbc->common.function_name);
phpdbg_print_function_helper(fbc TSRMLS_CC);
if (zend_lookup_class(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));
if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) {
phpdbg_notice(
"%s Method %s",
(fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal",
fbc->common.function_name);
phpdbg_print_function_helper(fbc TSRMLS_CC);
} else {
phpdbg_error(
"The method %s could not be found", param->method.name);
}
efree(lcname);
} else {
phpdbg_error(
"The method %s could not be found", param->method.name);
"The class %s could not be found", param->method.class);
}
efree(lcname);
} else {
phpdbg_error(
"Failed to find the requested class %s", param->method.class);
}
} else {
phpdbg_error(
"Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC));
} break;
phpdbg_default_switch_case();
}
return SUCCESS;
@@ -164,51 +184,51 @@ PHPDBG_PRINT(method) /* {{{ */
PHPDBG_PRINT(func) /* {{{ */
{
if (param->type == STR_PARAM) {
HashTable *func_table = EG(function_table);
zend_function* fbc;
const char *func_name = param->str;
size_t func_name_len = param->len;
char *lcname;
/* search active scope if begins with period */
if (func_name[0] == '.') {
if (EG(scope)) {
func_name++;
func_name_len--;
switch (param->type) {
case STR_PARAM: {
HashTable *func_table = EG(function_table);
zend_function* fbc;
const char *func_name = param->str;
size_t func_name_len = param->len;
char *lcname;
/* search active scope if begins with period */
if (func_name[0] == '.') {
if (EG(scope)) {
func_name++;
func_name_len--;
func_table = &EG(scope)->function_table;
} else {
phpdbg_error("No active class");
return SUCCESS;
}
} else if (!EG(function_table)) {
phpdbg_error(
"No function table loaded");
return SUCCESS;
} else {
func_table = EG(function_table);
}
func_table = &EG(scope)->function_table;
} else {
phpdbg_error("No active class");
return SUCCESS;
}
} else if (!EG(function_table)) {
phpdbg_error(
"No function table loaded");
return SUCCESS;
} else {
func_table = EG(function_table);
}
lcname = zend_str_tolower_dup(func_name, func_name_len);
lcname = zend_str_tolower_dup(func_name, func_name_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_print_function_helper(fbc TSRMLS_CC);
} else {
phpdbg_error(
"The function %s could not be found", func_name);
}
efree(lcname);
} break;
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_print_function_helper(fbc TSRMLS_CC);
} else {
phpdbg_error(
"Function %s not found", func_name);
}
efree(lcname);
} else {
phpdbg_error(
"Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC));
phpdbg_default_switch_case();
}
return SUCCESS;

View File

@@ -34,6 +34,7 @@
/**
* Printer Forward Declarations
*/
PHPDBG_PRINT(exec);
PHPDBG_PRINT(opline);
PHPDBG_PRINT(class);
PHPDBG_PRINT(method);
@@ -43,6 +44,7 @@ PHPDBG_PRINT(func);
* Commands
*/
static const phpdbg_command_t phpdbg_print_commands[] = {
PHPDBG_PRINT_D(exec, "print execution context instructions", 'e'),
PHPDBG_PRINT_D(opline, "print the current opline information", 'o'),
PHPDBG_PRINT_D(class, "print out the instructions in the specified class", 'c'),
PHPDBG_PRINT_D(method, "print out the instructions in the specified method", 'm'),

View File

@@ -101,6 +101,8 @@ void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TS
zend_bool in_code = 0;
while (fgets(cmd, PHPDBG_MAX_CMD, fp) != NULL) {
phpdbg_command_t *selected = NULL;
cmd_len = strlen(cmd)-1;
while (*cmd && isspace(cmd[cmd_len-1]))
@@ -141,7 +143,7 @@ void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TS
goto next_line;
}
switch (phpdbg_do_cmd(phpdbg_prompt_commands, cmd, cmd_len TSRMLS_CC)) {
switch (phpdbg_do_cmd(phpdbg_prompt_commands, &selected, cmd, cmd_len TSRMLS_CC)) {
case FAILURE:
phpdbg_error(
"Unrecognized command in %s:%d: %s!", init_file, line, cmd);
@@ -188,42 +190,49 @@ void phpdbg_welcome(zend_bool cleaning TSRMLS_DC) /* {{{ */
static PHPDBG_COMMAND(exec) /* {{{ */
{
if (param->type == EMPTY_PARAM) {
phpdbg_error("No expression provided");
return SUCCESS;
} else {
if (param->type == STR_PARAM) {
if (PHPDBG_G(exec)) {
phpdbg_notice("Unsetting old execution context: %s", PHPDBG_G(exec));
efree(PHPDBG_G(exec));
PHPDBG_G(exec) = NULL;
}
if (PHPDBG_G(ops)) {
phpdbg_notice("Destroying compiled opcodes");
phpdbg_clean(0 TSRMLS_CC);
}
switch (param->type) {
case STR_PARAM: {
struct stat sb;
PHPDBG_G(exec) = phpdbg_resolve_path(param->str TSRMLS_CC);
if (VCWD_STAT(param->str, &sb) != FAILURE) {
if (sb.st_mode & S_IFREG|S_IFLNK) {
if (PHPDBG_G(exec)) {
phpdbg_notice("Unsetting old execution context: %s", PHPDBG_G(exec));
efree(PHPDBG_G(exec));
PHPDBG_G(exec) = NULL;
}
if (!PHPDBG_G(exec)) {
phpdbg_error("Cannot get real file path");
return FAILURE;
}
if (PHPDBG_G(ops)) {
phpdbg_notice("Destroying compiled opcodes");
phpdbg_clean(0 TSRMLS_CC);
}
PHPDBG_G(exec_len) = strlen(PHPDBG_G(exec));
PHPDBG_G(exec) = phpdbg_resolve_path(param->str TSRMLS_CC);
if (!PHPDBG_G(exec)) {
phpdbg_error("Cannot get real file path");
return SUCCESS;
}
PHPDBG_G(exec_len) = strlen(PHPDBG_G(exec));
phpdbg_notice("Set execution context: %s", PHPDBG_G(exec));
} else {
phpdbg_error("Cannot use %s as execution context, not a valid file or symlink", param->str);
}
} else {
phpdbg_error("Cannot stat %s, ensure the file exists", param->str);
}
} break;
phpdbg_default_switch_case();
}
phpdbg_notice("Set execution context: %s", PHPDBG_G(exec));
} else {
phpdbg_error("Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC));
}
}
return SUCCESS;
} /* }}} */
static inline int phpdbg_compile(TSRMLS_D) /* {{{ */
int phpdbg_compile(TSRMLS_D) /* {{{ */
{
zend_file_handle fh;
@@ -253,8 +262,9 @@ static PHPDBG_COMMAND(compile) /* {{{ */
{
if (!PHPDBG_G(exec)) {
phpdbg_error("No execution context");
return FAILURE;
return SUCCESS;
}
if (!EG(in_execution)) {
if (PHPDBG_G(ops)) {
phpdbg_error("Destroying previously compiled opcodes");
@@ -262,23 +272,28 @@ static PHPDBG_COMMAND(compile) /* {{{ */
}
}
return phpdbg_compile(TSRMLS_C);
phpdbg_compile(TSRMLS_C);
return SUCCESS;
} /* }}} */
static PHPDBG_COMMAND(step) /* {{{ */
{
if (param->type == EMPTY_PARAM || param->type == NUMERIC_PARAM) {
if (param->type == NUMERIC_PARAM && param->num) {
PHPDBG_G(flags) |= PHPDBG_IS_STEPPING;
} else {
PHPDBG_G(flags) &= ~PHPDBG_IS_STEPPING;
}
switch (param->type) {
case EMPTY_PARAM:
case NUMERIC_PARAM: {
if (param->type == NUMERIC_PARAM && param->num) {
PHPDBG_G(flags) |= PHPDBG_IS_STEPPING;
} else {
PHPDBG_G(flags) &= ~PHPDBG_IS_STEPPING;
}
phpdbg_notice("Stepping %s",
(PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off");
} else {
phpdbg_error("Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC));
}
phpdbg_notice("Stepping %s",
(PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off");
} break;
phpdbg_default_switch_case();
}
return SUCCESS;
} /* }}} */
@@ -297,7 +312,7 @@ static PHPDBG_COMMAND(run) /* {{{ */
{
if (EG(in_execution)) {
phpdbg_error("Cannot start another execution while one is in progress");
return FAILURE;
return SUCCESS;
}
if (PHPDBG_G(ops) || PHPDBG_G(exec)) {
@@ -307,8 +322,9 @@ static PHPDBG_COMMAND(run) /* {{{ */
if (!PHPDBG_G(ops)) {
if (phpdbg_compile(TSRMLS_C) == FAILURE) {
phpdbg_error("Failed to compile %s, cannot run", PHPDBG_G(exec));
return FAILURE;
phpdbg_error(
"Failed to compile %s, cannot run", PHPDBG_G(exec));
goto out;
}
}
@@ -328,55 +344,51 @@ static PHPDBG_COMMAND(run) /* {{{ */
if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
phpdbg_error("Caught excetion in VM");
return FAILURE;
} else return SUCCESS;
goto out;
}
} zend_end_try();
EG(active_op_array) = orig_op_array;
EG(opline_ptr) = orig_opline;
EG(return_value_ptr_ptr) = orig_retval_ptr;
return SUCCESS;
} else {
phpdbg_error("Nothing to execute!");
return FAILURE;
}
out:
return SUCCESS;
} /* }}} */
static PHPDBG_COMMAND(eval) /* {{{ */
{
if (param->type == EMPTY_PARAM) {
phpdbg_error("No expression provided!");
return FAILURE;
} else {
if (param->type == STR_PARAM) {
zend_bool stepping = (PHPDBG_G(flags) & PHPDBG_IS_STEPPING);
zval retval;
switch (param->type) {
case STR_PARAM: {
zend_bool stepping = (PHPDBG_G(flags) & PHPDBG_IS_STEPPING);
zval retval;
PHPDBG_G(flags) &= ~ PHPDBG_IS_STEPPING;
PHPDBG_G(flags) &= ~ PHPDBG_IS_STEPPING;
/* disable stepping while eval() in progress */
PHPDBG_G(flags) |= PHPDBG_IN_EVAL;
if (zend_eval_stringl(param->str, param->len,
&retval, "eval()'d code" TSRMLS_CC) == SUCCESS) {
zend_print_zval_r(
&retval, 0 TSRMLS_CC);
phpdbg_writeln(EMPTY);
zval_dtor(&retval);
}
PHPDBG_G(flags) &= ~PHPDBG_IN_EVAL;
/* disable stepping while eval() in progress */
PHPDBG_G(flags) |= PHPDBG_IN_EVAL;
if (zend_eval_stringl(param->str, param->len,
&retval, "eval()'d code" TSRMLS_CC) == SUCCESS) {
zend_print_zval_r(
&retval, 0 TSRMLS_CC);
phpdbg_writeln(EMPTY);
zval_dtor(&retval);
}
PHPDBG_G(flags) &= ~PHPDBG_IN_EVAL;
/* switch stepping back on */
if (stepping) {
PHPDBG_G(flags) |= PHPDBG_IS_STEPPING;
}
} break;
phpdbg_default_switch_case();
}
/* switch stepping back on */
if (stepping) {
PHPDBG_G(flags) |= PHPDBG_IS_STEPPING;
}
} else {
phpdbg_error(
"Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC));
return FAILURE;
}
}
return SUCCESS;
} /* }}} */
@@ -384,7 +396,7 @@ static PHPDBG_COMMAND(back) /* {{{ */
{
if (!EG(in_execution)) {
phpdbg_error("Not executing!");
return FAILURE;
return SUCCESS;
}
switch (param->type) {
@@ -393,9 +405,9 @@ static PHPDBG_COMMAND(back) /* {{{ */
zval zbacktrace;
zval **tmp;
HashPosition position;
int i = 0,
int i = 0,
limit = (param->type == NUMERIC_PARAM) ? param->num : 0;
zend_fetch_debug_backtrace(
&zbacktrace, 0, 0, limit TSRMLS_CC);
@@ -410,63 +422,61 @@ static PHPDBG_COMMAND(back) /* {{{ */
phpdbg_writeln(EMPTY);
zval_dtor(&zbacktrace);
return SUCCESS;
} break;
default: {
phpdbg_error(
"Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC));
return FAILURE;
}
phpdbg_default_switch_case();
}
return SUCCESS;
} /* }}} */
static PHPDBG_COMMAND(print) /* {{{ */
{
if (param->type == EMPTY_PARAM) {
phpdbg_writeln(SEPARATE);
phpdbg_notice("Execution Context Information");
switch (param->type) {
case EMPTY_PARAM: {
phpdbg_writeln(SEPARATE);
phpdbg_notice("Execution Context Information");
#ifdef HAVE_LIBREADLINE
phpdbg_writeln("Readline\tyes");
phpdbg_writeln("Readline\tyes");
#else
phpdbg_writeln("Readline\tno");
phpdbg_writeln("Readline\tno");
#endif
phpdbg_writeln("Exec\t\t%s", PHPDBG_G(exec) ? PHPDBG_G(exec) : "none");
phpdbg_writeln("Compiled\t%s", PHPDBG_G(ops) ? "yes" : "no");
phpdbg_writeln("Stepping\t%s", (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off");
phpdbg_writeln("Quietness\t%s", (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "on" : "off");
phpdbg_writeln("Oplog\t\t%s", PHPDBG_G(oplog) ? "on" : "off");
phpdbg_writeln("Exec\t\t%s", PHPDBG_G(exec) ? PHPDBG_G(exec) : "none");
phpdbg_writeln("Compiled\t%s", PHPDBG_G(ops) ? "yes" : "no");
phpdbg_writeln("Stepping\t%s", (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off");
phpdbg_writeln("Quietness\t%s", (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "on" : "off");
phpdbg_writeln("Oplog\t\t%s", PHPDBG_G(oplog) ? "on" : "off");
if (PHPDBG_G(ops)) {
phpdbg_writeln("Opcodes\t\t%d", PHPDBG_G(ops)->last);
if (PHPDBG_G(ops)) {
phpdbg_writeln("Opcodes\t\t%d", PHPDBG_G(ops)->last);
if (PHPDBG_G(ops)->last_var) {
phpdbg_writeln("Variables\t%d", PHPDBG_G(ops)->last_var-1);
} else {
phpdbg_writeln("Variables\tNone");
}
}
if (PHPDBG_G(ops)->last_var) {
phpdbg_writeln("Variables\t%d", PHPDBG_G(ops)->last_var-1);
} else {
phpdbg_writeln("Variables\tNone");
}
}
phpdbg_writeln("Executing\t%s", EG(in_execution) ? "yes" : "no");
if (EG(in_execution)) {
phpdbg_writeln("VM Return\t%d", PHPDBG_G(vmret));
}
phpdbg_writeln("Classes\t\t%d", zend_hash_num_elements(EG(class_table)));
phpdbg_writeln("Functions\t%d", zend_hash_num_elements(EG(function_table)));
phpdbg_writeln("Constants\t%d", zend_hash_num_elements(EG(zend_constants)));
phpdbg_writeln("Included\t%d", zend_hash_num_elements(&EG(included_files)));
phpdbg_writeln("Executing\t%s", EG(in_execution) ? "yes" : "no");
if (EG(in_execution)) {
phpdbg_writeln("VM Return\t%d", PHPDBG_G(vmret));
}
phpdbg_writeln("Classes\t\t%d", zend_hash_num_elements(EG(class_table)));
phpdbg_writeln("Functions\t%d", zend_hash_num_elements(EG(function_table)));
phpdbg_writeln("Constants\t%d", zend_hash_num_elements(EG(zend_constants)));
phpdbg_writeln("Included\t%d", zend_hash_num_elements(&EG(included_files)));
phpdbg_print_breakpoints(PHPDBG_BREAK_FILE TSRMLS_CC);
phpdbg_print_breakpoints(PHPDBG_BREAK_SYM TSRMLS_CC);
phpdbg_print_breakpoints(PHPDBG_BREAK_METHOD TSRMLS_CC);
phpdbg_print_breakpoints(PHPDBG_BREAK_OPLINE TSRMLS_CC);
phpdbg_print_breakpoints(PHPDBG_BREAK_COND TSRMLS_CC);
phpdbg_writeln(SEPARATE);
} else {
phpdbg_error("You must use a specific printer");
phpdbg_print_breakpoints(PHPDBG_BREAK_FILE TSRMLS_CC);
phpdbg_print_breakpoints(PHPDBG_BREAK_SYM TSRMLS_CC);
phpdbg_print_breakpoints(PHPDBG_BREAK_METHOD TSRMLS_CC);
phpdbg_print_breakpoints(PHPDBG_BREAK_OPLINE TSRMLS_CC);
phpdbg_print_breakpoints(PHPDBG_BREAK_COND TSRMLS_CC);
phpdbg_writeln(SEPARATE);
} break;
phpdbg_default_switch_case();
}
return SUCCESS;
@@ -490,11 +500,8 @@ static PHPDBG_COMMAND(break) /* {{{ */
case STR_PARAM:
phpdbg_set_breakpoint_symbol(param->str TSRMLS_CC);
break;
default:
phpdbg_error(
"Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC));
return FAILURE;
phpdbg_default_switch_case();
}
return SUCCESS;
@@ -516,7 +523,7 @@ static PHPDBG_COMMAND(clean) /* {{{ */
{
if (EG(in_execution)) {
phpdbg_error("Cannot clean environment while executing");
return FAILURE;
return SUCCESS;
}
phpdbg_notice("Cleaning Execution Environment");
@@ -571,130 +578,149 @@ static PHPDBG_COMMAND(aliases) /* {{{ */
prompt_command->name, prompt_command->tip);
}
}
++prompt_command;
}
phpdbg_help_footer();
return SUCCESS;
} /* }}} */
static PHPDBG_COMMAND(oplog) /* {{{ */
{
if (param->type == EMPTY_PARAM ||
((param->type == NUMERIC_PARAM) && !param->num)) {
if (PHPDBG_G(oplog)) {
phpdbg_notice("Disabling oplog");
fclose(
PHPDBG_G(oplog));
return SUCCESS;
} else {
phpdbg_error("No oplog currently open");
return FAILURE;
}
} else {
if (param->type == STR_PARAM) {
/* open oplog */
switch (param->type) {
case EMPTY_PARAM:
case NUMERIC_PARAM:
if ((param->type != NUMERIC_PARAM) || !param->num) {
if (PHPDBG_G(oplog)) {
phpdbg_notice("Disabling oplog");
fclose(
PHPDBG_G(oplog));
} else {
phpdbg_error("No oplog currently open");
}
}
break;
case STR_PARAM: {
/* open oplog */
FILE *old = PHPDBG_G(oplog);
PHPDBG_G(oplog) = fopen(param->str, "w+");
if (!PHPDBG_G(oplog)) {
phpdbg_error("Failed to open %s for oplog", param->str);
PHPDBG_G(oplog) = old;
return FAILURE;
} else {
if (old) {
phpdbg_notice("Closing previously open oplog");
fclose(old);
}
phpdbg_notice("Successfully opened oplog %s", param->str);
return SUCCESS;
}
} else {
phpdbg_error(
"Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC));
return FAILURE;
}
} break;
phpdbg_default_switch_case();
}
return SUCCESS;
} /* }}} */
static PHPDBG_COMMAND(help) /* {{{ */
{
if (param->type == EMPTY_PARAM) {
const phpdbg_command_t *prompt_command = phpdbg_prompt_commands;
const phpdbg_command_t *help_command = phpdbg_help_commands;
phpdbg_help_header();
phpdbg_writeln("To get help regarding a specific command type \"help command\"");
switch (param->type) {
case EMPTY_PARAM: {
const phpdbg_command_t *prompt_command = phpdbg_prompt_commands;
const phpdbg_command_t *help_command = phpdbg_help_commands;
phpdbg_notice("Commands");
phpdbg_help_header();
phpdbg_writeln("To get help regarding a specific command type \"help command\"");
while (prompt_command && prompt_command->name) {
phpdbg_writeln(
"\t%s\t%s", prompt_command->name, prompt_command->tip);
++prompt_command;
}
phpdbg_notice("Commands");
phpdbg_notice("Helpers Loaded");
while (prompt_command && prompt_command->name) {
phpdbg_writeln(
"\t%s\t%s", prompt_command->name, prompt_command->tip);
++prompt_command;
}
while (help_command && help_command->name) {
phpdbg_writeln("\t%s\t%s", help_command->name, help_command->tip);
++help_command;
}
phpdbg_notice("Helpers Loaded");
phpdbg_notice("Command Line Options and Flags");
phpdbg_writeln("\tOption\tExample\t\t\tPurpose");
phpdbg_writeln(EMPTY);
phpdbg_writeln("\t-c\t-c/my/php.ini\t\tSet php.ini file to load");
phpdbg_writeln("\t-d\t-dmemory_limit=4G\tSet a php.ini directive");
phpdbg_writeln("\t-n\t-N/A\t\t\tDisable default php.ini");
phpdbg_writeln("\t-e\t-emytest.php\t\tSet execution context");
phpdbg_writeln("\t-v\tN/A\t\t\tEnable opline output while executing");
phpdbg_writeln("\t-s\tN/A\t\t\tEnable stepping");
phpdbg_writeln("\t-b\tN/A\t\t\tDisable the use of colours");
phpdbg_writeln("\t-i\t-imy.init\t\tSet the phpdbginit file");
phpdbg_writeln("\t-I\tN/A\t\t\tDisable loading .phpdbginit");
phpdbg_writeln("\t-O\t-Omy.oplog\t\tSets oplog output file");
phpdbg_help_footer();
} else {
phpdbg_error(
"Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC));
return FAILURE;
}
while (help_command && help_command->name) {
phpdbg_writeln("\t%s\t%s", help_command->name, help_command->tip);
++help_command;
}
phpdbg_notice("Command Line Options and Flags");
phpdbg_writeln("\tOption\tExample\t\t\tPurpose");
phpdbg_writeln(EMPTY);
phpdbg_writeln("\t-c\t-c/my/php.ini\t\tSet php.ini file to load");
phpdbg_writeln("\t-d\t-dmemory_limit=4G\tSet a php.ini directive");
phpdbg_writeln("\t-n\t-N/A\t\t\tDisable default php.ini");
phpdbg_writeln("\t-e\t-emytest.php\t\tSet execution context");
phpdbg_writeln("\t-v\tN/A\t\t\tEnable opline output while executing");
phpdbg_writeln("\t-s\tN/A\t\t\tEnable stepping");
phpdbg_writeln("\t-b\tN/A\t\t\tDisable the use of colours");
phpdbg_writeln("\t-i\t-imy.init\t\tSet the phpdbginit file");
phpdbg_writeln("\t-I\tN/A\t\t\tDisable loading .phpdbginit");
phpdbg_writeln("\t-O\t-Omy.oplog\t\tSets oplog output file");
phpdbg_help_footer();
} break;
phpdbg_default_switch_case();
}
return SUCCESS;
} /* }}} */
static PHPDBG_COMMAND(quiet) { /* {{{ */
if (param->type == NUMERIC_PARAM) {
if (param->num) {
PHPDBG_G(flags) |= PHPDBG_IS_QUIET;
} else {
PHPDBG_G(flags) &= ~PHPDBG_IS_QUIET;
}
phpdbg_notice("Quietness %s",
(PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "enabled" : "disabled");
} else {
phpdbg_error(
"Unsupported parameter type (%s) for command", phpdbg_get_param_type(param TSRMLS_CC));
return FAILURE;
static PHPDBG_COMMAND(quiet) /* {{{ */
{
switch (param->type) {
case NUMERIC_PARAM: {
if (param->num) {
PHPDBG_G(flags) |= PHPDBG_IS_QUIET;
} else {
PHPDBG_G(flags) &= ~PHPDBG_IS_QUIET;
}
phpdbg_notice("Quietness %s",
(PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "enabled" : "disabled");
} break;
phpdbg_default_switch_case();
}
return SUCCESS;
} /* }}} */
static PHPDBG_COMMAND(list) /* {{{ */
{
phpdbg_list_dispatch(param TSRMLS_CC);
switch (param->type) {
case NUMERIC_PARAM:
case EMPTY_PARAM:
return PHPDBG_LIST_HANDLER(lines)(param TSRMLS_CC);
case FILE_PARAM:
return PHPDBG_LIST_HANDLER(lines)(param TSRMLS_CC);
case STR_PARAM:
phpdbg_list_function_byname(param->str, param->len TSRMLS_CC);
break;
case METHOD_PARAM:
return PHPDBG_LIST_HANDLER(method)(param TSRMLS_CC);
break;
phpdbg_default_switch_case();
}
return SUCCESS;
} /* }}} */
int phpdbg_do_cmd(const phpdbg_command_t *command, char *cmd_line, size_t cmd_len TSRMLS_DC) /* {{{ */
int phpdbg_do_cmd( const phpdbg_command_t *command,
phpdbg_command_t **selected,
char *cmd_line, size_t cmd_len TSRMLS_DC) /* {{{ */
{
int rc = FAILURE;
char *expr = NULL;
#ifndef _WIN32
const char *cmd = strtok_r(cmd_line, " ", &expr);
@@ -703,12 +729,14 @@ int phpdbg_do_cmd(const phpdbg_command_t *command, char *cmd_line, size_t cmd_le
#endif
size_t expr_len = (cmd != NULL) ? strlen(cmd) : 0;
phpdbg_param_t *param = NULL;
while (command && command->name && command->handler) {
if ((command->name_len == expr_len
&& memcmp(cmd, command->name, expr_len) == 0)
|| ((expr_len == 1) && (command->alias && command->alias == cmd_line[0]))) {
phpdbg_param_t *param = emalloc(sizeof(phpdbg_param_t));
param = emalloc(sizeof(phpdbg_param_t));
PHPDBG_G(last) = (phpdbg_command_t*) command;
@@ -716,31 +744,41 @@ int phpdbg_do_cmd(const phpdbg_command_t *command, char *cmd_line, size_t cmd_le
if (PHPDBG_G(lparam)) {
//phpdbg_clear_param(
// PHPDBG_G(lparam) TSRMLS_CC);
//efree(PHPDBG_G(lparam));
//efree(PHPDBG_G(lparam));
}
phpdbg_parse_param(
expr,
(cmd_len - expr_len) ? (((cmd_len - expr_len) - sizeof(" "))+1) : 0,
(cmd_len - expr_len) ? (((cmd_len - expr_len) - sizeof(" "))+1) : 0,
param TSRMLS_CC);
PHPDBG_G(lparam) = param;
if (command->subs && (param->type == STR_PARAM)) {
if (phpdbg_do_cmd(command->subs, param->str, param->len TSRMLS_CC) == SUCCESS) {
if (phpdbg_do_cmd(command->subs, selected, param->str, param->len TSRMLS_CC) == SUCCESS) {
rc = SUCCESS;
break;
/* because we can */
phpdbg_clear_param(param TSRMLS_CC);
efree(param);
goto done;
}
}
phpdbg_debug("phpdbg_do_cmd(%s, \"%s\")",
command->name, phpdbg_get_param_type(param TSRMLS_CC));
*selected = (phpdbg_command_t*) command;
rc = command->handler(param TSRMLS_CC);
break;
}
++command;
}
break;
}
++command;
}
done:
if (selected && param) {
phpdbg_debug(
"phpdbg_do_cmd(%s, \"%s\"): %d",
command->name, phpdbg_get_param_type(param TSRMLS_CC), (rc==SUCCESS));
}
return rc;
} /* }}} */
@@ -773,11 +811,14 @@ int phpdbg_interactive(TSRMLS_D) /* {{{ */
cmd[cmd_len] = '\0';
if (*cmd && cmd_len > 0L) {
/* keep a cursor to selected command */
phpdbg_command_t *selected = NULL;
#ifdef HAVE_LIBREADLINE
add_history(cmd);
#endif
switch (ret = phpdbg_do_cmd(phpdbg_prompt_commands, cmd, cmd_len TSRMLS_CC)) {
switch (ret = phpdbg_do_cmd(phpdbg_prompt_commands, &selected, cmd, cmd_len TSRMLS_CC)) {
case FAILURE:
if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
phpdbg_error("Failed to execute %s!", cmd);
@@ -966,7 +1007,8 @@ zend_vm_enter:
#define DO_INTERACTIVE() do {\
phpdbg_list_file(\
zend_get_executed_filename(TSRMLS_C), \
2, \
3, \
zend_get_executed_lineno(TSRMLS_C)-1, \
zend_get_executed_lineno(TSRMLS_C) \
TSRMLS_CC\
);\

View File

@@ -33,7 +33,7 @@
/**
* Command Executor
*/
int phpdbg_do_cmd(const phpdbg_command_t *command, char *cmd_line, size_t cmd_len TSRMLS_DC);
int phpdbg_do_cmd(const phpdbg_command_t *command, phpdbg_command_t **selected, char *cmd_line, size_t cmd_len TSRMLS_DC);
/**
* Command Declarators
@@ -51,6 +51,7 @@ void phpdbg_init(char *init_file, size_t init_file_len, zend_bool use_default TS
void phpdbg_welcome(zend_bool cleaning TSRMLS_DC);
int phpdbg_interactive(TSRMLS_D);
void phpdbg_print_opline(zend_execute_data *execute_data, zend_bool ignore_flags TSRMLS_DC);
int phpdbg_compile(TSRMLS_D);
void phpdbg_clean(zend_bool full TSRMLS_DC);
#if PHP_VERSION_ID >= 50500
@@ -59,4 +60,11 @@ void phpdbg_execute_ex(zend_execute_data *execute_data TSRMLS_DC);
void phpdbg_execute_ex(zend_op_array *op_array TSRMLS_DC);
#endif
#define phpdbg_default_switch_case() \
default:\
phpdbg_error(\
"Unsupported parameter type (%s) for command", \
phpdbg_get_param_type(param TSRMLS_CC)); \
break
#endif /* PHPDBG_PROMPT_H */