]> granicus.if.org Git - php/commitdiff
add list class and method commands
authorkrakjoe <joe.watkins@live.co.uk>
Sat, 16 Nov 2013 18:53:12 +0000 (18:53 +0000)
committerkrakjoe <joe.watkins@live.co.uk>
Sat, 16 Nov 2013 18:53:12 +0000 (18:53 +0000)
update help text to be more specific

phpdbg_help.c
phpdbg_list.c
phpdbg_list.h
phpdbg_prompt.c

index 651ef8623aecb57ce9e31fb0dc65d1b48939ea99..295ada481008bba992b5591ad5caba09eee6e9fc 100644 (file)
@@ -114,21 +114,22 @@ PHPDBG_HELP(break) /* {{{ */
        phpdbg_writeln("Setting a breakpoint stops execution at a specific stage");
        phpdbg_writeln(EMPTY);
        phpdbg_writeln("Examples:");
-       phpdbg_writeln("\t%sbreak test.php:1", PROMPT);
+       phpdbg_writeln("\t%sbreak [file] test.php:1", PROMPT);
        phpdbg_writeln("Will break execution on line 1 of test.php");
-       phpdbg_writeln("\t%sbreak my_function", PROMPT);
+       phpdbg_writeln("\t%sbreak [func] my_function", PROMPT);
        phpdbg_writeln("Will break execution on entry to my_function");
-       phpdbg_writeln("\t%sbreak \\my\\class::method", PROMPT);
+       phpdbg_writeln("\t%sbreak [method] \\my\\class::method", PROMPT);
        phpdbg_writeln("Will break execution on entry to \\my\\class::method");
-       phpdbg_writeln("\t%sbreak 0x7ff68f570e08", PROMPT);
+       phpdbg_writeln("\t%sbreak [address] 0x7ff68f570e08", PROMPT);
        phpdbg_writeln("Will break at the opline with the address provided (addresses are shown during execution)");
-       phpdbg_writeln("\t%sbreak 200", PROMPT);
+       phpdbg_writeln("\t%sbreak [lineno] 200", PROMPT);
        phpdbg_writeln("Will break at line 200 of the currently executing file");
        phpdbg_writeln("\t%sbreak on ($expression == true)", PROMPT);
        phpdbg_writeln("Will break when the condition evaluates to true");
        phpdbg_writeln(EMPTY);
        phpdbg_writeln("It is important to note, an address is only valid for the current compiled representation of the script");
        phpdbg_writeln("If you have to clean the environment and recompile then your opline break points will be invalid");
+       phpdbg_writeln("The parameters enclosed by [] are usually optional, but help avoid ambigious commands");
        phpdbg_writeln(EMPTY);
        phpdbg_writeln("Conditional breaks are costly, use them sparingly !!");
 
@@ -176,17 +177,22 @@ PHPDBG_HELP(back) /* {{{ */
 
 PHPDBG_HELP(list) /* {{{ */
 {
-       phpdbg_writeln("The list command displays N line from current context file");
+       phpdbg_writeln("The list command displays source code for the given argument");
        phpdbg_writeln(EMPTY);
        phpdbg_writeln("Examples:");
-       phpdbg_writeln("\t%slist 2", PROMPT);
+       phpdbg_writeln("\t%slist [lines] 2", PROMPT);
        phpdbg_writeln("Will print next 2 lines from the current file");
-       phpdbg_writeln("\t%slist func", PROMPT);
-       phpdbg_writeln("Will print the source of the global function \"func\"");
-       phpdbg_writeln("\t%slist .mine", PROMPT);
-       phpdbg_writeln("Will print the source of the class method \"mine\"");
+       phpdbg_writeln("\t%slist [func] my_function", PROMPT);
+       phpdbg_writeln("Will print the source of the global function \"my_function\"");
+       phpdbg_writeln("\t%slist [func] .mine", PROMPT);
+       phpdbg_writeln("Will print the source of the method \"mine\" from the currently active scope");
+       phpdbg_writeln("\t%slist [method] my::method", PROMPT);
+       phpdbg_writeln("Will print the source of \"my::method\"");
+       phpdbg_writeln("\t%slist [class] myClass", PROMPT);
+       phpdbg_writeln("Will print the source of \"myClass\"");
        phpdbg_writeln(EMPTY);
        phpdbg_writeln("Note: before listing functions you must have a populated function table, try compile !!");
+       phpdbg_writeln("The parameters enclosed by [] are usually optional, but help avoid ambigious commands");
        return SUCCESS;
 } /* }}} */
 
