]> granicus.if.org Git - php/commitdiff
break on opline
authorkrakjoe <joe.watkins@live.co.uk>
Mon, 11 Nov 2013 11:54:41 +0000 (11:54 +0000)
committerkrakjoe <joe.watkins@live.co.uk>
Mon, 11 Nov 2013 11:54:41 +0000 (11:54 +0000)
phpdbg.c
phpdbg.h
phpdbg_bp.c
phpdbg_bp.h
phpdbg_prompt.c

index bae33aab91b3ba9028417c10acd87245eb30a3bc..3aa8c035241355a4d68b320e005a6894c305d475 100644 (file)
--- a/phpdbg.c
+++ b/phpdbg.c
@@ -40,6 +40,7 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */
     pg->last_params_len = 0;
     pg->has_file_bp = 0;
     pg->has_sym_bp = 0;
+    pg->has_opline_bp = 0;
 } /* }}} */
 
 static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */
@@ -66,7 +67,8 @@ static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */
 {
        zend_hash_init(&PHPDBG_G(bp_files),   8, NULL, php_phpdbg_destroy_bp_file, 0);
        zend_hash_init(&PHPDBG_G(bp_symbols), 8, NULL, php_phpdbg_destroy_bp_symbol, 0);
-
+    zend_hash_init(&PHPDBG_G(bp_oplines), 8, NULL, NULL, 0);
+    
        return SUCCESS;
 } /* }}} */
 
@@ -74,7 +76,8 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
 {
     zend_hash_destroy(&PHPDBG_G(bp_files));
     zend_hash_destroy(&PHPDBG_G(bp_symbols));
-
+    zend_hash_destroy(&PHPDBG_G(bp_oplines));
+    
     if (PHPDBG_G(exec)) {
         efree(PHPDBG_G(exec));
     }
index e8c02da70ad3c2e13f8c81b875cbc430223d1551..8adc69cf4f23fa271e0b0f7d35f3245b608c244d 100644 (file)
--- a/phpdbg.h
+++ b/phpdbg.h
@@ -50,20 +50,22 @@ typedef struct _phpdbg_command_t phpdbg_command_t;
 ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
        HashTable bp_files;
        HashTable bp_symbols;
-       char *exec;             /* file to execute */
-       size_t exec_len;        /* size of exec */
-       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 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 */
+       HashTable bp_oplines;
+       char *exec;                 /* file to execute */
+       size_t exec_len;            /* size of exec */
+       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 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_END_MODULE_GLOBALS(phpdbg)
 
 #endif /* PHPDBG_H */
index 236c0b4e0ebff683b8cd80059b55ead73790b8ca..b8b2d35113e44a42bda86a7416ca7f25420e1d8d 100644 (file)
@@ -59,7 +59,7 @@ void phpdbg_set_breakpoint_file(const char *path, long line_num TSRMLS_DC) /* {{
        zend_llist_add_element(break_files_ptr, &new_break);
        
        printf(
-           "Breakpoint #%d added at %s:%d\n", new_break.id, new_break.filename, new_break.line);
+           "Breakpoint #%d added at %s:%ld\n", new_break.id, new_break.filename, new_break.line);
 } /* }}} */
 
 void phpdbg_set_breakpoint_symbol(const char *name TSRMLS_DC) /* {{{ */
@@ -83,6 +83,29 @@ void phpdbg_set_breakpoint_symbol(const char *name TSRMLS_DC) /* {{{ */
        }
 } /* }}} */
 
+void phpdbg_set_breakpoint_opline(const char *name TSRMLS_DC) /* {{{ */
+{
+       size_t name_len = strlen(name);
+
+       if (!zend_hash_exists(&PHPDBG_G(bp_oplines), name, name_len)) {
+               phpdbg_breakline_t new_break;
+
+               PHPDBG_G(has_opline_bp) = 1;
+
+               sscanf(
+                   name, "%x", &new_break.opline);
+               
+               new_break.id = PHPDBG_G(bp_count)++;
+        
+               zend_hash_update(&PHPDBG_G(bp_oplines), name,
+                       name_len, &new_break, sizeof(phpdbg_breakline_t), NULL);
+           
+           printf("Breakpoint #%d added at 0x%x\n", new_break.id, new_break.opline);
+       } else {
+           printf("Breakpoint exists at %s\n", name);
+       }
+} /* }}} */
+
 int phpdbg_find_breakpoint_file(zend_op_array *op_array TSRMLS_DC) /* {{{ */
 {
        size_t name_len = strlen(op_array->filename);
@@ -130,3 +153,25 @@ int phpdbg_find_breakpoint_symbol(zend_function *fbc TSRMLS_DC) /* {{{ */
 
        return FAILURE;
 } /* }}} */
