]> granicus.if.org Git - php/commitdiff
Nearly finished opline num support patch
authorBob Weinand <bobwei9@hotmail.com>
Tue, 3 Dec 2013 11:31:25 +0000 (12:31 +0100)
committerBob Weinand <bobwei9@hotmail.com>
Tue, 3 Dec 2013 11:31:25 +0000 (12:31 +0100)
phpdbg_bp.c
phpdbg_break.c
phpdbg_cmd.c
phpdbg_cmd.h
phpdbg_help.c
phpdbg_prompt.c

index 24fdb936769e5515ee023360dfe44dc22516d066..a7be7eb5d4a08dbcbfe11148a56602bcc4219070 100644 (file)
@@ -128,8 +128,95 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
                                        noted = 1;
                                }
 
-                               fprintf(
-                                       handle, "break %s::%s\n", brake->class_name, brake->func_name);
+                               fprintf(handle, "break %s::%s\n", brake->class_name, brake->func_name);
+                       }
+               }
+       }
+
+       if (PHPDBG_G(flags) & PHPDBG_HAS_METHOD_OPLINE_BP) {
+               HashTable *class, *method;
+               phpdbg_breakopline_t *brake;
+               HashPosition mposition[2];
+               zend_bool noted = 0;
+
+               table = &PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE];
+
+               for (zend_hash_internal_pointer_reset_ex(table, &position);
+                    zend_hash_get_current_data_ex(table, (void**) &class, &position) == SUCCESS;
+                    zend_hash_move_forward_ex(table, &position)) {
+                       for (zend_hash_internal_pointer_reset_ex(class, &mposition[0]);
+                            zend_hash_get_current_data_ex(class, (void**) &method, &mposition[0]) == SUCCESS;
+                            zend_hash_move_forward_ex(class, &mposition[0])) {
+                               noted = 0;
+
+                               for (zend_hash_internal_pointer_reset_ex(method, &mposition[1]);
+                                    zend_hash_get_current_data_ex(method, (void**) &brake, &mposition[1]) == SUCCESS;
+                                    zend_hash_move_forward_ex(method, &mposition[1])) {
+                                       if (!noted) {
+                                               phpdbg_notice(
+                                                       "Exporting method opline breakpoints in %s::%s (%d)",
+                                                       brake->class_name, brake->func_name, zend_hash_num_elements(method));
+                                               noted = 1;
+                                       }
+
+                                       fprintf(handle, "break %s::%s#%d\n", brake->class_name, brake->func_name, brake->opline);
+                               }
+                       }
+               }
+       }
+
+       if (PHPDBG_G(flags) & PHPDBG_HAS_FUNCTION_OPLINE_BP) {
+               HashTable *function;
+               phpdbg_breakopline_t *brake;
+               HashPosition fposition;
+               zend_bool noted = 0;
+
+               table = &PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE];
+
+               for (zend_hash_internal_pointer_reset_ex(table, &position);
+                       zend_hash_get_current_data_ex(table, (void**) &function, &position) == SUCCESS;
+                       zend_hash_move_forward_ex(table, &position)) {
+                       noted = 0;
+
+                       for (zend_hash_internal_pointer_reset_ex(function, &fposition);
+                               zend_hash_get_current_data_ex(function, (void**) &brake, &fposition) == SUCCESS;
+                               zend_hash_move_forward_ex(function, &fposition)) {
+                               if (!noted) {
+                                       phpdbg_notice(
+                                               "Exporting function opline breakpoints in %s (%d)",
+                                               brake->func_name, zend_hash_num_elements(function));
+                                       noted = 1;
+                               }
+
+                               fprintf(handle, "break %s#%d\n", brake->func_name, brake->opline);
+                       }
+               }
+       }
+
+       if (PHPDBG_G(flags) & PHPDBG_HAS_FILE_OPLINE_BP) {
+               HashTable *file;
+               phpdbg_breakopline_t *brake;
+               HashPosition fposition;
+               zend_bool noted = 0;
+
+               table = &PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE];
+
+               for (zend_hash_internal_pointer_reset_ex(table, &position);
+                       zend_hash_get_current_data_ex(table, (void**) &file, &position) == SUCCESS;
+                       zend_hash_move_forward_ex(table, &position)) {
+                       noted = 0;
+
+                       for (zend_hash_internal_pointer_reset_ex(file, &fposition);
+                               zend_hash_get_current_data_ex(file, (void**) &brake, &fposition) == SUCCESS;
+                               zend_hash_move_forward_ex(file, &fposition)) {
+                               if (!noted) {
+                                       phpdbg_notice(
+                                               "Exporting file opline breakpoints in %s (%d)",
+                                               brake->class_name, zend_hash_num_elements(file));
+                                       noted = 1;
+                               }
+
+                               fprintf(handle, "break a %s#%d\n", brake->func_name, brake->opline);
                        }
                }
        }