index a4c3d1272d3ee2dbce63eac9ce292db185749bab..78ec2fc75a467f6c275f6cf6a7e4fd61f9204074 100644 (file)
 
 ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
 
-static inline void i_phpdbg_list_func(const char *str TSRMLS_DC)
+static inline void i_phpdbg_list_func(const char *str, size_t len TSRMLS_DC)
 {
     HashTable *func_table = EG(function_table);
     zend_function* fbc;
-    const char *func_name = str;
-    size_t func_name_len = strlen(str);
-
+    char *func_name = str;
+    size_t func_name_len = len;
+    
     /* search active scope if begins with period */
     if (func_name[0] == '.') {
        if (EG(scope)) {
@@ -55,13 +55,18 @@ static inline void i_phpdbg_list_func(const char *str TSRMLS_DC)
     } else {
         func_table = EG(function_table);
     }
-
+    
+    /* use lowercase names, case insensitive */
+    func_name = zend_str_tolower_dup(func_name, func_name_len);
+    
     if (zend_hash_find(func_table, func_name, func_name_len+1,
         (void**)&fbc) == SUCCESS) {
         phpdbg_list_function(fbc TSRMLS_CC);
     } else {
         phpdbg_error("Function %s not found", func_name);
     }
+    
+    efree(func_name);
 }
 
 PHPDBG_LIST(lines) /* {{{ */
@@ -87,7 +92,66 @@ PHPDBG_LIST(func) /* {{{ */
 {
     if (param->type == STR_PARAM) {
         i_phpdbg_list_func(
-            param->str TSRMLS_CC);
+            param->str, param->len TSRMLS_CC);
+    } else {
+        phpdbg_error(
+            "Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC));
+    }
+    
+    return SUCCESS;
+} /* }}} */
+
+PHPDBG_LIST(method) /* {{{ */
+{
+    if (param->type == METHOD_PARAM) {
+        zend_class_entry **ce;
+        
+        if (zend_lookup_class(param->method.class, strlen(param->method.class), &ce TSRMLS_CC) == SUCCESS) {
+            zend_function *function;
+            char *lcname = zend_str_tolower_dup(
+                param->method.name, strlen(param->method.name));
+            
+            if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**) &function) == SUCCESS) {
+                phpdbg_list_function(
+                    function TSRMLS_CC);
+            } else {
+                phpdbg_error("Could not find ::%s in %s", param->method.name, param->method.class);
+            }
+            
+            efree(lcname);
+        } else {
+            phpdbg_error("Could not find the class %s", param->method.class);
+        }
+    } else {
+        phpdbg_error(
+            "Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC));
+    }
+    
+    return SUCCESS;
+} /* }}} */
+
+PHPDBG_LIST(class) /* {{{ */
+{
+    if (param->type == STR_PARAM) {
+        zend_class_entry **ce;
+        
+        if (zend_lookup_class(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) {
+            if ((*ce)->type == ZEND_USER_CLASS) {
+                if ((*ce)->info.user.filename) {
+                    phpdbg_list_file(
+                        (*ce)->info.user.filename,
+                        (*ce)->info.user.line_end - (*ce)->info.user.line_start + 1,
+                        (*ce)->info.user.line_start TSRMLS_CC
+                    );
+                } else {
+                    phpdbg_error("The source of the requested class (%s) cannot be found", (*ce)->name);
+                }
+            } else {
+                phpdbg_error("The class requested (%s) is not user defined", (*ce)->name);
+            }
+        } else {
+            phpdbg_error("The requested class (%s) could not be found", param->str);
+        }
     } else {
         phpdbg_error(
             "Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC));
@@ -113,9 +177,13 @@ void phpdbg_list_dispatch(phpdbg_param_t *param TSRMLS_DC) /* {{{ */
                        break;
                        
                case STR_PARAM: {
-                   i_phpdbg_list_func(param->str TSRMLS_CC);
+                   i_phpdbg_list_func(param->str, param->len TSRMLS_CC);
                } break;
                
+               case METHOD_PARAM:
+                   phpdbg_do_list_method(param TSRMLS_CC);
+               break;
+               
                default:
             phpdbg_error(
                 "Unsupported parameter type (%s) for function", phpdbg_get_param_type(param TSRMLS_CC));
@@ -209,6 +277,8 @@ void phpdbg_list_function(const zend_function *fbc TSRMLS_DC) /* {{{ */
        const zend_op_array *ops;
 
        if (fbc->type != ZEND_USER_FUNCTION) {
+           phpdbg_error(
+               "The function requested (%s) is not user defined", fbc->common.function_name);
                return;
        }
 
index 8829d7f6cceb3606d5e307778c773a37e2eb94c2..53113aab3068d0ea940f93fd2bd0e4094619f494 100644 (file)
@@ -35,6 +35,8 @@
        int phpdbg_do_list_##name(phpdbg_param_t *param TSRMLS_DC)
 
 PHPDBG_LIST(lines);
+PHPDBG_LIST(class);
+PHPDBG_LIST(method);
 PHPDBG_LIST(func);
 
 void phpdbg_list_function(const zend_function* TSRMLS_DC);
@@ -42,8 +44,10 @@ void phpdbg_list_file(const char*, long, long TSRMLS_DC);
 void phpdbg_list_dispatch(phpdbg_param_t *param TSRMLS_DC);
 
 static const phpdbg_command_t phpdbg_list_commands[] = {
-    PHPDBG_LIST_EX_D(lines, "lists the specified lines", 'l'),
-    PHPDBG_LIST_EX_D(func,  "lists the specified function", 'f'),
+    PHPDBG_LIST_EX_D(lines,     "lists the specified lines", 'l'),
+    PHPDBG_LIST_EX_D(class,     "lists the specified class", 'c'),
+    PHPDBG_LIST_EX_D(method,    "lists the specified method", 'm'),
+    PHPDBG_LIST_EX_D(func,      "lists the specified function", 'f'),
     {NULL, 0, 0}
 };
 
index b0e2ff8b5ffe072b6d4b93926ce5591790ff5af8..9e6d73f622343917274fd84984a571e240d3cff5 100644 (file)
@@ -413,53 +413,57 @@ static PHPDBG_COMMAND(back) /* {{{ */
 
 static PHPDBG_COMMAND(print) /* {{{ */
 {
-       if (param->type == STR_PARAM) {
-               if (phpdbg_do_cmd(phpdbg_print_commands, param->str, param->len TSRMLS_CC) == FAILURE) {
-                       phpdbg_error("Failed to find print command %s", param->str);
-               }
-               return SUCCESS;
-       }
-
-    phpdbg_writeln(SEPARATE);
-       phpdbg_notice("Execution Context Information");
+    if (param->type == EMPTY_PARAM) {
+        phpdbg_writeln(SEPARATE);
+        phpdbg_notice("Execution Context Information");
 #ifdef HAVE_LIBREADLINE
-    phpdbg_writeln("Readline\tyes");
+        phpdbg_writeln("Readline\tyes");
 #else
-    phpdbg_writeln("Readline\tno");
+        phpdbg_writeln("Readline\tno");
 #endif
 
-       phpdbg_writeln("Exec\t\t%s", PHPDBG_G(exec) ? PHPDBG_G(exec) : "none");
-       phpdbg_writeln("Compiled\t%s", PHPDBG_G(ops) ? "yes" : "no");
-       phpdbg_writeln("Stepping\t%s", (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off");
-    phpdbg_writeln("Quietness\t%s", (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "on" : "off");
-    phpdbg_writeln("Oplog\t\t%s", PHPDBG_G(oplog) ? "on" : "off");
+        phpdbg_writeln("Exec\t\t%s", PHPDBG_G(exec) ? PHPDBG_G(exec) : "none");
+        phpdbg_writeln("Compiled\t%s", PHPDBG_G(ops) ? "yes" : "no");
+        phpdbg_writeln("Stepping\t%s", (PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ? "on" : "off");
+        phpdbg_writeln("Quietness\t%s", (PHPDBG_G(flags) & PHPDBG_IS_QUIET) ? "on" : "off");
+        phpdbg_writeln("Oplog\t\t%s", PHPDBG_G(oplog) ? "on" : "off");
 
-       if (PHPDBG_G(ops)) {
-               phpdbg_writeln("Opcodes\t\t%d", PHPDBG_G(ops)->last);
+        if (PHPDBG_G(ops)) {
+               phpdbg_writeln("Opcodes\t\t%d", PHPDBG_G(ops)->last);
 
-               if (PHPDBG_G(ops)->last_var) {
-                       phpdbg_writeln("Variables\t%d", PHPDBG_G(ops)->last_var-1);
-               } else {
-                       phpdbg_writeln("Variables\tNone");
-               }
-       }
-
-       phpdbg_writeln("Executing\t%s", EG(in_execution) ? "yes" : "no");
-       if (EG(in_execution)) {
-               phpdbg_writeln("VM Return\t%d", PHPDBG_G(vmret));
-       }
-       phpdbg_writeln("Classes\t\t%d", zend_hash_num_elements(EG(class_table)));
-    phpdbg_writeln("Functions\t%d", zend_hash_num_elements(EG(function_table)));
-    phpdbg_writeln("Constants\t%d", zend_hash_num_elements(EG(zend_constants)));
-    phpdbg_writeln("Included\t%d", zend_hash_num_elements(&EG(included_files)));
-
-    phpdbg_print_breakpoints(PHPDBG_BREAK_FILE TSRMLS_CC);
-    phpdbg_print_breakpoints(PHPDBG_BREAK_SYM TSRMLS_CC);
-    phpdbg_print_breakpoints(PHPDBG_BREAK_METHOD TSRMLS_CC);
-    phpdbg_print_breakpoints(PHPDBG_BREAK_OPLINE TSRMLS_CC);
-    phpdbg_print_breakpoints(PHPDBG_BREAK_COND TSRMLS_CC);
+               if (PHPDBG_G(ops)->last_var) {
+                       phpdbg_writeln("Variables\t%d", PHPDBG_G(ops)->last_var-1);
+               } else {
+                       phpdbg_writeln("Variables\tNone");
+               }
+        }
 
-    phpdbg_writeln(SEPARATE);
+        phpdbg_writeln("Executing\t%s", EG(in_execution) ? "yes" : "no");
+        if (EG(in_execution)) {
+               phpdbg_writeln("VM Return\t%d", PHPDBG_G(vmret));
+        }
+        phpdbg_writeln("Classes\t\t%d", zend_hash_num_elements(EG(class_table)));
+        phpdbg_writeln("Functions\t%d", zend_hash_num_elements(EG(function_table)));
+        phpdbg_writeln("Constants\t%d", zend_hash_num_elements(EG(zend_constants)));
+        phpdbg_writeln("Included\t%d", zend_hash_num_elements(&EG(included_files)));
+
+        phpdbg_print_breakpoints(PHPDBG_BREAK_FILE TSRMLS_CC);
+        phpdbg_print_breakpoints(PHPDBG_BREAK_SYM TSRMLS_CC);
+        phpdbg_print_breakpoints(PHPDBG_BREAK_METHOD TSRMLS_CC);
+        phpdbg_print_breakpoints(PHPDBG_BREAK_OPLINE TSRMLS_CC);
+        phpdbg_print_breakpoints(PHPDBG_BREAK_COND TSRMLS_CC);
+        
+        phpdbg_writeln(SEPARATE);
+    } else {
+        if (param->type == STR_PARAM) {
+            if (phpdbg_do_cmd(phpdbg_print_commands, param->str, param->len TSRMLS_CC) == FAILURE) {
+                           phpdbg_error("Failed to find print command %s", param->str);
+                           return FAILURE;
+                   }
+        } else {
+            phpdbg_error("You must use a specific printer");
+        }
+    }
 
        return SUCCESS;
 } /* }}} */
@@ -957,12 +961,22 @@ zend_vm_enter:
 #endif
 
 #define DO_INTERACTIVE() do {\
-    switch (last_step = phpdbg_interactive(TSRMLS_C)) {\
-               case PHPDBG_UNTIL:\
-        case PHPDBG_NEXT:\
-            goto next;\
-    }\
-} while(!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING))
+    phpdbg_list_file(\
+        zend_get_executed_filename(TSRMLS_C), \
+        2, \
+        zend_get_executed_lineno(TSRMLS_C) \
+        TSRMLS_CC\
+    );\
+    \
+    do {\
+        switch (last_step = phpdbg_interactive(TSRMLS_C)) {\
+                   case PHPDBG_UNTIL:\
+            case PHPDBG_NEXT:{\
+                goto next;\
+            }\
+        }\
+    } while(!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING));\
+} while(0)
 
                /* allow conditional breakpoints to access the vm uninterrupted */
                if (PHPDBG_G(flags) & PHPDBG_IN_COND_BP) {