]> granicus.if.org Git - php/commitdiff
- Added catch command
authorFelipe Pena <felipensp@gmail.com>
Sat, 23 Nov 2013 22:03:17 +0000 (20:03 -0200)
committerFelipe Pena <felipensp@gmail.com>
Sat, 23 Nov 2013 22:03:17 +0000 (20:03 -0200)
phpdbg.c
phpdbg.h
phpdbg_help.c
phpdbg_help.h
phpdbg_prompt.c
phpdbg_prompt.h

index c4d53718a1dd9087b6a7e41d5b48045fd6929317..9bfa2834e2cf1a2fc565e9b1c5be9a31237b0ec0 100644 (file)
--- a/phpdbg.c
+++ b/phpdbg.c
@@ -119,6 +119,7 @@ static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */
        zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], 8, NULL, php_phpdbg_destroy_bp_methods, 0);
        zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], 8, NULL, php_phpdbg_destroy_bp_condition, 0);
        zend_hash_init(&PHPDBG_G(seek), 8, NULL, NULL, 0);
+       zend_hash_init(&PHPDBG_G(catch), 8, NULL, NULL, 0);
        zend_hash_init(&PHPDBG_G(registered), 8, NULL, php_phpdbg_destroy_registered, 0);
 
        return SUCCESS;
@@ -132,6 +133,7 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
        zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD]);
        zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]);
        zend_hash_destroy(&PHPDBG_G(seek));
+       zend_hash_destroy(&PHPDBG_G(catch));
        zend_hash_destroy(&PHPDBG_G(registered));
 
        if (PHPDBG_G(exec)) {
index 8a1b814d500a9d65158788763173b5a0553d9a4b..fd7930a7fae786320da5b0f9460e69fd41759269 100644 (file)
--- a/phpdbg.h
+++ b/phpdbg.h
 #define PHPDBG_IS_SIGNALED      (1<<19)
 #define PHPDBG_IS_INTERACTIVE  (1<<20)
 
+#define PHPDBG_HAS_CATCH        (1<<21)
+
 #ifndef _WIN32
 #   define PHPDBG_DEFAULT_FLAGS    (PHPDBG_IS_QUIET|PHPDBG_IS_COLOURED)
 #else
@@ -138,6 +140,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
        phpdbg_param_t lparam;              /* last param */
        FILE *oplog;                        /* opline log */
        HashTable seek;                                         /* seek oplines */
+       HashTable catch;                                        /* seek opcodes */
        zend_ulong flags;                   /* phpdbg flags */
        HashTable registered;                           /* registered */
        phpdbg_frame_t frame;                           /* frame */
index 50b77b3b7d98fe05831af454fbb61737115cfe43..906fbd1b8856014f558b24c6be55c5d48da8ee3a 100644 (file)
@@ -341,6 +341,19 @@ PHPDBG_HELP(back) /* {{{ */
        return SUCCESS;
 } /* }}} */
 
+PHPDBG_HELP(catch) /* {{{ */
+{
+    phpdbg_help_header();
+       phpdbg_writeln("Catch a VM opcode before its execution");
+    phpdbg_writeln(EMPTY);
+    phpdbg_notice("Examples");
+       phpdbg_writeln("\t%scatch ZEND_ADD", PROMPT);
+       phpdbg_writeln("\t%so ZEND_ADD", PROMPT);
+       phpdbg_writeln("\tWill break the execution before the specified opcode is reached");
+       phpdbg_help_footer();
+       return SUCCESS;
+} /* }}} */
+
 PHPDBG_HELP(frame) /* {{{ */
 {
     phpdbg_help_header();
@@ -422,7 +435,7 @@ PHPDBG_HELP(oplog) /* {{{ */
        phpdbg_writeln("Note: upon failure to open a new oplog, the last oplog is held open");
        phpdbg_help_footer();
        return SUCCESS;
-} 
+}
 
 PHPDBG_HELP(register) /* {{{ */
 {
@@ -439,7 +452,7 @@ PHPDBG_HELP(register) /* {{{ */
                HashPosition position;
                char *name = NULL;
                zend_uint name_len = 0;
-               
+
                phpdbg_notice("Registered Functions (%d)", zend_hash_num_elements(&PHPDBG_G(registered)));
                for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(registered), &position);
                        zend_hash_get_current_key_ex(&PHPDBG_G(registered), &name, &name_len, NULL, 1, &position) == HASH_KEY_IS_STRING;
@@ -448,7 +461,7 @@ PHPDBG_HELP(register) /* {{{ */
                        efree(name);
                }
     }
-    
+
     phpdbg_help_footer();
     return SUCCESS;
 } /* }}} */
index 8ec9ee235fd3f9eba8abb54542d780c627c5c53f..942b2265916cb4f4035947d8d5887d4836bcec3b 100644 (file)
@@ -44,6 +44,7 @@ PHPDBG_HELP(clean);
 PHPDBG_HELP(clear);
 PHPDBG_HELP(info);
 PHPDBG_HELP(back);
+PHPDBG_HELP(catch);
 PHPDBG_HELP(frame);
 PHPDBG_HELP(quiet);
 PHPDBG_HELP(list);