@@ -146,8 +233,7 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
                        zend_hash_get_current_data_ex(table, (void**) &brake, &position) == SUCCESS;
                        zend_hash_move_forward_ex(table, &position)) {
 
-                       fprintf(
-                               handle, "break op %s\n", brake->name);
+                       fprintf(handle, "break op %s\n", brake->name);
                }
        }
 
@@ -163,8 +249,7 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
                        zend_hash_get_current_data_ex(table, (void**) &brake, &position) == SUCCESS;
                        zend_hash_move_forward_ex(table, &position)) {
 
-                       fprintf(
-                               handle, "break on %s\n", Z_STRVAL(brake->code));
+                       fprintf(handle, "break on %s\n", Z_STRVAL(brake->code));
                }
        }
 } /* }}} */
@@ -333,7 +418,11 @@ PHPDBG_API void phpdbg_resolve_op_array_breaks(zend_op_array *op_array TSRMLS_DC
                return;
        }
 
-       if (zend_hash_find(func_table, op_array->function_name?op_array->function_name:"", op_array->function_name?strlen(op_array->function_name):0, (void **)&oplines_table) == FAILURE) {
+       if (op_array->function_name == NULL) {
+               if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], op_array->filename, strlen(op_array->filename), (void **)&oplines_table) == FAILURE) {
+                       return;
+               }
+       } else if (zend_hash_find(func_table, op_array->function_name?op_array->function_name:"", op_array->function_name?strlen(op_array->function_name):0, (void **)&oplines_table) == FAILURE) {
                return;
        }
 
@@ -346,7 +435,7 @@ PHPDBG_API void phpdbg_resolve_op_array_breaks(zend_op_array *op_array TSRMLS_DC
                        zend_hash_internal_pointer_end(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
                        zend_hash_get_current_data(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (void **)&opline_break);
 
-                       phpdbg_notice("Breakpoint #%d resolved at %s%s%s:%d (opline %#lx)", brake->id, brake->class_name?brake->class_name:"", brake->class_name?"::":"", brake->func_name, brake->opline, opline_break->opline);
+                       phpdbg_notice("Breakpoint #%d resolved at %s%s%s#%d (opline %#lx)", brake->id, brake->class_name?brake->class_name:"", brake->class_name&&brake->func_name?"::":"", brake->func_name?brake->func_name:"", brake->opline, opline_break->opline);
                }
        }
 }