+
+int phpdbg_find_breakpoint_opline(void *opline TSRMLS_DC) /* {{{ */
+{
+       char *opstring = NULL;
+       size_t opstring_len;
+       phpdbg_breakline_t *bp;
+
+    opstring_len = asprintf(
+        &opstring, "0x%x", (unsigned int) opline);
+
+       if (zend_hash_find(&PHPDBG_G(bp_oplines), opstring, opstring_len,
+               (void**)&bp) == SUCCESS) {
+               printf("Breakpoint #%d in 0x%x at %s\n", bp->id, bp->opline,
+                       zend_get_executed_filename(TSRMLS_C));
+           free(opstring);
+           
+               return SUCCESS;
+       }
+       
+    free(opstring);
+       return FAILURE;
+} /* }}} */
index 104e9d0c1d9aa90efe9848b3340d47c24109043f..3ab00048d954ad222e8dd5ad8daeabfb09c48fcb 100644 (file)
@@ -37,10 +37,20 @@ typedef struct _phpdbg_breaksymbol_t {
        int id;
 } phpdbg_breaksymbol_t;
 
+/**
+ * Breakpoint opline based representation
+ */
+typedef struct _phpdbg_breakline_t {
+    zend_uint opline;
+    int id;
+} phpdbg_breakline_t;
+
 void phpdbg_set_breakpoint_file(const char*, long TSRMLS_DC);
 void phpdbg_set_breakpoint_symbol(const char* TSRMLS_DC);
+void phpdbg_set_breakpoint_opline(const char* TSRMLS_DC);
 
 int phpdbg_find_breakpoint_file(zend_op_array* TSRMLS_DC);
 int phpdbg_find_breakpoint_symbol(zend_function* TSRMLS_DC);
+int phpdbg_find_breakpoint_opline(void * TSRMLS_DC);
 
 #endif /* PHPDBG_BP_H */
index 283b66bebd4407ba1a16ea19ce832fe7f8f96d44..9ab039e476b582790a5305bab384a3e48550b906 100644 (file)
@@ -80,7 +80,7 @@ static PHPDBG_COMMAND(compile) /* {{{ */
 {
        if (PHPDBG_G(exec)) {
                if (PHPDBG_G(ops)) {
-                       printf("Destroying compiled opcodes\n");
+                       printf("Destroying previously compiled opcodes\n");
                        destroy_op_array(PHPDBG_G(ops) TSRMLS_CC);
                        efree(PHPDBG_G(ops));
                        PHPDBG_G(ops)=NULL;
@@ -96,6 +96,8 @@ static PHPDBG_COMMAND(compile) /* {{{ */
 static PHPDBG_COMMAND(step) /* {{{ */
 {
        PHPDBG_G(stepping) = atoi(expr);
+       printf(
+           "Stepping %s\n", PHPDBG_G(stepping) ? "on" : "off");
        return SUCCESS;
 } /* }}} */
 
@@ -186,7 +188,10 @@ static PHPDBG_COMMAND(print) /* {{{ */
                printf("%s\n", expr);
                return SUCCESS;
        }
-    
+#ifdef HAVE_READLINE_H
+    printf("HAVE READLINE\n");
+#endif    
+
     printf("--------------------------------------\n");
        printf("Execution Context Information:\n");
        printf("Exec\t\t%s\n", PHPDBG_G(exec) ? PHPDBG_G(exec) : "none");
@@ -282,14 +287,18 @@ static PHPDBG_COMMAND(break) /* {{{ */
                    return FAILURE;
                }
        } else {
-               char name[200];
-               size_t name_len = strlen(expr);
+               if (expr_len > 2 && expr[0] == '0' && expr[1] == 'x') {
+                   phpdbg_set_breakpoint_opline(expr TSRMLS_CC);
+               } else {
+                   char name[200];
+                   size_t name_len = strlen(expr);
 
-               name_len = MIN(name_len, 200);
-               memcpy(name, expr, name_len);
-               name[name_len] = 0;
+                   name_len = MIN(name_len, 200);
+                   memcpy(name, expr, name_len);
+                   name[name_len] = 0;
 
-               phpdbg_set_breakpoint_symbol(name TSRMLS_CC);
+                   phpdbg_set_breakpoint_symbol(name TSRMLS_CC);
+               }
        }
 
        return SUCCESS;
@@ -403,7 +412,7 @@ int phpdbg_do_cmd(const phpdbg_command_t *command, char *cmd_line, size_t cmd_le
        while (command && command->name) {
                if (command->name_len == expr_len
                            && memcmp(cmd, command->name, expr_len) == 0) {
-                       PHPDBG_G(last) = command;
+                       PHPDBG_G(last) = (phpdbg_command_t*) command;
                        PHPDBG_G(last_params) = params;
                        PHPDBG_G(last_params_len) = cmd_len - expr_len;
                        return command->handler(params, cmd_len - expr_len TSRMLS_CC);
@@ -503,6 +512,13 @@ zend_vm_enter:
                                }
                        }
         }
+        
+        if (PHPDBG_G(has_opline_bp)
+                       && phpdbg_find_breakpoint_opline(execute_data->opline TSRMLS_CC) == SUCCESS) {
+                       while (phpdbg_interactive(TSRMLS_C) != PHPDBG_NEXT) {
+                               continue;
+                       }
+               }
 
                PHPDBG_G(vmret) = execute_data->opline->handler(execute_data TSRMLS_CC);