mirror of
https://github.com/php/php-src.git
synced 2024-09-22 10:27:25 +00:00
stepping
This commit is contained in:
parent
8043d1ee5f
commit
5c866a9f13
1
phpdbg.c
1
phpdbg.c
@ -26,6 +26,7 @@ void (*zend_execute_internal_old)(zend_execute_data *execute_data_ptr, zend_fcal
|
||||
static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) {
|
||||
pg->exec = NULL;
|
||||
pg->ops = NULL;
|
||||
pg->stepping = 0;
|
||||
}
|
||||
|
||||
static PHP_MINIT_FUNCTION(phpdbg) {
|
||||
|
4
phpdbg.h
4
phpdbg.h
@ -36,12 +36,16 @@
|
||||
# define PHPDBG_G(v) (phpdbg_globals.v)
|
||||
#endif
|
||||
|
||||
#define PHPDBG_NEXT 2
|
||||
|
||||
ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
|
||||
HashTable breaks;
|
||||
char *exec; /* file to execute */
|
||||
size_t exec_len; /* size of exec */
|
||||
zend_op_array *ops; /* op_array */
|
||||
zval *retval; /* return value */
|
||||
zend_bool stepping; /* stepping */
|
||||
int vmret; /* return from last opcode handler execution */
|
||||
ZEND_END_MODULE_GLOBALS(phpdbg)
|
||||
|
||||
#include "phpdbg_prompt.h"
|
||||
|
@ -30,6 +30,20 @@ PHPDBG_HELP(exec) /* {{{ */
|
||||
return SUCCESS;
|
||||
} /* }}} */
|
||||
|
||||
PHPDBG_HELP(step) { /* {{{ */
|
||||
printf("You can enable and disable stepping at any phpdbg prompt during execution\n");
|
||||
printf("For example:\n");
|
||||
printf("phpdbg> stepping 1\n");
|
||||
printf("Will enable stepping\n");
|
||||
printf("While stepping is enabled you are presented with a prompt after the execution of each opcode\n");
|
||||
return SUCCESS;
|
||||
} /* }}} */
|
||||
|
||||
PHPDBG_HELP(next) { /* {{{ */
|
||||
printf("While stepping through execution, use the next command to step back into the vm and execute the next opcode");
|
||||
return SUCCESS;
|
||||
} /* }}} */
|
||||
|
||||
PHPDBG_HELP(compile) /* {{{ */
|
||||
{
|
||||
printf("Pre-compilation of the execution context provides the opportunity to inspect the opcodes before they are executed\n");
|
||||
@ -43,7 +57,7 @@ PHPDBG_HELP(print) /* {{{ */
|
||||
{
|
||||
printf("By default, print will show information about the current execution environment\n");
|
||||
printf("To show specific information pass an expression to print, for example:\n");
|
||||
printf("\tprint opcodes[0]\n");
|
||||
printf("\tphpdbg> print opcodes[0]\n");
|
||||
printf("Will show the opline @ 0\n");
|
||||
printf("Available print commands:\n");
|
||||
printf("\tNone\n");
|
||||
|
@ -33,6 +33,8 @@
|
||||
*/
|
||||
PHPDBG_HELP(exec);
|
||||
PHPDBG_HELP(compile);
|
||||
PHPDBG_HELP(step);
|
||||
PHPDBG_HELP(next);
|
||||
PHPDBG_HELP(run);
|
||||
PHPDBG_HELP(print);
|
||||
PHPDBG_HELP(break);
|
||||
@ -43,6 +45,8 @@ PHPDBG_HELP(break);
|
||||
static const phpdbg_command_t phpdbg_help_commands[] = {
|
||||
PHPDBG_HELP_D(exec, "the execution context should be a valid phpdbg path"),
|
||||
PHPDBG_HELP_D(compile, "pre-compilation allows inspection of code before execution"),
|
||||
PHPDBG_HELP_D(step, "stepping through execution allows inspection of the opline after every opcode"),
|
||||
PHPDBG_HELP_D(next, "execute the next opcode"),
|
||||
PHPDBG_HELP_D(run, "execution inside the phpdbg vm allows detailed inspection and debugging"),
|
||||
PHPDBG_HELP_D(print, "printing allows inspection of the execution environment"),
|
||||
PHPDBG_HELP_D(break, "breakpoints allow execution interruption"),
|
||||
|
@ -85,6 +85,15 @@ static PHPDBG_COMMAND(compile) { /* {{{ */
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
static PHPDBG_COMMAND(step) { /* {{{ */
|
||||
PHPDBG_G(stepping) = atoi(expr);
|
||||
return SUCCESS;
|
||||
} /* }}} */
|
||||
|
||||
static PHPDBG_COMMAND(next) { /* {{{ */
|
||||
return PHPDBG_NEXT;
|
||||
} /* }}} */
|
||||
|
||||
static PHPDBG_COMMAND(run) { /* {{{ */
|
||||
if (PHPDBG_G(ops) || PHPDBG_G(exec)) {
|
||||
if (!PHPDBG_G(ops)) {
|
||||
@ -116,9 +125,12 @@ static PHPDBG_COMMAND(print) { /* {{{ */
|
||||
printf("Showing Execution Context Information:\n");
|
||||
printf("Exec\t\t%s\n", PHPDBG_G(exec) ? PHPDBG_G(exec) : "none");
|
||||
printf("Compiled\t%s\n", PHPDBG_G(ops) ? "yes" : "no");
|
||||
printf("Stepping\t%s\n", PHPDBG_G(stepping) ? "on" : "off");
|
||||
if (PHPDBG_G(ops)) {
|
||||
printf("Opcodes\t\t%d\n", PHPDBG_G(ops)->last-1);
|
||||
printf("Variables\t%d\n", PHPDBG_G(ops)->last_var-1);
|
||||
printf("Opcodes\t\t%d\n", PHPDBG_G(ops)->last);
|
||||
if (PHPDBG_G(ops)->last_var) {
|
||||
printf("Variables\t%d\n", PHPDBG_G(ops)->last_var-1);
|
||||
} else printf("Variables\tNone\n");
|
||||
}
|
||||
} else {
|
||||
printf(
|
||||
@ -175,6 +187,8 @@ static PHPDBG_COMMAND(help) /* {{{ */
|
||||
static const phpdbg_command_t phpdbg_prompt_commands[] = {
|
||||
PHPDBG_COMMAND_D(exec, "set execution context"),
|
||||
PHPDBG_COMMAND_D(compile, "attempt to pre-compile execution context"),
|
||||
PHPDBG_COMMAND_D(step, "step through execution"),
|
||||
PHPDBG_COMMAND_D(next, "next opcode"),
|
||||
PHPDBG_COMMAND_D(run, "attempt execution"),
|
||||
PHPDBG_COMMAND_D(print, "print something"),
|
||||
PHPDBG_COMMAND_D(break, "set breakpoint"),
|
||||
@ -200,7 +214,7 @@ int phpdbg_do_cmd(const phpdbg_command_t *command, char *cmd_line, size_t cmd_le
|
||||
return FAILURE;
|
||||
} /* }}} */
|
||||
|
||||
void phpdbg_interactive(int argc, char **argv TSRMLS_DC) /* {{{ */
|
||||
int phpdbg_interactive(int argc, char **argv TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
char cmd[PHPDBG_MAX_CMD];
|
||||
|
||||
@ -214,13 +228,20 @@ void phpdbg_interactive(int argc, char **argv TSRMLS_DC) /* {{{ */
|
||||
}
|
||||
|
||||
if (cmd_len) {
|
||||
if (phpdbg_do_cmd(phpdbg_prompt_commands, cmd, cmd_len TSRMLS_CC) == FAILURE) {
|
||||
printf("error executing %s !\n", cmd);
|
||||
}
|
||||
switch (phpdbg_do_cmd(phpdbg_prompt_commands, cmd, cmd_len TSRMLS_CC)) {
|
||||
case FAILURE:
|
||||
printf("error executing %s !\n", cmd);
|
||||
break;
|
||||
|
||||
case PHPDBG_NEXT:
|
||||
return PHPDBG_NEXT;
|
||||
}
|
||||
}
|
||||
|
||||
printf("phpdbg> ");
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
} /* }}} */
|
||||
|
||||
void phpdbg_execute_ex(zend_execute_data *execute_data TSRMLS_DC)
|
||||
@ -236,7 +257,6 @@ zend_vm_enter:
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int ret;
|
||||
#ifdef ZEND_WIN32
|
||||
if (EG(timed_out)) {
|
||||
zend_timeout(0);
|
||||
@ -245,8 +265,17 @@ zend_vm_enter:
|
||||
|
||||
printf("[OPLINE: %p]\n", execute_data->opline);
|
||||
|
||||
if ((ret = execute_data->opline->handler(execute_data TSRMLS_CC)) > 0) {
|
||||
switch (ret) {
|
||||
PHPDBG_G(vmret) = execute_data->opline->handler(execute_data TSRMLS_CC);
|
||||
|
||||
if (PHPDBG_G(stepping)) {
|
||||
while (phpdbg_interactive(
|
||||
0, NULL TSRMLS_CC) != PHPDBG_NEXT) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (PHPDBG_G(vmret) > 0) {
|
||||
switch (PHPDBG_G(vmret)) {
|
||||
case 1:
|
||||
EG(in_execution) = original_in_execution;
|
||||
return;
|
||||
|
@ -56,7 +56,7 @@ int phpdbg_do_cmd(const phpdbg_command_t *command, char *cmd_line, size_t cmd_le
|
||||
#define PHPDBG_COMMAND(name) \
|
||||
int phpdbg_do_##name(const char *expr, size_t expr_len TSRMLS_DC)
|
||||
|
||||
void phpdbg_interactive(int argc, char **argv TSRMLS_DC);
|
||||
int phpdbg_interactive(int argc, char **argv TSRMLS_DC);
|
||||
void phpdbg_execute_ex(zend_execute_data *execute_data TSRMLS_DC);
|
||||
|
||||
#endif /* PHPDBG_PROMPT_H */
|
||||
|
Loading…
Reference in New Issue
Block a user