# define PHPDBG_G(v) (phpdbg_globals.v)
#endif
+ #define PHPDBG_NEXT 2
+
ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
- HashTable break_files;
- HashTable break_symbols;
- char *exec; /* file to execute */
- size_t exec_len; /* size of exec */
- zend_op_array *ops; /* op_array */
- zval *retval; /* return value */
- zend_bool has_breakpoint; /* breakpoint has been set */
- 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 */
++ HashTable break_files;
++ HashTable break_symbols;
++ 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_bool has_file_bp; /* file-based breakpoint has been set */
ZEND_END_MODULE_GLOBALS(phpdbg)
#include "phpdbg_prompt.h"
return SUCCESS;
} /* }}} */
-static PHPDBG_COMMAND(break) { /* {{{ */
- return SUCCESS;
+static PHPDBG_COMMAND(break) /* {{{ */
+{
+ const char *line_pos = zend_memrchr(expr, ':', expr_len);
+
+ if (line_pos) {
+ long line_num = strtol(line_pos+1, NULL, 0);
+ phpdbg_breakfile_t new_break;
- zend_llist break_files;
++ zend_llist *break_files_ptr;
++
++ size_t name_len = line_pos - expr;
+
- new_break.filename = estrndup(expr, line_pos - expr);
++ new_break.filename = estrndup(expr, name_len);
+ new_break.line = line_num;
+
- PHPDBG_G(has_breakpoint) = 1;
++ PHPDBG_G(has_file_bp) = 1;
+
- if (zend_hash_find(&PHPDBG_G(break_files), new_break.filename, line_pos - expr, &break_files) == FAILURE) {
++ if (zend_hash_find(&PHPDBG_G(break_files),
++ new_break.filename, name_len, (void**)&break_files_ptr) == FAILURE) {
++ zend_llist break_files;
+ zend_llist_init(&break_files, sizeof(phpdbg_breakfile_t), NULL, 0);
++
++ zend_hash_update(&PHPDBG_G(break_files),
++ new_break.filename, name_len, &break_files, sizeof(zend_llist), (void**)&break_files_ptr);
+ }
- zend_llist_add_element(&break_files, &new_break);
++ zend_llist_add_element(break_files_ptr, &new_break);
+ }
+
+ return SUCCESS;
} /* }}} */
static PHPDBG_COMMAND(quit) /* {{{ */
return FAILURE;
} /* }}} */
- void phpdbg_breakpoint(zend_op_array *op_array) /* {{{ */
++int phpdbg_breakpoint(zend_op_array *op_array TSRMLS_DC) /* {{{ */
+{
- printf(">> %s\n", op_array->filename);
++ size_t name_len = strlen(op_array->filename);
++ zend_llist *break_list;
++
++ if (zend_hash_find(&PHPDBG_G(break_files), op_array->filename, name_len,
++ (void**)&break_list) == SUCCESS) {
++ zend_llist_element *le;
++
++ for (le = break_list->head; le; le = le->next) {
++ phpdbg_breakfile_t *bp = (phpdbg_breakfile_t*) le->data;
++
++ if (bp->line == (*EG(opline_ptr))->lineno) {
++ printf("breakpoint reached!\n");
++ return SUCCESS;
++ }
++ }
++ }
++
++ 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];
}
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)
#endif
printf("[OPLINE: %p]\n", execute_data->opline);
-
- 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(has_breakpoint)) {
- phpdbg_breakpoint(execute_data->op_array);
++ if (PHPDBG_G(has_file_bp)
++ && phpdbg_breakpoint(execute_data->op_array TSRMLS_CC) == SUCCESS) {
++ while (phpdbg_interactive(0, NULL TSRMLS_CC) != PHPDBG_NEXT) {
++ continue;
++ }
++ }
++
++ 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 ((ret = execute_data->opline->handler(execute_data TSRMLS_CC)) > 0) {
- switch (ret) {
+ if (PHPDBG_G(vmret) > 0) {
+ switch (PHPDBG_G(vmret)) {
case 1:
EG(in_execution) = original_in_execution;
return;