]> granicus.if.org Git - php/commitdiff
don't be lazy, scan for ZEND_RETURN when setting seek opline
authorkrakjoe <joe.watkins@live.co.uk>
Mon, 18 Nov 2013 02:14:17 +0000 (02:14 +0000)
committerkrakjoe <joe.watkins@live.co.uk>
Mon, 18 Nov 2013 02:14:17 +0000 (02:14 +0000)
phpdbg.h
phpdbg_prompt.c

index bf528edc8aed9971baff500edd5ff528e23a132d..0416b93619a0178071b5b2930065edf8f0ac887e 100644 (file)
--- a/phpdbg.h
+++ b/phpdbg.h
@@ -94,6 +94,7 @@
 #define PHPDBG_IN_UNTIL                        (1<<13)
 #define PHPDBG_IN_FINISH               (1<<14)
 #define PHPDBG_IN_LEAVE                        (1<<15)
+#define PHPDBG_SEEK_MASK               (PHPDBG_IN_UNTIL|PHPDBG_IN_FINISH|PHPDBG_IN_LEAVE)
 
 #ifndef _WIN32
 #   define PHPDBG_DEFAULT_FLAGS    (PHPDBG_IS_QUIET|PHPDBG_IS_COLOURED)
index d8edcde5bff2bc1a7422d063b9649e117c2b59e1..7f976bf8ed899a9a77f8b9ab5ba2f5ae1d3f4ea4 100644 (file)
@@ -326,7 +326,18 @@ static PHPDBG_COMMAND(finish) /* {{{ */
        }
        
        PHPDBG_G(flags) |= PHPDBG_IN_FINISH;
-       PHPDBG_G(seek) = (zend_ulong) &(EG(active_op_array)->opcodes[EG(active_op_array)->last-2]);
+       {
+               zend_uint next = 0,
+                                 self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes);
+               zend_op  *opline = &EG(active_op_array)->opcodes[self];
+               
+               for (next = self; next < EG(active_op_array)->last; next++) {
+                       if (EG(active_op_array)->opcodes[next].opcode == ZEND_RETURN) {
+                               PHPDBG_G(seek) = (zend_ulong) &EG(active_op_array)->opcodes[next];
+                               break;
+                       }
+               }
+       }
        
        return PHPDBG_FINISH;
 } /* }}} */
@@ -339,7 +350,18 @@ static PHPDBG_COMMAND(leave) /* {{{ */
        }
        
        PHPDBG_G(flags) |= PHPDBG_IN_LEAVE;
-       PHPDBG_G(seek) = (zend_ulong) &(EG(active_op_array)->opcodes[EG(active_op_array)->last-2]);
+       {
+               zend_uint next = 0,
+                                 self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes);
+               zend_op  *opline = &EG(active_op_array)->opcodes[self];
+               
+               for (next = self; next < EG(active_op_array)->last; next++) {
+                       if (EG(active_op_array)->opcodes[next].opcode == ZEND_RETURN) {
+                               PHPDBG_G(seek) = (zend_ulong) &EG(active_op_array)->opcodes[next];
+                               break;
+                       }
+               }
+       }
        
        return PHPDBG_LEAVE;
 } /* }}} */
@@ -375,7 +397,8 @@ static PHPDBG_COMMAND(run) /* {{{ */
                zend_activate_auto_globals(TSRMLS_C);
         } zend_end_try();
 
-               PHPDBG_G(flags) &= ~(PHPDBG_IN_UNTIL|PHPDBG_IN_FINISH|PHPDBG_IN_LEAVE);         
+               /* clean flags */
+               PHPDBG_G(flags) &= ~PHPDBG_SEEK_MASK;           
                
                zend_try {
                        zend_execute(
@@ -1009,39 +1032,43 @@ zend_vm_enter:
                        goto next;
                }
 
-               /* run to next line */
-               if (PHPDBG_G(flags) & PHPDBG_IN_UNTIL) {
-                       if (((zend_ulong)execute_data->opline) == PHPDBG_G(seek)) {
-                               PHPDBG_G(flags) &= ~PHPDBG_IN_UNTIL;
-                       } else {
-                               /* skip possible breakpoints */
-                               goto next;
-                       }
-               }
+               /* perform seek operation */
+               if (PHPDBG_G(flags) & PHPDBG_SEEK_MASK) {
 
-               /* run to finish */
-               if (PHPDBG_G(flags) & PHPDBG_IN_FINISH) {
-                       if (((zend_ulong)execute_data->opline) == PHPDBG_G(seek)) {
-                               PHPDBG_G(flags) &= ~PHPDBG_IN_FINISH;
+                       /* run to next line */
+                       if (PHPDBG_G(flags) & PHPDBG_IN_UNTIL) {
+                               if (((zend_ulong)execute_data->opline) == PHPDBG_G(seek)) {
+                                       PHPDBG_G(flags) &= ~PHPDBG_IN_UNTIL;
+                               } else {
+                                       /* skip possible breakpoints */
+                                       goto next;
+                               }
                        }
-                       /* skip possible breakpoints */
-                       goto next;
-               }
 
-               /* break for leave */
-               if (PHPDBG_G(flags) & PHPDBG_IN_LEAVE) {
-                       if (((zend_ulong)execute_data->opline) == PHPDBG_G(seek)) {
-                               PHPDBG_G(flags) &= ~PHPDBG_IN_LEAVE;
-                               phpdbg_notice(
-                                       "Breaking for leave at %s:%u",
-                                       zend_get_executed_filename(TSRMLS_C),
-                                       zend_get_executed_lineno(TSRMLS_C)
-                               );
-                               DO_INTERACTIVE();
-                       } else {
+                       /* run to finish */
+                       if (PHPDBG_G(flags) & PHPDBG_IN_FINISH) {
+                               if (((zend_ulong)execute_data->opline) == PHPDBG_G(seek)) {
+                                       PHPDBG_G(flags) &= ~PHPDBG_IN_FINISH;
+                               }
                                /* skip possible breakpoints */
                                goto next;
                        }
+
+                       /* break for leave */
+                       if (PHPDBG_G(flags) & PHPDBG_IN_LEAVE) {
+                               if (((zend_ulong)execute_data->opline) == PHPDBG_G(seek)) {
+                                       PHPDBG_G(flags) &= ~PHPDBG_IN_LEAVE;
+                                       phpdbg_notice(
+                                               "Breaking for leave at %s:%u",
+                                               zend_get_executed_filename(TSRMLS_C),
+                                               zend_get_executed_lineno(TSRMLS_C)
+                                       );
+                                       DO_INTERACTIVE();
+                               } else {
+                                       /* skip possible breakpoints */
+                                       goto next;
+                               }
+                       }
                }
 
                /* not while in conditionals */