@@ -406,11 +495,11 @@ PHPDBG_API void phpdbg_set_breakpoint_method_opline(const char *class, const cha
 
        switch (phpdbg_resolve_opline_break(&new_break TSRMLS_CC)) {
                case FAILURE:
-                       phpdbg_notice("Pending breakpoint #%d at %s::%s:%d", new_break.id, new_break.class_name, new_break.func_name, opline);
+                       phpdbg_notice("Pending breakpoint #%d at %s::%s#%d", new_break.id, new_break.class_name, new_break.func_name, opline);
                        break;
 
                case SUCCESS:
-                       phpdbg_notice("Breakpoint #%d added at %s::%s:%d", new_break.id, new_break.class_name, new_break.func_name, opline);
+                       phpdbg_notice("Breakpoint #%d added at %s::%s#%d", new_break.id, new_break.class_name, new_break.func_name, opline);
                        break;
 
                case 2:
@@ -436,7 +525,7 @@ PHPDBG_API void phpdbg_set_breakpoint_method_opline(const char *class, const cha
        }
 
        if (zend_hash_index_exists(method_table, opline)) {
-               phpdbg_notice("Breakpoint already exists for %s::%s:%d", new_break.class_name, new_break.func_name, opline);
+               phpdbg_notice("Breakpoint already exists for %s::%s#%d", new_break.class_name, new_break.func_name, opline);
                efree(new_break.func_name);
                efree(new_break.class_name);
                PHPDBG_G(bp_count)--;
@@ -462,11 +551,11 @@ PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, int
 
        switch (phpdbg_resolve_opline_break(&new_break TSRMLS_CC)) {
                case FAILURE:
-                       phpdbg_notice("Pending breakpoint #%d at %s:%d", new_break.id, new_break.func_name, new_break.opline);
+                       phpdbg_notice("Pending breakpoint #%d at %s#%d", new_break.id, new_break.func_name, new_break.opline);
                        break;
 
                case SUCCESS:
-                       phpdbg_notice("Breakpoint #%d added at %s:%d", new_break.id, new_break.func_name, new_break.opline);
+                       phpdbg_notice("Breakpoint #%d added at %s#%d", new_break.id, new_break.func_name, new_break.opline);
                        break;
 
                case 2:
@@ -483,7 +572,7 @@ PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, int
        }
 
        if (zend_hash_index_exists(func_table, opline)) {
-               phpdbg_notice("Breakpoint already exists for %s:%d", new_break.func_name, opline);
+               phpdbg_notice("Breakpoint already exists for %s#%d", new_break.func_name, opline);
                efree(new_break.func_name);
                PHPDBG_G(bp_count)--;
                return;
index cb2a01b5bd9c2c4cfc9c637de5dc873cd93938c7..e2dc95d971f3a4ee5177503211b8fa31facaa300 100644 (file)
@@ -63,9 +63,12 @@ PHPDBG_BREAK(address) /* {{{ */
                        phpdbg_set_breakpoint_method_opline(param->method.class, param->method.name, param->num TSRMLS_CC);
                        break;
 
-               case NUMERIC_PARAM:
-               case FILE_PARAM:
+               case NUMERIC_FUNCTION_PARAM:
                        phpdbg_set_breakpoint_function_opline(param->str, param->num TSRMLS_CC);
+                       break;                  
+
+               case FILE_PARAM:
+                       phpdbg_set_breakpoint_file_opline(param->file.name, param->file.line TSRMLS_CC);
                        break;
 
                phpdbg_default_switch_case();
index 4f3fe71eed1684276dff51c1714afc7fd4599ef6..30ce0dc0d6fec293ae500864e3f009c88b342fbe 100644 (file)
@@ -35,10 +35,12 @@ PHPDBG_API const char *phpdbg_get_param_type(const phpdbg_param_t *param TSRMLS_
                        return "numeric";
                case METHOD_PARAM:
                        return "method";
+               case NUMERIC_FUNCTION_PARAM:
+                       return "function opline";
                case NUMERIC_METHOD_PARAM:
                        return "method opline";
                case FILE_PARAM:
-                       return "file or function opline";
+                       return "file or file opline";
                case STR_PARAM:
                        return "string";
                default: /* this is bad */
@@ -74,27 +76,39 @@ PHPDBG_API phpdbg_param_type phpdbg_parse_param(const char *str, size_t len, php
                char *line_pos = strrchr(str, ':');
 
                if (line_pos && phpdbg_is_numeric(line_pos+1)) {
-                       param->len = line_pos - str;
-                       param->str = estrndup(str, param->len);
-
                        if (strchr(str, ':') == line_pos) {
+                               char path[MAXPATHLEN];
+
+                               memcpy(path, str, line_pos - str);
+                               path[line_pos - str] = 0;
                                *line_pos = 0;
-                               param->file.name = phpdbg_resolve_path(param->str TSRMLS_CC);
-                               param->num = param->file.line = strtol(line_pos+1, NULL, 0);
+                               param->file.name = phpdbg_resolve_path(path TSRMLS_CC);
+                               param->file.line = strtol(line_pos+1, NULL, 0);
                                param->type = FILE_PARAM;
-                       } else {
+
+                               goto parsed;
+                       }
+               }
+
+               line_pos = strrchr(str, '#');
+
+               if (line_pos && phpdbg_is_numeric(line_pos+1)) {
+                       if (strchr(str, '#') == line_pos) {
                                *line_pos = 0;
-                                if (phpdbg_is_class_method(str, line_pos - str, &class_name, &func_name)) {
-                                       param->num = strtol(str, NULL, 0);
+                               param->num = strtol(line_pos + 1, NULL, 0);
+
+                               if (phpdbg_is_class_method(str, line_pos - str, &class_name, &func_name)) {
                                        param->method.class = class_name;
                                        param->method.name = func_name;
                                        param->type = NUMERIC_METHOD_PARAM;
                                } else {
-                                       phpdbg_error("Impossible to parse %s", str);
+                                       param->len = line_pos - str;
+                                       param->str = estrndup(str, param->len);
+                                       param->type = NUMERIC_FUNCTION_PARAM;
                                }
-                       }
 
-                       goto parsed;
+                               goto parsed;
+                       }
                }
        }
 
index 69d36828c3548070321a3a578c1bd90db66a07ef..aef9fe2653189716740d41dfa422db8e59a763a2 100644 (file)
@@ -38,6 +38,7 @@ typedef enum {
        METHOD_PARAM,
        STR_PARAM,
        NUMERIC_PARAM,
+       NUMERIC_FUNCTION_PARAM,
        NUMERIC_METHOD_PARAM
 } phpdbg_param_type;
 
index eaf5f649d898bf4d45f519c59101ecf0da47ee3e..12bff5ce0b8c44efe8f7172ba4339555af51aa6c 100644 (file)
@@ -238,6 +238,18 @@ PHPDBG_HELP(break) /* {{{ */
        phpdbg_writeln("\t%sb [a] 0x7ff68f570e08", phpdbg_get_prompt(TSRMLS_C));
        phpdbg_writeln("\tWill break at the opline with the address provided");
        phpdbg_writeln(EMPTY);
+       phpdbg_writeln("\t%sbreak [address] my_function#1", phpdbg_get_prompt(TSRMLS_C));
+       phpdbg_writeln("\t%sb [a] my_function#1", phpdbg_get_prompt(TSRMLS_C));
+       phpdbg_writeln("\tWill break at the opline number 1 of the function my_function");
+       phpdbg_writeln(EMPTY);
+       phpdbg_writeln("\t%sbreak [address] \\my\\class::method#2", phpdbg_get_prompt(TSRMLS_C));
+       phpdbg_writeln("\t%sb [a] \\my\\class::method#2", phpdbg_get_prompt(TSRMLS_C));
+       phpdbg_writeln("\tWill break at the opline number 2 of the method \\my\\class::method");
+       phpdbg_writeln(EMPTY);
+       phpdbg_writeln("\t%sbreak address test.php:3", phpdbg_get_prompt(TSRMLS_C));
+       phpdbg_writeln("\t%sb a test.php:3", phpdbg_get_prompt(TSRMLS_C));
+       phpdbg_writeln("\tWill break at the opline number 3 of test.php");
+       phpdbg_writeln(EMPTY);
        phpdbg_writeln("\t%sbreak [lineno] 200", phpdbg_get_prompt(TSRMLS_C));
        phpdbg_writeln("\t%sb [l] 200", phpdbg_get_prompt(TSRMLS_C));
        phpdbg_writeln("\tWill break at line 200 of the currently executing file");
index 009d19c8d038a79a3f52c6c47aa594b1f216ea06..390aaa556bba80abb3ea0cde7fe4e418fac3ee1e 100644 (file)
@@ -817,6 +817,12 @@ PHPDBG_COMMAND(break) /* {{{ */
                case METHOD_PARAM:
                        phpdbg_set_breakpoint_method(param->method.class, param->method.name TSRMLS_CC);
                        break;
+               case NUMERIC_METHOD_PARAM:
+                       phpdbg_set_breakpoint_method_opline(param->method.class, param->method.name, param->num TSRMLS_CC);
+                       break;
+               case NUMERIC_FUNCTION_PARAM:
+                       phpdbg_set_breakpoint_function_opline(param->str, param->num TSRMLS_CC);
+                       break;
                case FILE_PARAM:
                        phpdbg_set_breakpoint_file(param->file.name, param->file.line TSRMLS_CC);
                        break;