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:
48
phpdbg_bp.c
48
phpdbg_bp.c
@@ -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) /* {{{ */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
206
phpdbg_list.c
206
phpdbg_list.c
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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'),
|
||||
|
||||
212
phpdbg_print.c
212
phpdbg_print.c
@@ -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;
|
||||
|
||||
@@ -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'),
|
||||
|
||||
486
phpdbg_prompt.c
486
phpdbg_prompt.c
@@ -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\
|
||||
);\
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user