@@ -71,6 +72,7 @@ static const phpdbg_command_t phpdbg_help_commands[] = {
        PHPDBG_COMMAND_D_EX(clear,    "reset breakpoints to execute without interruption",                                               'c', help_clear,   NULL, 0),
        PHPDBG_COMMAND_D_EX(info,     "quick access to useful information on the console",                               'i', help_info,    NULL, 0),
        PHPDBG_COMMAND_D_EX(back,     "show debug backtrace information during execution",                               't', help_back,    NULL, 0),
+       PHPDBG_COMMAND_D_EX(catch,    "catch an opcode before its execution",                                            'o', help_catch,   NULL, 0),
        PHPDBG_COMMAND_D_EX(frame,    "switch to a frame in the current stack for inspection",                           'f', help_frame,   NULL, 0),
     PHPDBG_COMMAND_D_EX(quiet,    "be quiet during execution",                                                       'Q', help_quiet,   NULL, 0),
        PHPDBG_COMMAND_D_EX(list,     "list code gives you quick access to code",                                                        'l', help_list,    NULL, 0),
index 8a6ec927de5e7853590acec15b9a46e0412cc832..f4666e8a817b58b26b8f7879136e115acf4db2a0 100644 (file)
@@ -48,6 +48,7 @@ const phpdbg_command_t phpdbg_prompt_commands[] = {
        PHPDBG_COMMAND_D(print,   "print something",                          'p', phpdbg_print_commands, 2),
        PHPDBG_COMMAND_D(break,   "set breakpoint",                           'b', phpdbg_break_commands, 1),
        PHPDBG_COMMAND_D(back,    "show trace",                               't', NULL, 0),
+       PHPDBG_COMMAND_D(catch,   "catch an opcode",                          'o', NULL, 1),
        PHPDBG_COMMAND_D(frame,   "switch to a frame",                        'f', NULL, 1),
        PHPDBG_COMMAND_D(list,    "lists some code",                          'l', phpdbg_list_commands, 2),
        PHPDBG_COMMAND_D(info,    "displays some informations",               'i', phpdbg_info_commands, 1),
@@ -163,6 +164,38 @@ next_line:
        }
 } /* }}} */
 
+int phpdbg_find_catch(zend_uchar opcode TSRMLS_DC) /* {{{ */
+{
+       const char *opname = phpdbg_decode_opcode(opcode);
+
+       if (memcmp(opname, PHPDBG_STRL("UNKNOWN")) == 0) {
+               return FAILURE;
+       }
+
+       return zend_hash_index_exists(&PHPDBG_G(catch),
+               zend_hash_func(opname, strlen(opname))) ? SUCCESS : FAILURE;
+} /* }}} */
+
+PHPDBG_COMMAND(catch) /* {{{ */
+{
+       switch (param->type) {
+               case STR_PARAM: {
+                       int tmp = 0;
+
+                       zend_hash_index_update(&PHPDBG_G(catch),
+                               zend_hash_func(param->str, param->len),
+                               &tmp, sizeof(int), NULL);
+
+                       PHPDBG_G(flags) |= PHPDBG_HAS_CATCH;
+               }
+               break;
+
+               phpdbg_default_switch_case();
+       }
+
+       return SUCCESS;
+} /* }}} */
+
 PHPDBG_COMMAND(exec) /* {{{ */
 {
        switch (param->type) {
@@ -558,7 +591,7 @@ PHPDBG_COMMAND(run) /* {{{ */
                    EG(active_op_array) = orig_op_array;
                    EG(opline_ptr) = orig_opline;
                    EG(return_value_ptr_ptr) = orig_retval_ptr;
-                       
+
                        if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
                                phpdbg_error("Caught exit/error from VM");
                                goto out;
@@ -1385,12 +1418,21 @@ zend_vm_enter:
                        }
                }
 
-               if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP)
+               if (PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP
                        && phpdbg_find_breakpoint_opline(execute_data->opline TSRMLS_CC) == SUCCESS) {
                        DO_INTERACTIVE();
                }
 
-               if ((PHPDBG_G(flags) & PHPDBG_IS_STEPPING)) {
+               if (PHPDBG_G(flags) & PHPDBG_HAS_CATCH
+                       && phpdbg_find_catch(execute_data->opline->opcode TSRMLS_CC) == SUCCESS) {
+                       phpdbg_notice("Catched opcode %s at %s:%u",
+                               phpdbg_decode_opcode(execute_data->opline->opcode),
+                               zend_get_executed_filename(TSRMLS_C),
+                               zend_get_executed_lineno(TSRMLS_C));
+                       DO_INTERACTIVE();
+               }
+
+               if (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) {
                        DO_INTERACTIVE();
                }
 
index 7392b96813248fd3760d9df5983ad1a6ce253228..c0832f045f0f9cd2f88a341b78b6715ef05d6369 100644 (file)
@@ -40,6 +40,7 @@ PHPDBG_COMMAND(frame);
 PHPDBG_COMMAND(print);
 PHPDBG_COMMAND(break);
 PHPDBG_COMMAND(back);
+PHPDBG_COMMAND(catch);
 PHPDBG_COMMAND(list);
 PHPDBG_COMMAND(info);
 PHPDBG_COMMAND(clean);