}
} /* }}} */
-void phpdbg_set_breakpoint_method(const char* class_name,
- size_t class_len,
- const char* func_name,
- size_t func_len TSRMLS_DC) /* {{{ */
+void phpdbg_set_breakpoint_method(const char* class_name, const char* func_name TSRMLS_DC) /* {{{ */
{
HashTable class_breaks, *class_table;
+ size_t class_len = strlen(class_name);
+ size_t func_len = strlen(func_name);
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], class_name, class_len, (void**)&class_table) != SUCCESS) {
- zend_hash_init(
- &class_breaks, 8, NULL, phpdbg_class_breaks_dtor, 0);
+ if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], class_name,
+ class_len, (void**)&class_table) != SUCCESS) {
+ zend_hash_init(&class_breaks, 8, NULL, phpdbg_class_breaks_dtor, 0);
zend_hash_update(
&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD],
class_name, class_len,
new_break.func_len = func_len;
new_break.id = PHPDBG_G(bp_count)++;
- zend_hash_update(class_table, func_name, func_len, &new_break, sizeof(phpdbg_breakmethod_t), NULL);
+ zend_hash_update(class_table, func_name, func_len,
+ &new_break, sizeof(phpdbg_breakmethod_t), NULL);
+
printf(
"%sBreakpoint #%d added at %s::%s%s\n",
PHPDBG_BOLD_LINE(TSRMLS_C),
void phpdbg_set_breakpoint_file(const char*, long TSRMLS_DC);
void phpdbg_set_breakpoint_symbol(const char* TSRMLS_DC);
-void phpdbg_set_breakpoint_method(const char*, size_t, const char*, size_t TSRMLS_DC);
+void phpdbg_set_breakpoint_method(const char*, const char* TSRMLS_DC);
void phpdbg_set_breakpoint_opline(zend_ulong TSRMLS_DC);
void phpdbg_set_breakpoint_opline_ex(phpdbg_opline_ptr_t TSRMLS_DC);
static PHPDBG_COMMAND(break) /* {{{ */
{
- char *line_pos = NULL;
- char *func_pos = NULL;
+ char *line_pos;
if (expr_len <= 0L) {
printf(
return FAILURE;
}
- line_pos = strchr(expr, ':');
+ line_pos = strchr(expr, ':');
if (line_pos) {
- if (!(func_pos=strchr(line_pos+1, ':'))) {
+ char *class;
+ char *func;
+
+ /* break class::method */
+ if (phpdbg_is_class_method(expr, expr_len, &class, &func)) {
+ phpdbg_set_breakpoint_method(class, func TSRMLS_CC);
+ } else {
+ /* break file:line */
char path[MAXPATHLEN], resolved_name[MAXPATHLEN];
long line_num = strtol(line_pos+1, NULL, 0);
path[line_pos - expr] = 0;
if (expand_filepath(path, resolved_name TSRMLS_CC) == NULL) {
- printf("%sFailed to expand path %s%s\n", PHPDBG_RED_LINE(TSRMLS_C), path, PHPDBG_END_LINE(TSRMLS_C));
+ printf("%sFailed to expand path %s%s\n",
+ PHPDBG_RED_LINE(TSRMLS_C), path, PHPDBG_END_LINE(TSRMLS_C));
return FAILURE;
}
phpdbg_set_breakpoint_file(resolved_name, line_num TSRMLS_CC);
} else {
- printf("%sNo line specified in expression %s%s\n", PHPDBG_RED_LINE(TSRMLS_C), expr, PHPDBG_END_LINE(TSRMLS_C));
- return FAILURE;
- }
- } else {
- char *class;
- char *func;
-
- size_t func_len = strlen(func_pos+1),
- class_len = (line_pos - expr);
-
- if (func_len) {
- class = emalloc(class_len+1);
- func = emalloc(func_len+1);
-
- memcpy(class, expr, class_len);
- class[class_len]='\0';
- memcpy(func, func_pos+1, func_len);
- func[func_len]='\0';
-
- phpdbg_set_breakpoint_method(class, class_len, func, func_len TSRMLS_CC);
- } else {
- printf("%sNo function found in method expression %s%s\n", PHPDBG_RED_LINE(TSRMLS_C), expr, PHPDBG_END_LINE(TSRMLS_C));
+ printf("%sNo line specified in expression %s%s\n",
+ PHPDBG_RED_LINE(TSRMLS_C), expr, PHPDBG_END_LINE(TSRMLS_C));
return FAILURE;
}
- }
+ }
} else {
+ /* break 0xc0ffee */
if (phpdbg_is_addr(expr)) {
zend_ulong opline = strtoul(expr, 0, 16);
phpdbg_set_breakpoint_opline(opline TSRMLS_CC);
} else if (phpdbg_is_numeric(expr)) {
+ /* break 1337 */
const char *filename = zend_get_executed_filename(TSRMLS_C);
long line_num = strtol(expr, NULL, 0);
phpdbg_set_breakpoint_file(filename, line_num TSRMLS_CC);
} else {
+ /* break symbol */
char name[200];
size_t name_len = strlen(expr);
+----------------------------------------------------------------------+
*/
+#include <stdio.h>
#include <ctype.h>
+#include "zend_alloc.h"
#include "phpdbg_utils.h"
int phpdbg_is_numeric(const char *str) /* {{{ */
{
return str[0] && str[1] && memcmp(str, "0x", 2) == 0;
} /* }}} */
+
+int phpdbg_is_class_method(const char *str, size_t len, char **class, char **method) /* {{{ */
+{
+ const char *sep = strstr(str, "::");
+ size_t class_len, method_len;
+
+ if (!sep) {
+ return 0;
+ }
+
+ class_len = sep - str;
+ method_len = len - ((sep+2) - str);
+
+ *class = estrndup(str, class_len);
+ class[class_len] = 0;
+
+ *method = estrndup(sep+2, method_len+1);
+
+ return 1;
+} /* }}} */
int phpdbg_is_numeric(const char*);
int phpdbg_is_empty(const char*);
int phpdbg_is_addr(const char*);
+int phpdbg_is_class_method(const char*, size_t, char**, char**);
#endif /* PHPDBG_UTILS_H */