#define PHPDBG_NEXT 2
+/* {{{ flags */
+#define PHPDBG_HAS_FILE_BP 0x00000001
+#define PHPDBG_HAS_SYM_BP 0x00000010
+#define PHPDBG_HAS_OPLINE_BP 0x00000100
+#define PHPDBG_HAS_METHOD_BP 0x00001000
+
+#define PHPDBG_IS_STEPPING 0x00010000
+#define PHPDBG_IS_QUIET 0x00100000
+#define PHPDBG_IS_QUITTING 0x01000000 /* }}} */
+
typedef struct _phpdbg_command_t phpdbg_command_t;
ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
zend_op_array *ops; /* op_array */
zval *retval; /* return value */
int bp_count; /* breakpoint count */
- int stepping; /* stepping */
int vmret; /* return from last opcode handler execution */
- zend_bool has_file_bp; /* file-based breakpoint has been set */
- zend_bool has_sym_bp; /* symbol-based breakpoint has been set */
- zend_bool has_opline_bp; /* opline-based breakpoint has been set */
- zend_bool has_method_bp; /* method-based breakpoint has been set */
- zend_bool quitting; /* quitting flag */
- int quiet; /* quiet */
phpdbg_command_t *last; /* last command */
const char *last_params; /* last expression */
size_t last_params_len; /* last expression length */
+ zend_ulong flags; /* phpdbg flags */
ZEND_END_MODULE_GLOBALS(phpdbg)
#endif /* PHPDBG_H */
new_break.filename = estrndup(path, path_len);
new_break.line = line_num;
- PHPDBG_G(has_file_bp) = 1;
+ PHPDBG_G(flags) |= PHPDBG_HAS_FILE_BP;
if (zend_hash_find(&PHPDBG_G(bp_files),
new_break.filename, path_len, (void**)&break_files_ptr) == FAILURE) {
if (!zend_hash_exists(&PHPDBG_G(bp_symbols), name, name_len)) {
phpdbg_breaksymbol_t new_break;
- PHPDBG_G(has_sym_bp) = 1;
+ PHPDBG_G(flags) |= PHPDBG_HAS_SYM_BP;
new_break.symbol = estrndup(name, name_len + 1);
new_break.id = PHPDBG_G(bp_count)++;
if (!zend_hash_exists(class_table, func_name, func_len)) {
phpdbg_breakmethod_t new_break;
- PHPDBG_G(has_method_bp) = 1;
+ PHPDBG_G(flags) |= PHPDBG_HAS_METHOD_BP;
new_break.class_name = class_name;
new_break.class_len = class_len;
if (!zend_hash_index_exists(&PHPDBG_G(bp_oplines), opline)) {
phpdbg_breakline_t new_break;
- PHPDBG_G(has_opline_bp) = 1;
+ PHPDBG_G(flags) |= PHPDBG_HAS_OPLINE_BP;
new_break.name = strdup(name);
new_break.opline = opline;
if (!zend_hash_index_exists(&PHPDBG_G(bp_oplines), (zend_ulong) opline)) {
phpdbg_breakline_t new_break;
- PHPDBG_G(has_opline_bp) = 1;
+ PHPDBG_G(flags) |= PHPDBG_HAS_OPLINE_BP;
asprintf(
(char**)&new_break.name, "%p", (zend_op*) opline);
zend_hash_clean(&PHPDBG_G(bp_oplines));
zend_hash_clean(&PHPDBG_G(bp_methods));
- PHPDBG_G(has_file_bp) = 0;
- PHPDBG_G(has_sym_bp) = 0;
- PHPDBG_G(has_opline_bp) = 0;
- PHPDBG_G(has_method_bp) = 0;
+ PHPDBG_G(flags) &= ~(PHPDBG_HAS_FILE_BP|PHPDBG_HAS_SYM_BP|PHPDBG_HAS_METHOD_BP|PHPDBG_HAS_OPLINE_BP);
PHPDBG_G(bp_count) = 0;
} /* }}} */
static PHPDBG_COMMAND(step) /* {{{ */
{
- PHPDBG_G(stepping) = atoi(expr);
+ if (atoi(expr)) {
+ PHPDBG_G(flags) |= PHPDBG_IS_STEPPING;
+ } else {
+ PHPDBG_G(flags) &= ~PHPDBG_IS_STEPPING;
+ }
+
printf(
- "[Stepping %s]\n", PHPDBG_G(stepping) ? "on" : "off");
+ "[Stepping %s]\n", (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off");
return SUCCESS;
} /* }}} */
zend_try {
zend_execute(EG(active_op_array) TSRMLS_CC);
} zend_catch {
- if (!PHPDBG_G(quitting)) {
+ if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
printf("[Caught excetion in VM]\n");
return FAILURE;
} else return SUCCESS;
static PHPDBG_COMMAND(eval) /* {{{ */
{
zval retval;
-
+
if (expr_len) {
+ zend_bool stepping = (PHPDBG_G(flags) & PHPDBG_IS_STEPPING);
+
+ /* disable stepping while eval() in progress */
+ PHPDBG_G(flags) &= ~ PHPDBG_IS_STEPPING;
+
if (zend_eval_stringl((char*)expr, expr_len-1,
&retval, "eval()'d code" TSRMLS_CC) == SUCCESS) {
zend_print_zval_r(
&retval, 0 TSRMLS_CC);
printf("\n");
}
+
+ /* switch stepping back on */
+ if (stepping) {
+ PHPDBG_G(flags) |= PHPDBG_IS_STEPPING;
+ }
} else {
printf("[No expression provided !]\n");
return FAILURE;
printf("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");
+ printf("Stepping\t%s\n", (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off");
if (PHPDBG_G(ops)) {
printf("Opcodes\t\t%d\n", PHPDBG_G(ops)->last);
printf("Constants\t%d\n", zend_hash_num_elements(EG(zend_constants)));
printf("Included\t%d\n", zend_hash_num_elements(&EG(included_files)));
- if (PHPDBG_G(has_file_bp)) {
+ if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_BP)) {
HashPosition position;
zend_llist *points;
}
#endif
- if (PHPDBG_G(has_opline_bp)) {
+ if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP)) {
HashPosition position;
phpdbg_breakline_t *brake;
static PHPDBG_COMMAND(quit) /* {{{ */
{
- PHPDBG_G(quitting)=1;
+ PHPDBG_G(flags) |= PHPDBG_IS_QUITTING;
zend_bailout();
} /* }}} */
static PHPDBG_COMMAND(quiet) { /* {{{ */
- PHPDBG_G(quiet) = atoi(expr);
+ if (atoi(expr)) {
+ PHPDBG_G(flags) |= PHPDBG_IS_QUIET;
+ } else {
+ PHPDBG_G(flags) &= ~PHPDBG_IS_QUIET;
+ }
printf(
- "[Quietness %s]\n", PHPDBG_G(quiet) ? "enabled" : "disabled");
+ "[Quietness %s]\n", (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "enabled" : "disabled");
return SUCCESS;
} /* }}} */
printf("phpdbg> ");
- while (!PHPDBG_G(quitting) &&
+ while (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING) &&
fgets(cmd, PHPDBG_MAX_CMD, stdin) != NULL) {
size_t cmd_len = strlen(cmd) - 1;
if (cmd_len) {
switch (phpdbg_do_cmd(phpdbg_prompt_commands, cmd, cmd_len TSRMLS_CC)) {
case FAILURE:
- if (!PHPDBG_G(quitting)) {
+ if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
printf(
"[Failed to execute %s !]\n", cmd);
}
PHPDBG_G(last_params), PHPDBG_G(last_params_len) TSRMLS_CC);
}
- if (!PHPDBG_G(quitting)) {
+ if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
printf("phpdbg> ");
}
static void phpdbg_print_opline(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */
{
- if (!PHPDBG_G(quiet)) {
+ /* force out a line while stepping so the user knows what is happening */
+ if (!(PHPDBG_G(flags) & PHPDBG_IS_QUIET) || (PHPDBG_G(flags) & PHPDBG_IS_STEPPING)) {
zend_op *opline = execute_data->opline;
- printf("[OPLINE: %p:%s]\n", opline, phpdbg_decode_opcode(opline->opcode));
+ printf(
+ "[OPLINE: %p:%s]\n", opline, phpdbg_decode_opcode(opline->opcode));
}
} /* }}} */
phpdbg_print_opline(
execute_data TSRMLS_CC);
- if (PHPDBG_G(has_file_bp)
+ if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_BP)
&& phpdbg_find_breakpoint_file(execute_data->op_array TSRMLS_CC) == SUCCESS) {
while (phpdbg_interactive(TSRMLS_C) != PHPDBG_NEXT) {
- if (!PHPDBG_G(quitting)) {
+ if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
continue;
}
}
}
- if ((PHPDBG_G(has_sym_bp)||PHPDBG_G(has_method_bp))) {
+ if ((PHPDBG_G(flags) & (PHPDBG_HAS_METHOD_BP|PHPDBG_HAS_SYM_BP))) {
zend_execute_data *previous = execute_data->prev_execute_data;
if (previous && previous != execute_data && previous->opline) {
/* check we are the beginning of a function entry */
case ZEND_INIT_STATIC_METHOD_CALL: {
if (phpdbg_find_breakpoint_symbol(previous->function_state.function TSRMLS_CC) == SUCCESS) {
while (phpdbg_interactive(TSRMLS_C) != PHPDBG_NEXT) {
- if (!PHPDBG_G(quitting)) {
+ if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
continue;
}
}
}
}
- if (PHPDBG_G(has_opline_bp)
+ if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP)
&& phpdbg_find_breakpoint_opline(execute_data->opline TSRMLS_CC) == SUCCESS) {
while (phpdbg_interactive(TSRMLS_C) != PHPDBG_NEXT) {
- if (!PHPDBG_G(quitting)) {
+ if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
continue;
}
}
PHPDBG_G(vmret) = execute_data->opline->handler(execute_data TSRMLS_CC);
- if (PHPDBG_G(stepping)) {
+ if ((PHPDBG_G(flags) & PHPDBG_IS_STEPPING)) {
while (phpdbg_interactive(TSRMLS_C) != PHPDBG_NEXT) {
- if (!PHPDBG_G(quitting)) {
+ if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
continue;
}
}