summaryrefslogtreecommitdiff
path: root/sapi/phpdbg
diff options
context:
space:
mode:
Diffstat (limited to 'sapi/phpdbg')
-rw-r--r--sapi/phpdbg/phpdbg.c205
-rw-r--r--sapi/phpdbg/phpdbg.h29
-rw-r--r--sapi/phpdbg/phpdbg_bp.c632
-rw-r--r--sapi/phpdbg/phpdbg_bp.h2
-rw-r--r--sapi/phpdbg/phpdbg_btree.c15
-rw-r--r--sapi/phpdbg/phpdbg_btree.h5
-rw-r--r--sapi/phpdbg/phpdbg_cmd.c42
-rw-r--r--sapi/phpdbg/phpdbg_frame.c112
-rw-r--r--sapi/phpdbg/phpdbg_info.c254
-rw-r--r--sapi/phpdbg/phpdbg_list.c67
-rw-r--r--sapi/phpdbg/phpdbg_list.h4
-rw-r--r--sapi/phpdbg/phpdbg_opcode.c205
-rw-r--r--sapi/phpdbg/phpdbg_out.c17
-rw-r--r--sapi/phpdbg/phpdbg_parser.c286
-rw-r--r--sapi/phpdbg/phpdbg_parser.h37
-rw-r--r--sapi/phpdbg/phpdbg_print.c70
-rw-r--r--sapi/phpdbg/phpdbg_prompt.c365
-rw-r--r--sapi/phpdbg/phpdbg_rinit_hook.c6
-rw-r--r--sapi/phpdbg/phpdbg_set.c4
-rw-r--r--sapi/phpdbg/phpdbg_sigsafe.c73
-rw-r--r--sapi/phpdbg/phpdbg_sigsafe.h9
-rw-r--r--sapi/phpdbg/phpdbg_utils.c208
-rw-r--r--sapi/phpdbg/phpdbg_utils.h30
-rw-r--r--sapi/phpdbg/phpdbg_wait.c189
-rw-r--r--sapi/phpdbg/phpdbg_watch.c445
-rw-r--r--sapi/phpdbg/phpdbg_watch.h44
-rw-r--r--sapi/phpdbg/phpdbg_webdata_transfer.c137
-rw-r--r--sapi/phpdbg/tests/run-tests.php2
-rw-r--r--sapi/phpdbg/xml.md110
29 files changed, 1506 insertions, 2098 deletions
diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c
index f09dc4ee13..d70e512751 100644
--- a/sapi/phpdbg/phpdbg.c
+++ b/sapi/phpdbg/phpdbg.c
@@ -52,7 +52,7 @@ static PHP_INI_MH(OnUpdateEol)
return FAILURE;
}
- return phpdbg_eol_global_update(new_value TSRMLS_CC);
+ return phpdbg_eol_global_update(new_value->val TSRMLS_CC);
}
PHP_INI_BEGIN()
@@ -83,6 +83,7 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */
pg->last_was_newline = 1;
pg->ops = NULL;
pg->vmret = 0;
+ pg->in_execution = 0;
pg->bp_count = 0;
pg->flags = PHPDBG_DEFAULT_FLAGS;
pg->oplog = NULL;
@@ -135,50 +136,49 @@ static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */
return SUCCESS;
} /* }}} */
-static void php_phpdbg_destroy_bp_file(void *brake) /* {{{ */
+static void php_phpdbg_destroy_bp_file(zval *brake) /* {{{ */
{
- zend_hash_destroy((HashTable*)brake);
+ zend_hash_destroy(Z_ARRVAL_P(brake));
} /* }}} */
-static void php_phpdbg_destroy_bp_symbol(void *brake) /* {{{ */
+static void php_phpdbg_destroy_bp_symbol(zval *brake) /* {{{ */
{
- efree((char*)((phpdbg_breaksymbol_t*)brake)->symbol);
+ efree((char *) ((phpdbg_breaksymbol_t *) Z_PTR_P(brake))->symbol);
} /* }}} */
-static void php_phpdbg_destroy_bp_opcode(void *brake) /* {{{ */
+static void php_phpdbg_destroy_bp_opcode(zval *brake) /* {{{ */
{
- efree((char*)((phpdbg_breakop_t*)brake)->name);
+ efree((char *) ((phpdbg_breakop_t *) Z_PTR_P(brake))->name);
} /* }}} */
-static void php_phpdbg_destroy_bp_methods(void *brake) /* {{{ */
+static void php_phpdbg_destroy_bp_methods(zval *brake) /* {{{ */
{
- zend_hash_destroy((HashTable*)brake);
+ zend_hash_destroy(Z_ARRVAL_P(brake));
} /* }}} */
-static void php_phpdbg_destroy_bp_condition(void *data) /* {{{ */
+static void php_phpdbg_destroy_bp_condition(zval *data) /* {{{ */
{
- phpdbg_breakcond_t *brake = (phpdbg_breakcond_t*) data;
+ phpdbg_breakcond_t *brake = (phpdbg_breakcond_t *) Z_PTR_P(data);
if (brake) {
if (brake->ops) {
TSRMLS_FETCH();
- destroy_op_array(
- brake->ops TSRMLS_CC);
+ destroy_op_array(brake->ops TSRMLS_CC);
efree(brake->ops);
}
- efree((char*)brake->code);
+ efree((char*) brake->code);
}
} /* }}} */
-static void php_phpdbg_destroy_registered(void *data) /* {{{ */
+static void php_phpdbg_destroy_registered(zval *data) /* {{{ */
{
- zend_function *function = (zend_function*) data;
+ zend_function *function = (zend_function *) Z_PTR_P(data);
+
TSRMLS_FETCH();
- destroy_zend_function(
- function TSRMLS_CC);
+ destroy_zend_function(function TSRMLS_CC);
} /* }}} */
@@ -261,10 +261,9 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
If the request to set the context fails, boolean false is returned, and an E_WARNING raised */
static PHP_FUNCTION(phpdbg_exec)
{
- char *exec = NULL;
- int exec_len = 0;
+ zend_string *exec;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &exec, &exec_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &exec) == FAILURE) {
return;
}
@@ -272,27 +271,26 @@ static PHP_FUNCTION(phpdbg_exec)
struct stat sb;
zend_bool result = 1;
- if (VCWD_STAT(exec, &sb) != FAILURE) {
+ if (VCWD_STAT(exec->val, &sb) != FAILURE) {
if (sb.st_mode & (S_IFREG|S_IFLNK)) {
if (PHPDBG_G(exec)) {
- ZVAL_STRINGL(return_value, PHPDBG_G(exec), PHPDBG_G(exec_len), 1);
+ ZVAL_STRINGL(return_value, PHPDBG_G(exec), PHPDBG_G(exec_len));
efree(PHPDBG_G(exec));
result = 0;
}
- PHPDBG_G(exec) = estrndup(exec, exec_len);
- PHPDBG_G(exec_len) = exec_len;
+ PHPDBG_G(exec) = estrndup(exec->val, exec->len);
+ PHPDBG_G(exec_len) = exec->len;
- if (result)
+ if (result) {
ZVAL_BOOL(return_value, 1);
+ }
} else {
- zend_error(
- E_WARNING, "Failed to set execution context (%s), not a regular file or symlink", exec);
+ zend_error(E_WARNING, "Failed to set execution context (%s), not a regular file or symlink", exec);
ZVAL_BOOL(return_value, 0);
}
} else {
- zend_error(
- E_WARNING, "Failed to set execution context (%s) the file does not exist", exec);
+ zend_error(E_WARNING, "Failed to set execution context (%s) the file does not exist", exec);
ZVAL_BOOL(return_value, 0);
}
@@ -316,13 +314,8 @@ static PHP_FUNCTION(phpdbg_break)
phpdbg_parse_param(expr, expr_len, &param TSRMLS_CC);
phpdbg_do_break(&param TSRMLS_CC);
phpdbg_clear_param(&param TSRMLS_CC);
-
- } else if (EG(current_execute_data) && EG(active_op_array)) {
- zend_ulong opline_num = (EG(current_execute_data)->opline -
- EG(active_op_array)->opcodes);
-
- phpdbg_set_breakpoint_opline_ex(
- &EG(active_op_array)->opcodes[opline_num+1] TSRMLS_CC);
+ } else if (EG(current_execute_data) && EG(current_execute_data)->func->type != ZEND_INTERNAL_FUNCTION) {
+ phpdbg_set_breakpoint_opline_ex((phpdbg_opline_ptr_t) EG(current_execute_data)->opline + 1 TSRMLS_CC);
}
} /* }}} */
@@ -478,13 +471,10 @@ static void php_sapi_phpdbg_log_message(char *message TSRMLS_DC) /* {{{ */
case E_PARSE:
case E_RECOVERABLE_ERROR:
if (!(PHPDBG_G(flags) & PHPDBG_IN_EVAL)) {
- phpdbg_list_file(
- zend_get_executed_filename(TSRMLS_C),
- 3,
- zend_get_executed_lineno(TSRMLS_C)-1,
- zend_get_executed_lineno(TSRMLS_C)
- TSRMLS_CC
- );
+ const char *file_char = zend_get_executed_filename(TSRMLS_C);
+ zend_string *file = zend_string_init(file_char, strlen(file_char), 0);
+ phpdbg_list_file(file, 3, zend_get_executed_lineno(TSRMLS_C) - 1, zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC);
+ efree(file);
}
do {
@@ -515,8 +505,8 @@ static int php_sapi_phpdbg_deactivate(TSRMLS_D) /* {{{ */
static void php_sapi_phpdbg_register_vars(zval *track_vars_array TSRMLS_DC) /* {{{ */
{
- unsigned int len;
- char *docroot = "";
+ size_t len;
+ char *docroot = "";
/* In phpdbg mode, we consider the environment to be a part of the server variables
*/
@@ -524,39 +514,30 @@ static void php_sapi_phpdbg_register_vars(zval *track_vars_array TSRMLS_DC) /* {
if (PHPDBG_G(exec)) {
len = PHPDBG_G(exec_len);
- if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF",
- &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
- php_register_variable("PHP_SELF", PHPDBG_G(exec),
- track_vars_array TSRMLS_CC);
+ if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
+ php_register_variable("PHP_SELF", PHPDBG_G(exec), track_vars_array TSRMLS_CC);
}
- if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_NAME",
- &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
- php_register_variable("SCRIPT_NAME", PHPDBG_G(exec),
- track_vars_array TSRMLS_CC);
+ if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_NAME", &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
+ php_register_variable("SCRIPT_NAME", PHPDBG_G(exec), track_vars_array TSRMLS_CC);
}
- if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_FILENAME",
- &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
- php_register_variable("SCRIPT_FILENAME", PHPDBG_G(exec),
- track_vars_array TSRMLS_CC);
+ if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_FILENAME", &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
+ php_register_variable("SCRIPT_FILENAME", PHPDBG_G(exec), track_vars_array TSRMLS_CC);
}
- if (sapi_module.input_filter(PARSE_SERVER, "PATH_TRANSLATED",
- &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
- php_register_variable("PATH_TRANSLATED", PHPDBG_G(exec),
- track_vars_array TSRMLS_CC);
+ if (sapi_module.input_filter(PARSE_SERVER, "PATH_TRANSLATED", &PHPDBG_G(exec), PHPDBG_G(exec_len), &len TSRMLS_CC)) {
+ php_register_variable("PATH_TRANSLATED", PHPDBG_G(exec), track_vars_array TSRMLS_CC);
}
}
- /* any old docroot will doo */
- len = 0U;
- if (sapi_module.input_filter(PARSE_SERVER, "DOCUMENT_ROOT",
- &docroot, len, &len TSRMLS_CC)) {
+ /* any old docroot will do */
+ len = 0;
+ if (sapi_module.input_filter(PARSE_SERVER, "DOCUMENT_ROOT", &docroot, len, &len TSRMLS_CC)) {
php_register_variable("DOCUMENT_ROOT", docroot, track_vars_array TSRMLS_CC);
}
}
/* }}} */
-static inline int php_sapi_phpdbg_ub_write(const char *message, unsigned int length TSRMLS_DC) /* {{{ */
+static inline size_t php_sapi_phpdbg_ub_write(const char *message, size_t length TSRMLS_DC) /* {{{ */
{
if (PHPDBG_G(socket_fd) != -1 && !(PHPDBG_G(flags) & PHPDBG_IS_INTERACTIVE)) {
send(PHPDBG_G(socket_fd), message, length, 0);
@@ -611,23 +592,16 @@ static inline void php_sapi_phpdbg_flush(void *context) /* {{{ */
/* copied from sapi/cli/php_cli.c cli_register_file_handles */
static void phpdbg_register_file_handles(TSRMLS_D) /* {{{ */
{
- zval *zin, *zout, *zerr;
+ zval zin, zout, zerr;
php_stream *s_in, *s_out, *s_err;
php_stream_context *sc_in=NULL, *sc_out=NULL, *sc_err=NULL;
zend_constant ic, oc, ec;
- MAKE_STD_ZVAL(zin);
- MAKE_STD_ZVAL(zout);
- MAKE_STD_ZVAL(zerr);
-
s_in = php_stream_open_wrapper_ex("php://stdin", "rb", 0, NULL, sc_in);
s_out = php_stream_open_wrapper_ex("php://stdout", "wb", 0, NULL, sc_out);
s_err = php_stream_open_wrapper_ex("php://stderr", "wb", 0, NULL, sc_err);
if (s_in==NULL || s_out==NULL || s_err==NULL) {
- FREE_ZVAL(zin);
- FREE_ZVAL(zout);
- FREE_ZVAL(zerr);
if (s_in) php_stream_close(s_in);
if (s_out) php_stream_close(s_out);
if (s_err) php_stream_close(s_err);
@@ -640,34 +614,27 @@ static void phpdbg_register_file_handles(TSRMLS_D) /* {{{ */
s_err->flags |= PHP_STREAM_FLAG_NO_CLOSE;
#endif
- php_stream_to_zval(s_in, zin);
- php_stream_to_zval(s_out, zout);
- php_stream_to_zval(s_err, zerr);
+ php_stream_to_zval(s_in, &zin);
+ php_stream_to_zval(s_out, &zout);
+ php_stream_to_zval(s_err, &zerr);
- ic.value = *zin;
+ ic.value = zin;
ic.flags = CONST_CS;
- ic.name = zend_strndup(ZEND_STRL("STDIN"));
- ic.name_len = sizeof("STDIN");
+ ic.name = zend_string_init(ZEND_STRL("STDIN"), 0);
ic.module_number = 0;
zend_register_constant(&ic TSRMLS_CC);
- oc.value = *zout;
+ oc.value = zout;
oc.flags = CONST_CS;
- oc.name = zend_strndup(ZEND_STRL("STDOUT"));
- oc.name_len = sizeof("STDOUT");
+ oc.name = zend_string_init(ZEND_STRL("STDOUT"), 0);
oc.module_number = 0;
zend_register_constant(&oc TSRMLS_CC);
- ec.value = *zerr;
+ ec.value = zerr;
ec.flags = CONST_CS;
- ec.name = zend_strndup(ZEND_STRL("STDERR"));
- ec.name_len = sizeof("STDERR");
+ ec.name = zend_string_init(ZEND_STRL("STDERR"), 0);
ec.module_number = 0;
zend_register_constant(&ec TSRMLS_CC);
-
- FREE_ZVAL(zin);
- FREE_ZVAL(zout);
- FREE_ZVAL(zerr);
}
/* }}} */
@@ -721,8 +688,10 @@ const opt_struct OPTIONS[] = { /* {{{ */
{'r', 0, "run"},
{'E', 0, "step-through-eval"},
{'S', 1, "sapi-name"},
+#ifndef _WIN32
{'l', 1, "listen"},
{'a', 1, "address-or-any"},
+#endif
{'x', 0, "xml output"},
{'V', 0, "version"},
{'-', 0, NULL}
@@ -740,10 +709,9 @@ const char phpdbg_ini_hardcoded[] =
/* overwriteable ini defaults must be set in phpdbg_ini_defaults() */
#define INI_DEFAULT(name, value) \
+ ZVAL_STRINGL(&tmp, value, sizeof(value) - 1); \
Z_SET_REFCOUNT(tmp, 0); \
- Z_UNSET_ISREF(tmp); \
- ZVAL_STRINGL(&tmp, zend_strndup(value, sizeof(value)-1), sizeof(value)-1, 0); \
- zend_hash_update(configuration_hash, name, sizeof(name), &tmp, sizeof(zval), NULL);
+ zend_hash_str_update(configuration_hash, name, sizeof(name) - 1, &tmp);
void phpdbg_ini_defaults(HashTable *configuration_hash) /* {{{ */
{
@@ -805,7 +773,6 @@ static inline void phpdbg_sigint_handler(int signo) /* {{{ */
}
} /* }}} */
-
static void phpdbg_remote_close(int socket, FILE *stream) {
if (socket >= 0) {
phpdbg_close_socket(socket);
@@ -990,11 +957,13 @@ int main(int argc, char **argv) /* {{{ */
char bp_tmp_file[] = "/tmp/phpdbg.XXXXXX";
#endif
+#ifndef _WIN32
char *address;
int listen = -1;
int server = -1;
int socket = -1;
FILE* stream = NULL;
+#endif
#ifdef ZTS
void ***tsrm_ls;
@@ -1007,9 +976,10 @@ int main(int argc, char **argv) /* {{{ */
signal_struct.sa_flags = SA_SIGINFO | SA_NODEFER;
sigio_struct.sa_sigaction = phpdbg_sigio_handler;
sigio_struct.sa_flags = SA_SIGINFO;
-#endif
+
address = strdup("127.0.0.1");
+#endif
#ifdef PHP_WIN32
_fmode = _O_BINARY; /* sets default for file streams to binary */
@@ -1172,6 +1142,7 @@ phpdbg_main:
show_banner = 0;
break;
+#ifndef _WIN32
/* if you pass a listen port, we will read and write on listen port */
case 'l': /* set listen ports */
if (sscanf(php_optarg, "%d", &listen) != 1) {
@@ -1185,6 +1156,7 @@ phpdbg_main:
address = strdup("*");
} else address = strdup(php_optarg);
} break;
+#endif
case 'x':
flags |= PHPDBG_WRITE_XML;
@@ -1276,7 +1248,11 @@ phpdbg_main:
__try {
#endif
zend_mm_heap *mm_heap;
+ void* (*_malloc)(size_t);
+ void (*_free)(void*);
+ void* (*_realloc)(void*, size_t);
+#ifndef _WIN32
/* setup remote server if necessary */
if (!cleaning && listen > 0) {
server = phpdbg_open_socket(address, listen TSRMLS_CC);
@@ -1284,29 +1260,34 @@ phpdbg_main:
exit(0);
}
-#ifndef _WIN32
sigaction(SIGIO, &sigio_struct, NULL);
-#endif
/* set remote flag to stop service shutting down upon quit */
remote = 1;
}
+#endif
mm_heap = phpdbg_mm_get_heap();
+ zend_mm_get_custom_handlers(mm_heap, &_malloc, &_free, &_realloc);
- if (mm_heap->use_zend_alloc) {
- mm_heap->_malloc = phpdbg_malloc_wrapper;
- mm_heap->_realloc = phpdbg_realloc_wrapper;
- mm_heap->_free = phpdbg_free_wrapper;
- mm_heap->use_zend_alloc = 0;
+ if (!_malloc) {
+ _malloc = phpdbg_malloc_wrapper;
+ }
+ if (!_realloc) {
+ _realloc = phpdbg_realloc_wrapper;
+ }
+ if (!_free) {
+ _free = phpdbg_free_wrapper;
}
zend_activate(TSRMLS_C);
phpdbg_init_list(TSRMLS_C);
- PHPDBG_G(original_free_function) = mm_heap->_free;
- mm_heap->_free = phpdbg_watch_efree;
+ PHPDBG_G(original_free_function) = _free;
+ _free = phpdbg_watch_efree;
+
+ zend_mm_set_custom_handlers(mm_heap, _malloc, _free, _realloc);
phpdbg_setup_watchpoints(TSRMLS_C);
@@ -1363,13 +1344,14 @@ phpdbg_main:
/* set flags from command line */
PHPDBG_G(flags) = flags;
+#ifndef _WIN32
/* setup io here */
if (remote) {
PHPDBG_G(flags) |= PHPDBG_IS_REMOTE;
-#ifndef _WIN32
+
signal(SIGPIPE, SIG_IGN);
-#endif
}
+#endif
#ifndef _WIN32
PHPDBG_G(io)[PHPDBG_STDIN].ptr = stdin;
@@ -1465,7 +1447,10 @@ phpdbg_main:
}
}
+/* #ifndef for making compiler shutting up */
+#ifndef _WIN32
phpdbg_interact:
+#endif
/* phpdbg main() */
do {
zend_try {
@@ -1480,6 +1465,7 @@ phpdbg_interact:
cleaning = 0;
}
+#ifndef _WIN32
if (!cleaning) {
/* remote client disconnected */
if ((PHPDBG_G(flags) & PHPDBG_IS_DISCONNECTED)) {
@@ -1501,6 +1487,7 @@ phpdbg_interact:
}
}
}
+#endif
} zend_end_try();
} while(!cleaning && !(PHPDBG_G(flags) & PHPDBG_IS_QUITTING));
@@ -1510,17 +1497,19 @@ phpdbg_interact:
/* this is just helpful */
PG(report_memleaks) = 0;
+#ifndef _WIN32
phpdbg_out:
if ((PHPDBG_G(flags) & PHPDBG_IS_DISCONNECTED)) {
PHPDBG_G(flags) &= ~PHPDBG_IS_DISCONNECTED;
goto phpdbg_interact;
}
+#endif
#ifdef _WIN32
} __except(phpdbg_exception_handler_win32(xp = GetExceptionInformation())) {
phpdbg_error("segfault", "", "Access violation (Segementation fault) encountered\ntrying to abort cleanly...");
}
-/* phpdbg_out: */
+phpdbg_out:
#endif
{
diff --git a/sapi/phpdbg/phpdbg.h b/sapi/phpdbg/phpdbg.h
index 8c0dbb4afa..f3e8ba3107 100644
--- a/sapi/phpdbg/phpdbg.h
+++ b/sapi/phpdbg/phpdbg.h
@@ -67,6 +67,29 @@
# include "TSRM.h"
#endif
+#define ZEND_HASH_FOREACH_NUM_KEY_PTR(ht, _h, _ptr) \
+ ZEND_HASH_FOREACH(ht, 0); \
+ _h = _p->h; \
+ _ptr = Z_PTR_P(_z);
+
+#undef zend_hash_str_add
+#define zend_hash_str_add_tmp(ht, key, len, pData) \
+ _zend_hash_str_add(ht, key, len, pData ZEND_FILE_LINE_CC)
+#define zend_hash_str_add(...) zend_hash_str_add_tmp(__VA_ARGS__)
+
+static zend_always_inline void *zend_hash_index_add_mem(HashTable *ht, zend_ulong h, void *pData, size_t size)
+{
+ zval tmp, *zv;
+
+ ZVAL_PTR(&tmp, NULL);
+ if ((zv = zend_hash_index_add(ht, h, &tmp))) {
+ Z_PTR_P(zv) = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT);
+ memcpy(Z_PTR_P(zv), pData, size);
+ return Z_PTR_P(zv);
+ }
+ return NULL;
+}
+
#ifdef HAVE_LIBREADLINE
# include <readline/readline.h>
# include <readline/history.h>
@@ -225,7 +248,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
HashTable registered; /* registered */
HashTable seek; /* seek oplines */
phpdbg_frame_t frame; /* frame */
- zend_uint last_line; /* last executed line */
+ uint32_t last_line; /* last executed line */
phpdbg_lexer_data lexer; /* lexer data */
phpdbg_param_t *parser_stack; /* param stack during lexer / parser phase */
@@ -236,6 +259,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
phpdbg_btree watchpoint_tree; /* tree with watchpoints */
phpdbg_btree watch_HashTables; /* tree with original dtors of watchpoints */
HashTable watchpoints; /* watchpoints */
+ HashTable watch_collisions; /* collision table to check if multiple watches share the same recursive watchpoint */
zend_llist watchlist_mem; /* triggered watchpoints */
zend_bool watchpoint_hit; /* a watchpoint was hit */
void (*original_free_function)(void *); /* the original AG(mm_heap)->_free function */
@@ -243,9 +267,10 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
char *exec; /* file to execute */
size_t exec_len; /* size of exec */
zend_op_array *ops; /* op_array */
- zval *retval; /* return value */
+ zval retval; /* return value */
int bp_count; /* breakpoint count */
int vmret; /* return from last opcode handler execution */
+ zend_bool in_execution; /* in execution? */
zend_op_array *(*compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);
HashTable file_sources;
diff --git a/sapi/phpdbg/phpdbg_bp.c b/sapi/phpdbg/phpdbg_bp.c
index 81674a0daf..aaeaee13fd 100644
--- a/sapi/phpdbg/phpdbg_bp.c
+++ b/sapi/phpdbg/phpdbg_bp.c
@@ -43,7 +43,7 @@ static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execut
*/
static inline void _phpdbg_break_mapping(int id, HashTable *table TSRMLS_DC)
{
- zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (id), (void**) &table, sizeof(void*), NULL);
+ zend_hash_index_update_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], id, table);
}
#define PHPDBG_BREAK_MAPPING(id, table) _phpdbg_break_mapping(id, table TSRMLS_CC)
@@ -57,29 +57,29 @@ static inline void _phpdbg_break_mapping(int id, HashTable *table TSRMLS_DC)
b.hits = 0; \
} while(0)
-static void phpdbg_file_breaks_dtor(void *data) /* {{{ */
+static void phpdbg_file_breaks_dtor(zval *data) /* {{{ */
{
- phpdbg_breakfile_t *bp = (phpdbg_breakfile_t*) data;
+ phpdbg_breakfile_t *bp = (phpdbg_breakfile_t*) Z_PTR_P(data);
efree((char*)bp->filename);
} /* }}} */
-static void phpdbg_class_breaks_dtor(void *data) /* {{{ */
+static void phpdbg_class_breaks_dtor(zval *data) /* {{{ */
{
- phpdbg_breakmethod_t *bp = (phpdbg_breakmethod_t*) data;
+ phpdbg_breakmethod_t *bp = (phpdbg_breakmethod_t *) Z_PTR_P(data);
efree((char*)bp->class_name);
efree((char*)bp->func_name);
} /* }}} */
-static void phpdbg_opline_class_breaks_dtor(void *data) /* {{{ */
+static void phpdbg_opline_class_breaks_dtor(zval *data) /* {{{ */
{
- zend_hash_destroy((HashTable *)data);
+ zend_hash_destroy((HashTable *) Z_PTR_P(data));
} /* }}} */
-static void phpdbg_opline_breaks_dtor(void *data) /* {{{ */
+static void phpdbg_opline_breaks_dtor(zval *data) /* {{{ */
{
- phpdbg_breakopline_t *bp = (phpdbg_breakopline_t *) data;
+ phpdbg_breakopline_t *bp = (phpdbg_breakopline_t *) Z_PTR_P(data);
if (bp->class_name) {
efree((char*)bp->class_name);
@@ -91,43 +91,30 @@ static void phpdbg_opline_breaks_dtor(void *data) /* {{{ */
PHPDBG_API void phpdbg_reset_breakpoints(TSRMLS_D) /* {{{ */
{
- if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])) {
- HashPosition position[2];
- HashTable **table = NULL;
+ HashTable *table;
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (void **) &table, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0])) {
- phpdbg_breakbase_t *brake;
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], table) {
+ phpdbg_breakbase_t *brake;
- for (zend_hash_internal_pointer_reset_ex((*table), &position[1]);
- zend_hash_get_current_data_ex((*table), (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex((*table), &position[1])) {
- brake->hits = 0;
- }
- }
- }
+ ZEND_HASH_FOREACH_PTR(table, brake) {
+ brake->hits = 0;
+ } ZEND_HASH_FOREACH_END();
+ } ZEND_HASH_FOREACH_END();
} /* }}} */
PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
{
- HashPosition position[2];
- HashTable **table = NULL;
+ HashTable *table;
zend_ulong id = 0L;
if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP])) {
phpdbg_notice("exportbreakpoint", "count=\"%d\"", "Exporting %d breakpoints", zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP]));
+
/* this only looks like magic, it isn't */
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], (void **) &table, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], &position[0])) {
+ ZEND_HASH_FOREACH_NUM_KEY_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], id, table) {
phpdbg_breakbase_t *brake;
- zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], NULL, NULL, &id, 0, &position[0]);
-
- for (zend_hash_internal_pointer_reset_ex((*table), &position[1]);
- zend_hash_get_current_data_ex((*table), (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex((*table), &position[1])) {
+ ZEND_HASH_FOREACH_PTR(table, brake) {
if (brake->id == id) {
switch (brake->type) {
case PHPDBG_BREAK_FILE: {
@@ -152,7 +139,7 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
case PHPDBG_BREAK_METHOD_OPLINE: {
fprintf(handle,
- "break %s::%s#%ld\n",
+ "break %s::%s#%llu\n",
((phpdbg_breakopline_t*)brake)->class_name,
((phpdbg_breakopline_t*)brake)->func_name,
((phpdbg_breakopline_t*)brake)->opline_num);
@@ -160,14 +147,14 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
case PHPDBG_BREAK_FUNCTION_OPLINE: {
fprintf(handle,
- "break %s#%ld\n",
+ "break %s#%llu\n",
((phpdbg_breakopline_t*)brake)->func_name,
((phpdbg_breakopline_t*)brake)->opline_num);
} break;
case PHPDBG_BREAK_FILE_OPLINE: {
fprintf(handle,
- "break %s:#%ld\n",
+ "break %s:#%llu\n",
((phpdbg_breakopline_t*)brake)->class_name,
((phpdbg_breakopline_t*)brake)->opline_num);
} break;
@@ -211,8 +198,8 @@ PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC) /* {{{ */
} break;
}
}
- }
- }
+ } ZEND_HASH_FOREACH_END();
+ } ZEND_HASH_FOREACH_END();
}
} /* }}} */
@@ -232,15 +219,12 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML
}
path_len = strlen(path);
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE],
- path, path_len, (void**)&broken) == FAILURE) {
+ if (!(broken = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], path, path_len))) {
HashTable breaks;
zend_hash_init(&breaks, 8, NULL, phpdbg_file_breaks_dtor, 0);
- zend_hash_update(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE],
- path, path_len, &breaks, sizeof(HashTable),
- (void**)&broken);
+ broken = zend_hash_str_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], path, path_len, &breaks, sizeof(HashTable));
}
if (!zend_hash_index_exists(broken, line_num)) {
@@ -250,10 +234,9 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML
new_break.filename = estrndup(path, path_len);
new_break.line = line_num;
- zend_hash_index_update( broken, line_num, (void**)&new_break, sizeof(phpdbg_breakfile_t), NULL);
+ zend_hash_index_update_mem(broken, line_num, &new_break, sizeof(phpdbg_breakfile_t));
- phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" file=\"%s\" line=\"%ld\"", "Breakpoint #%d added at %s:%ld",
- new_break.id, new_break.filename, new_break.line);
+ phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" file=\"%s\" line=\"%ld\"", "Breakpoint #%d added at %s:%ld", new_break.id, new_break.filename, new_break.line);
PHPDBG_BREAK_MAPPING(new_break.id, broken);
} else {
@@ -270,7 +253,7 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num TSRML
PHPDBG_API void phpdbg_set_breakpoint_symbol(const char *name, size_t name_len TSRMLS_DC) /* {{{ */
{
- if (!zend_hash_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], name, name_len)) {
+ if (!zend_hash_str_exists(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], name, name_len)) {
phpdbg_breaksymbol_t new_break;
PHPDBG_G(flags) |= PHPDBG_HAS_SYM_BP;
@@ -278,11 +261,9 @@ PHPDBG_API void phpdbg_set_breakpoint_symbol(const char *name, size_t name_len T
PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_SYM);
new_break.symbol = estrndup(name, name_len);
- zend_hash_update(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], new_break.symbol,
- name_len, &new_break, sizeof(phpdbg_breaksymbol_t), NULL);
+ zend_hash_str_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], new_break.symbol, name_len, &new_break, sizeof(phpdbg_breaksymbol_t));
- phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" function=\"%s\"", "Breakpoint #%d added at %s",
- new_break.id, new_break.symbol);
+ phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" function=\"%s\"", "Breakpoint #%d added at %s", new_break.id, new_break.symbol);
PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_SYM]);
} else {
@@ -297,16 +278,12 @@ PHPDBG_API void phpdbg_set_breakpoint_method(const char *class_name, const char
size_t func_len = strlen(func_name);
char *lcname = zend_str_tolower_dup(func_name, func_len);
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], class_name,
- class_len, (void**)&class_table) != SUCCESS) {
+ if (!(class_table = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], class_name, class_len))) {
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,
- (void**)&class_breaks, sizeof(HashTable), (void**)&class_table);
+ class_table = zend_hash_str_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], class_name, class_len, &class_breaks, sizeof(HashTable));
}
- if (!zend_hash_exists(class_table, lcname, func_len)) {
+ if (!zend_hash_str_exists(class_table, lcname, func_len)) {
phpdbg_breakmethod_t new_break;
PHPDBG_G(flags) |= PHPDBG_HAS_METHOD_BP;
@@ -317,11 +294,9 @@ PHPDBG_API void phpdbg_set_breakpoint_method(const char *class_name, const char
new_break.func_name = estrndup(func_name, func_len);
new_break.func_len = func_len;
- zend_hash_update(class_table, lcname, func_len,
- &new_break, sizeof(phpdbg_breakmethod_t), NULL);
+ zend_hash_str_update_mem(class_table, lcname, func_len, &new_break, sizeof(phpdbg_breakmethod_t));
- phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" method=\"%s::%s\"", "Breakpoint #%d added at %s::%s",
- new_break.id, class_name, func_name);
+ phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" method=\"%s::%s\"", "Breakpoint #%d added at %s::%s", new_break.id, class_name, func_name);
PHPDBG_BREAK_MAPPING(new_break.id, class_table);
} else {
@@ -343,11 +318,9 @@ PHPDBG_API void phpdbg_set_breakpoint_opline(zend_ulong opline TSRMLS_DC) /* {{{
new_break.opline = opline;
new_break.base = NULL;
- zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline,
- &new_break, sizeof(phpdbg_breakline_t), NULL);
+ zend_hash_index_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline, &new_break, sizeof(phpdbg_breakline_t));
- phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" opline=\"%#lx\"", "Breakpoint #%d added at %#lx",
- new_break.id, new_break.opline);
+ phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" opline=\"%#lx\"", "Breakpoint #%d added at %#lx", new_break.id, new_break.opline);
PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
} else {
phpdbg_error("breakpoint", "type=\"exists\" add=\"fail\" opline=\"%#lx\"", "Breakpoint exists at %#lx", opline);
@@ -385,7 +358,7 @@ PHPDBG_API int phpdbg_resolve_op_array_break(phpdbg_breakopline_t *brake, zend_o
PHPDBG_G(flags) |= PHPDBG_HAS_OPLINE_BP;
- zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline_break.opline, &opline_break, sizeof(phpdbg_breakline_t), NULL);
+ zend_hash_index_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], opline_break.opline, &opline_break, sizeof(phpdbg_breakline_t));
return SUCCESS;
} /* }}} */
@@ -394,40 +367,36 @@ PHPDBG_API void phpdbg_resolve_op_array_breaks(zend_op_array *op_array TSRMLS_DC
{
HashTable *func_table = &PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE];
HashTable *oplines_table;
- HashPosition position;
phpdbg_breakopline_t *brake;
- if (op_array->scope != NULL &&
- zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], op_array->scope->name, op_array->scope->name_length, (void **)&func_table) == FAILURE) {
+ if (op_array->scope != NULL && !(func_table = zend_hash_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], op_array->scope->name))) {
return;
}
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) {
+ if (!(oplines_table = zend_hash_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], op_array->filename))) {
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) {
+ } else if (!op_array->function_name || !(oplines_table = zend_hash_find_ptr(func_table, op_array->function_name))) {
return;
}
- for (zend_hash_internal_pointer_reset_ex(oplines_table, &position);
- zend_hash_get_current_data_ex(oplines_table, (void**) &brake, &position) == SUCCESS;
- zend_hash_move_forward_ex(oplines_table, &position)) {
+ ZEND_HASH_FOREACH_PTR(oplines_table, brake) {
if (phpdbg_resolve_op_array_break(brake, op_array TSRMLS_CC) == SUCCESS) {
phpdbg_breakline_t *opline_break;
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);
+ opline_break = zend_hash_get_current_data_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
phpdbg_notice("breakpoint", "add=\"success\" id=\"%d\" symbol=\"%s\" num=\"%ld\" opline=\"%#lx\"", "Breakpoint #%d resolved at %s%s%s#%ld (opline %#lx)",
brake->id,
- brake->class_name?brake->class_name:"",
- brake->class_name&&brake->func_name?"::":"",
- brake->func_name?brake->func_name:"",
+ brake->class_name ? brake->class_name : "",
+ brake->class_name && brake->func_name ? "::" : "",
+ brake->func_name ? brake->func_name : "",
brake->opline_num,
brake->opline);
}
- }
+ } ZEND_HASH_FOREACH_END();
} /* }}} */
PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRMLS_DC) /* {{{ */
@@ -448,8 +417,9 @@ PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRML
} else {
zend_execute_data *execute_data = EG(current_execute_data);
do {
- if (execute_data->op_array->function_name == NULL && execute_data->op_array->scope == NULL && !memcmp(execute_data->op_array->filename, new_break->class_name, new_break->class_len)) {
- if (phpdbg_resolve_op_array_break(new_break, execute_data->op_array TSRMLS_CC) == SUCCESS) {
+ zend_op_array *op_array = &execute_data->func->op_array;
+ if (op_array->function_name == NULL && op_array->scope == NULL && new_break->class_len == op_array->filename->len && !memcmp(op_array->filename->val, new_break->class_name, new_break->class_len)) {
+ if (phpdbg_resolve_op_array_break(new_break, op_array TSRMLS_CC) == SUCCESS) {
return SUCCESS;
} else {
return 2;
@@ -461,14 +431,14 @@ PHPDBG_API int phpdbg_resolve_opline_break(phpdbg_breakopline_t *new_break TSRML
}
if (new_break->class_name != NULL) {
- zend_class_entry **ce;
- if (zend_hash_find(EG(class_table), zend_str_tolower_dup(new_break->class_name, new_break->class_len), new_break->class_len + 1, (void **)&ce) == FAILURE) {
+ zend_class_entry *ce;
+ if (!(ce = zend_hash_str_find_ptr(EG(class_table), zend_str_tolower_dup(new_break->class_name, new_break->class_len), new_break->class_len))) {
return FAILURE;
}
- func_table = &(*ce)->function_table;
+ func_table = &ce->function_table;
}
- if (zend_hash_find(func_table, zend_str_tolower_dup(new_break->func_name, new_break->func_len), new_break->func_len + 1, (void **)&func) == FAILURE) {
+ if (!(func = zend_hash_str_find_ptr(func_table, zend_str_tolower_dup(new_break->func_name, new_break->func_len), new_break->func_len))) {
if (new_break->class_name != NULL && new_break->func_name != NULL) {
phpdbg_error("breakpoint", "type=\"nomethod\" method=\"%s::%s\"", "Method %s doesn't exist in class %s", new_break->func_name, new_break->class_name);
return 2;
@@ -519,22 +489,14 @@ PHPDBG_API void phpdbg_set_breakpoint_method_opline(const char *class, const cha
return;
}
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], new_break.class_name, new_break.class_len, (void **)&class_table) == FAILURE) {
+ if (!(class_table = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], new_break.class_name, new_break.class_len))) {
zend_hash_init(&class_breaks, 8, NULL, phpdbg_opline_class_breaks_dtor, 0);
- zend_hash_update(
- &PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE],
- new_break.class_name,
- new_break.class_len,
- (void **)&class_breaks, sizeof(HashTable), (void **)&class_table);
+ class_table = zend_hash_str_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], new_break.class_name, new_break.class_len, &class_breaks, sizeof(HashTable));
}
- if (zend_hash_find(class_table, new_break.func_name, new_break.func_len, (void **)&method_table) == FAILURE) {
+ if (!(method_table = zend_hash_str_find_ptr(class_table, new_break.func_name, new_break.func_len))) {
zend_hash_init(&method_breaks, 8, NULL, phpdbg_opline_breaks_dtor, 0);
- zend_hash_update(
- class_table,
- new_break.func_name,
- new_break.func_len,
- (void **)&method_breaks, sizeof(HashTable), (void **)&method_table);
+ method_table = zend_hash_str_update_mem(class_table, new_break.func_name, new_break.func_len, &method_breaks, sizeof(HashTable));
}
if (zend_hash_index_exists(method_table, opline)) {
@@ -549,7 +511,7 @@ PHPDBG_API void phpdbg_set_breakpoint_method_opline(const char *class, const cha
PHPDBG_BREAK_MAPPING(new_break.id, method_table);
- zend_hash_index_update(method_table, opline, &new_break, sizeof(phpdbg_breakopline_t), NULL);
+ zend_hash_index_update_mem(method_table, opline, &new_break, sizeof(phpdbg_breakopline_t));
}
PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, zend_ulong opline TSRMLS_DC) /* {{{ */
@@ -578,13 +540,9 @@ PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, zend
return;
}
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], new_break.func_name, new_break.func_len, (void **)&func_table) == FAILURE) {
+ if (!(func_table = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], new_break.func_name, new_break.func_len))) {
zend_hash_init(&func_breaks, 8, NULL, phpdbg_opline_breaks_dtor, 0);
- zend_hash_update(
- &PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE],
- new_break.func_name,
- new_break.func_len,
- (void **)&func_breaks, sizeof(HashTable), (void **)&func_table);
+ func_table = zend_hash_str_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], new_break.func_name, new_break.func_len, &func_breaks, sizeof(HashTable));
}
if (zend_hash_index_exists(func_table, opline)) {
@@ -598,7 +556,7 @@ PHPDBG_API void phpdbg_set_breakpoint_function_opline(const char *function, zend
PHPDBG_G(flags) |= PHPDBG_HAS_FUNCTION_OPLINE_BP;
- zend_hash_index_update(func_table, opline, &new_break, sizeof(phpdbg_breakopline_t), NULL);
+ zend_hash_index_update_mem(func_table, opline, &new_break, sizeof(phpdbg_breakopline_t));
}
PHPDBG_API void phpdbg_set_breakpoint_file_opline(const char *file, zend_ulong opline TSRMLS_DC) /* {{{ */
@@ -627,13 +585,9 @@ PHPDBG_API void phpdbg_set_breakpoint_file_opline(const char *file, zend_ulong o
return;
}
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], new_break.class_name, new_break.class_len, (void **)&file_table) == FAILURE) {
+ if (!(file_table = zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], new_break.class_name, new_break.class_len))) {
zend_hash_init(&file_breaks, 8, NULL, phpdbg_opline_breaks_dtor, 0);
- zend_hash_update(
- &PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE],
- new_break.class_name,
- new_break.class_len,
- (void **)&file_breaks, sizeof(HashTable), (void **)&file_table);
+ file_table = zend_hash_str_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], new_break.class_name, new_break.class_len, &file_breaks, sizeof(HashTable));
}
if (zend_hash_index_exists(file_table, opline)) {
@@ -647,7 +601,7 @@ PHPDBG_API void phpdbg_set_breakpoint_file_opline(const char *file, zend_ulong o
PHPDBG_G(flags) |= PHPDBG_HAS_FILE_OPLINE_BP;
- zend_hash_index_update(file_table, opline, &new_break, sizeof(phpdbg_breakopline_t), NULL);
+ zend_hash_index_update_mem(file_table, opline, &new_break, sizeof(phpdbg_breakopline_t));
}
PHPDBG_API void phpdbg_set_breakpoint_opcode(const char *name, size_t name_len TSRMLS_DC) /* {{{ */
@@ -664,8 +618,7 @@ PHPDBG_API void phpdbg_set_breakpoint_opcode(const char *name, size_t name_len T
new_break.hash = hash;
new_break.name = estrndup(name, name_len);
- zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], hash,
- &new_break, sizeof(phpdbg_breakop_t), NULL);
+ zend_hash_index_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], hash, &new_break, sizeof(phpdbg_breakop_t));
PHPDBG_G(flags) |= PHPDBG_HAS_OPCODE_BP;
@@ -683,8 +636,7 @@ PHPDBG_API void phpdbg_set_breakpoint_opline_ex(phpdbg_opline_ptr_t opline TSRML
PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_OPLINE);
new_break.opline = (zend_ulong) opline;
- zend_hash_index_update(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE],
- (zend_ulong) opline, &new_break, sizeof(phpdbg_breakline_t), NULL);
+ zend_hash_index_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (zend_ulong) opline, &new_break, sizeof(phpdbg_breakline_t));
phpdbg_notice("breakpoint", "id=\"%d\" opline=\"%#lx\"", "Breakpoint #%d added at %#lx", new_break.id, new_break.opline);
PHPDBG_BREAK_MAPPING(new_break.id, &PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
@@ -696,7 +648,7 @@ PHPDBG_API void phpdbg_set_breakpoint_opline_ex(phpdbg_opline_ptr_t opline TSRML
static inline void phpdbg_create_conditional_break(phpdbg_breakcond_t *brake, const phpdbg_param_t *param, const char *expr, size_t expr_len, zend_ulong hash TSRMLS_DC) /* {{{ */
{
phpdbg_breakcond_t new_break;
- zend_uint cops = CG(compiler_options);
+ uint32_t cops = CG(compiler_options);
zval pv;
PHPDBG_BREAK_INIT(new_break, PHPDBG_BREAK_COND);
@@ -717,22 +669,19 @@ static inline void phpdbg_create_conditional_break(phpdbg_breakcond_t *brake, co
new_break.code = estrndup(expr, expr_len);
new_break.code_len = expr_len;
- Z_STRLEN(pv) = expr_len + sizeof("return ;") - 1;
- Z_STRVAL(pv) = emalloc(Z_STRLEN(pv) + 1);
+ Z_STR(pv) = zend_string_alloc(expr_len + sizeof("return ;") - 1, 0);
memcpy(Z_STRVAL(pv), "return ", sizeof("return ") - 1);
memcpy(Z_STRVAL(pv) + sizeof("return ") - 1, expr, expr_len);
Z_STRVAL(pv)[Z_STRLEN(pv) - 1] = ';';
Z_STRVAL(pv)[Z_STRLEN(pv)] = '\0';
- Z_TYPE(pv) = IS_STRING;
+ Z_TYPE_INFO(pv) = IS_STRING;
new_break.ops = zend_compile_string(&pv, "Conditional Breakpoint Code" TSRMLS_CC);
zval_dtor(&pv);
if (new_break.ops) {
- zend_hash_index_update(
- &PHPDBG_G(bp)[PHPDBG_BREAK_COND], hash, &new_break,
- sizeof(phpdbg_breakcond_t), (void**)&brake);
+ brake = zend_hash_index_update_mem(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], hash, &new_break, sizeof(phpdbg_breakcond_t));
phpdbg_notice("breakpoint", "id=\"%d\" expression=\"%s\" ptr=\"%p\"", "Conditional breakpoint #%d added %s/%p", brake->id, brake->code, brake->ops);
@@ -743,6 +692,7 @@ static inline void phpdbg_create_conditional_break(phpdbg_breakcond_t *brake, co
efree((char*)new_break.code);
PHPDBG_G(bp_count)--;
}
+
CG(compiler_options) = cops;
} /* }}} */
@@ -782,14 +732,12 @@ static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_file(zend_op_array *op_
{
HashTable *breaks;
phpdbg_breakbase_t *brake;
- size_t name_len = strlen(op_array->filename);
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], op_array->filename,
- name_len, (void**)&breaks) == FAILURE) {
+ if (!(breaks = zend_hash_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], op_array->filename))) {
return NULL;
}
- if (zend_hash_index_find(breaks, (*EG(opline_ptr))->lineno, (void**)&brake) == SUCCESS) {
+ if (EG(current_execute_data) && (brake = zend_hash_index_find_ptr(breaks, EG(current_execute_data)->opline->lineno))) {
return brake;
}
@@ -799,88 +747,73 @@ static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_file(zend_op_array *op_
static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_symbol(zend_function *fbc TSRMLS_DC) /* {{{ */
{
const char *fname;
+ size_t flen;
zend_op_array *ops;
- phpdbg_breakbase_t *brake;
if (fbc->type != ZEND_USER_FUNCTION) {
return NULL;
}
- ops = (zend_op_array*)fbc;
+ ops = (zend_op_array *) fbc;
if (ops->scope) {
/* find method breaks here */
return phpdbg_find_breakpoint_method(ops TSRMLS_CC);
}
- fname = ops->function_name;
-
- if (!fname) {
+ if (ops->function_name) {
+ fname = ops->function_name->val;
+ flen = ops->function_name->len;
+ } else {
fname = "main";
+ flen = 4;
}
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], fname, strlen(fname), (void**)&brake) == SUCCESS) {
- return brake;
- }
-
- return NULL;
+ return zend_hash_str_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], fname, flen);
} /* }}} */
static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_method(zend_op_array *ops TSRMLS_DC) /* {{{ */
{
HashTable *class_table;
- phpdbg_breakbase_t *brake;
+ phpdbg_breakbase_t *brake = NULL;
- if (zend_hash_find(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], ops->scope->name,
- ops->scope->name_length, (void**)&class_table) == SUCCESS) {
- char *lcname = zend_str_tolower_dup(ops->function_name, strlen(ops->function_name));
- size_t lcname_len = strlen(lcname);
-
- if (zend_hash_find(
- class_table,
- lcname,
- lcname_len, (void**)&brake) == SUCCESS) {
- efree(lcname);
- return brake;
- }
+ if ((class_table = zend_hash_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], ops->scope->name))) {
+ size_t lcname_len = ops->function_name->len;
+ char *lcname = zend_str_tolower_dup(ops->function_name->val, lcname_len);
+
+ brake = zend_hash_str_find_ptr(class_table, lcname, lcname_len);
efree(lcname);
}
- return NULL;
+ return brake;
} /* }}} */
static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_opline(phpdbg_opline_ptr_t opline TSRMLS_DC) /* {{{ */
{
phpdbg_breakline_t *brake;
- if (zend_hash_index_find(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE],
- (zend_ulong) opline, (void**)&brake) == SUCCESS) {
- return (brake->base?(phpdbg_breakbase_t *)brake->base:(phpdbg_breakbase_t *)brake);
+ if ((brake = zend_hash_index_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (zend_ulong) opline)) && brake->base) {
+ return (phpdbg_breakbase_t *)brake->base;
}
- return NULL;
+ return (phpdbg_breakbase_t *) brake;
} /* }}} */
static inline phpdbg_breakbase_t *phpdbg_find_breakpoint_opcode(zend_uchar opcode TSRMLS_DC) /* {{{ */
{
- phpdbg_breakbase_t *brake;
const char *opname = phpdbg_decode_opcode(opcode);
if (memcmp(opname, PHPDBG_STRL("UNKNOWN")) == 0) {
return NULL;
}
- if (zend_hash_index_find(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE],
- zend_hash_func(opname, strlen(opname)), (void**)&brake) == SUCCESS) {
- return brake;
- }
- return NULL;
+ return zend_hash_index_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], zend_hash_func(opname, strlen(opname)));
} /* }}} */
static inline zend_bool phpdbg_find_breakpoint_param(phpdbg_param_t *param, zend_execute_data *execute_data TSRMLS_DC) /* {{{ */
{
- zend_function *function = (zend_function*) execute_data->function_state.function;
+ zend_function *function = execute_data->func;
switch (param->type) {
case NUMERIC_FUNCTION_PARAM:
@@ -895,8 +828,8 @@ static inline zend_bool phpdbg_find_breakpoint_param(phpdbg_param_t *param, zend
const char *str = NULL;
size_t len = 0L;
zend_op_array *ops = (zend_op_array*)function;
- str = ops->function_name ? ops->function_name : "main";
- len = strlen(str);
+ str = ops->function_name ? ops->function_name->val : "main";
+ len = ops->function_name ? ops->function_name->len : strlen(str);
if (len == param->len && memcmp(param->str, str, len) == SUCCESS) {
return param->type == STR_PARAM || execute_data->opline - ops->opcodes == param->num;
@@ -926,10 +859,10 @@ static inline zend_bool phpdbg_find_breakpoint_param(phpdbg_param_t *param, zend
zend_op_array *ops = (zend_op_array*) function;
if (ops->scope) {
- size_t lengths[2] = {strlen(param->method.class), ops->scope->name_length};
+ size_t lengths[2] = { strlen(param->method.class), ops->scope->name->len };
if (lengths[0] == lengths[1] && memcmp(param->method.class, ops->scope->name, lengths[0]) == SUCCESS) {
lengths[0] = strlen(param->method.name);
- lengths[1] = strlen(ops->function_name);
+ lengths[1] = ops->function_name->len;
if (lengths[0] == lengths[1] && memcmp(param->method.name, ops->function_name, lengths[0]) == SUCCESS) {
return param->type == METHOD_PARAM || (execute_data->opline - ops->opcodes) == param->num;
@@ -953,16 +886,13 @@ static inline zend_bool phpdbg_find_breakpoint_param(phpdbg_param_t *param, zend
static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */
{
phpdbg_breakcond_t *bp;
- HashPosition position;
int breakpoint = FAILURE;
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], (void*)&bp, &position) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) {
- zval *retval = NULL;
- zval **orig_retval = EG(return_value_ptr_ptr);
- zend_op_array *orig_ops = EG(active_op_array);
- zend_op **orig_opline = EG(opline_ptr);
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], bp) {
+ zval retval;
+ const zend_op *orig_opline = EG(current_execute_data)->opline;
+ zend_function *orig_func = EG(current_execute_data)->func;
+ zval *orig_retval = EG(current_execute_data)->return_value;
if (((phpdbg_breakbase_t*)bp)->disabled) {
continue;
@@ -974,49 +904,37 @@ static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execut
}
}
- ALLOC_INIT_ZVAL(retval);
-
- EG(return_value_ptr_ptr) = &retval;
- EG(active_op_array) = bp->ops;
EG(no_extensions) = 1;
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
+ zend_rebuild_symbol_table(TSRMLS_C);
zend_try {
PHPDBG_G(flags) |= PHPDBG_IN_COND_BP;
- zend_execute(EG(active_op_array) TSRMLS_CC);
+ zend_execute(bp->ops, &retval TSRMLS_CC);
#if PHP_VERSION_ID >= 50700
- if (zend_is_true(retval TSRMLS_CC)) {
+ if (zend_is_true(&retval TSRMLS_CC)) {
#else
- if (zend_is_true(retval)) {
+ if (zend_is_true(&retval)) {
#endif
breakpoint = SUCCESS;
}
- } zend_catch {
- EG(no_extensions)=1;
- EG(return_value_ptr_ptr) = orig_retval;
- EG(active_op_array) = orig_ops;
- EG(opline_ptr) = orig_opline;
- PHPDBG_G(flags) &= ~PHPDBG_IN_COND_BP;
} zend_end_try();
- EG(no_extensions)=1;
- EG(return_value_ptr_ptr) = orig_retval;
- EG(active_op_array) = orig_ops;
- EG(opline_ptr) = orig_opline;
+ EG(no_extensions) = 1;
+ EG(current_execute_data)->opline = orig_opline;
+ EG(current_execute_data)->func = orig_func;
+ EG(current_execute_data)->return_value = orig_retval;
PHPDBG_G(flags) &= ~PHPDBG_IN_COND_BP;
if (breakpoint == SUCCESS) {
break;
}
- }
+ } ZEND_HASH_FOREACH_END();
- return (breakpoint == SUCCESS) ? ((phpdbg_breakbase_t*)bp) : NULL;
+ return (breakpoint == SUCCESS) ? ((phpdbg_breakbase_t *) bp) : NULL;
} /* }}} */
-PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakpoint(zend_execute_data* execute_data TSRMLS_DC) /* {{{ */
+PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakpoint(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */
{
phpdbg_breakbase_t *base = NULL;
@@ -1031,28 +949,24 @@ PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakpoint(zend_execute_data* execute
goto result;
}
- if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_BP) &&
- (base = phpdbg_find_breakpoint_file(execute_data->op_array TSRMLS_CC))) {
+ if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_BP) && (base = phpdbg_find_breakpoint_file(&execute_data->func->op_array TSRMLS_CC))) {
goto result;
}
if (PHPDBG_G(flags) & (PHPDBG_HAS_METHOD_BP|PHPDBG_HAS_SYM_BP)) {
/* check we are at the beginning of the stack */
- if (execute_data->opline == EG(active_op_array)->opcodes) {
- if ((base = phpdbg_find_breakpoint_symbol(
- execute_data->function_state.function TSRMLS_CC))) {
+ if (execute_data->opline == execute_data->func->op_array.opcodes) {
+ if ((base = phpdbg_find_breakpoint_symbol(execute_data->func TSRMLS_CC))) {
goto result;
}
}
}
- if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP) &&
- (base = phpdbg_find_breakpoint_opline(execute_data->opline TSRMLS_CC))) {
+ if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP) && (base = phpdbg_find_breakpoint_opline((phpdbg_opline_ptr_t) execute_data->opline TSRMLS_CC))) {
goto result;
}
- if ((PHPDBG_G(flags) & PHPDBG_HAS_OPCODE_BP) &&
- (base = phpdbg_find_breakpoint_opcode(execute_data->opline->opcode TSRMLS_CC))) {
+ if ((PHPDBG_G(flags) & PHPDBG_HAS_OPCODE_BP) && (base = phpdbg_find_breakpoint_opcode(execute_data->opline->opcode TSRMLS_CC))) {
goto result;
}
@@ -1069,14 +983,12 @@ result:
PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */
{
- HashTable **table;
- HashPosition position;
+ HashTable *table;
phpdbg_breakbase_t *brake;
+ zend_string *strkey;
+ zend_ulong numkey;
- if ((brake = phpdbg_find_breakbase_ex(num, &table, &position TSRMLS_CC))) {
- char *key;
- zend_uint klen;
- zend_ulong idx;
+ if ((brake = phpdbg_find_breakbase_ex(num, &table, &numkey, &strkey TSRMLS_CC))) {
int type = brake->type;
char *name = NULL;
size_t name_len = 0L;
@@ -1084,7 +996,7 @@ PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */
switch (type) {
case PHPDBG_BREAK_FILE:
case PHPDBG_BREAK_METHOD:
- if (zend_hash_num_elements((*table)) == 1) {
+ if (zend_hash_num_elements(table) == 1) {
name = estrdup(brake->name);
name_len = strlen(name);
if (zend_hash_num_elements(&PHPDBG_G(bp)[type]) == 1) {
@@ -1094,7 +1006,7 @@ PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */
break;
default: {
- if (zend_hash_num_elements((*table)) == 1) {
+ if (zend_hash_num_elements(table) == 1) {
PHPDBG_G(flags) &= ~(1<<(brake->type+1));
}
}
@@ -1107,25 +1019,20 @@ PHPDBG_API void phpdbg_delete_breakpoint(zend_ulong num TSRMLS_DC) /* {{{ */
if (zend_hash_num_elements(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]) == 1) {
PHPDBG_G(flags) &= PHPDBG_HAS_OPLINE_BP;
}
- zend_hash_index_del(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], ((phpdbg_breakopline_t*)brake)->opline);
+ zend_hash_index_del(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], ((phpdbg_breakopline_t *) brake)->opline);
}
- switch (zend_hash_get_current_key_ex(
- (*table), &key, &klen, &idx, 0, &position)) {
-
- case HASH_KEY_IS_STRING:
- zend_hash_del((*table), key, klen);
- break;
-
- default:
- zend_hash_index_del((*table), idx);
+ if (strkey) {
+ zend_hash_del(table, strkey);
+ } else {
+ zend_hash_index_del(table, numkey);
}
switch (type) {
case PHPDBG_BREAK_FILE:
case PHPDBG_BREAK_METHOD:
if (name) {
- zend_hash_del(&PHPDBG_G(bp)[type], name, name_len);
+ zend_hash_str_del(&PHPDBG_G(bp)[type], name, name_len);
efree(name);
}
break;
@@ -1307,26 +1214,25 @@ PHPDBG_API void phpdbg_disable_breakpoints(TSRMLS_D) { /* {{{ */
PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase(zend_ulong id TSRMLS_DC) /* {{{ */
{
- HashTable **table;
- HashPosition position;
+ HashTable *table;
+ zend_string *strkey;
+ zend_ulong numkey;
- return phpdbg_find_breakbase_ex(id, &table, &position TSRMLS_CC);
+ return phpdbg_find_breakbase_ex(id, &table, &numkey, &strkey TSRMLS_CC);
} /* }}} */
-PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable ***table, HashPosition *position TSRMLS_DC) /* {{{ */
+PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable **table, zend_ulong *numkey, zend_string **strkey TSRMLS_DC) /* {{{ */
{
- if (zend_hash_index_find(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], id, (void**)table) == SUCCESS) {
+ if ((*table = zend_hash_index_find_ptr(&PHPDBG_G(bp)[PHPDBG_BREAK_MAP], id))) {
phpdbg_breakbase_t *brake;
- for (zend_hash_internal_pointer_reset_ex((**table), position);
- zend_hash_get_current_data_ex((**table), (void**)&brake, position) == SUCCESS;
- zend_hash_move_forward_ex((**table), position)) {
-
+ ZEND_HASH_FOREACH_KEY_PTR(*table, *numkey, *strkey, brake) {
if (brake->id == id) {
return brake;
}
- }
+ } ZEND_HASH_FOREACH_END();
}
+
return NULL;
} /* }}} */
@@ -1336,259 +1242,182 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */
switch (type) {
case PHPDBG_BREAK_SYM: if ((PHPDBG_G(flags) & PHPDBG_HAS_SYM_BP)) {
- HashPosition position;
phpdbg_breaksymbol_t *brake;
phpdbg_out(SEPARATE "\n");
phpdbg_out("Function Breakpoints:\n");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], &position);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], (void**) &brake, &position) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], &position)) {
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], brake) {
phpdbg_writeln("function", "id=\"%d\" name=\"%s\" disabled=\"%s\"", "#%d\t\t%s%s",
brake->id, brake->symbol,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
+ } ZEND_HASH_FOREACH_END();
} break;
case PHPDBG_BREAK_METHOD: if ((PHPDBG_G(flags) & PHPDBG_HAS_METHOD_BP)) {
- HashPosition position[2];
HashTable *class_table;
- char *class_name = NULL;
- zend_uint class_len = 0;
- zend_ulong class_idx = 0L;
phpdbg_out(SEPARATE "\n");
phpdbg_out("Method Breakpoints:\n");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], (void**) &class_table, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], &position[0])) {
-
- if (zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD],
- &class_name, &class_len, &class_idx, 0, &position[0]) == HASH_KEY_IS_STRING) {
- phpdbg_breakmethod_t *brake;
-
- for (zend_hash_internal_pointer_reset_ex(class_table, &position[1]);
- zend_hash_get_current_data_ex(class_table, (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex(class_table, &position[1])) {
- phpdbg_writeln("method", "id=\"%d\" name=\"%s::%s\" disabled=\"%s\"", "#%d\t\t%s::%s%s",
- brake->id, brake->class_name, brake->func_name,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
- }
-
- }
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], class_table) {
+ phpdbg_breakmethod_t *brake;
+
+ ZEND_HASH_FOREACH_PTR(class_table, brake) {
+ phpdbg_writeln("method", "id=\"%d\" name=\"%s::%s\" disabled=\"%s\"", "#%d\t\t%s::%s%s",
+ brake->id, brake->class_name, brake->func_name,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
+ } ZEND_HASH_FOREACH_END();
+ } ZEND_HASH_FOREACH_END();
} break;
case PHPDBG_BREAK_FILE: if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_BP)) {
- HashPosition position[2];
HashTable *points;
phpdbg_out(SEPARATE "\n");
phpdbg_out("File Breakpoints:\n");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], (void**) &points, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], &position[0])) {
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], points) {
phpdbg_breakfile_t *brake;
- for (zend_hash_internal_pointer_reset_ex(points, &position[1]);
- zend_hash_get_current_data_ex(points, (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex(points, &position[1])) {
+ ZEND_HASH_FOREACH_PTR(points, brake) {
phpdbg_writeln("file", "id=\"%d\" name=\"%s\" line=\"%lu\" disabled=\"%s\"", "#%d\t\t%s:%lu%s",
brake->id, brake->filename, brake->line,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
- }
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
+ } ZEND_HASH_FOREACH_END();
+ } ZEND_HASH_FOREACH_END();
} break;
case PHPDBG_BREAK_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_OPLINE_BP)) {
- HashPosition position;
phpdbg_breakline_t *brake;
phpdbg_out(SEPARATE "\n");
phpdbg_out("Opline Breakpoints:\n");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], (void**) &brake, &position) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], &position)) {
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], brake) {
+ const char *type;
switch (brake->type) {
case PHPDBG_BREAK_METHOD_OPLINE:
+ type = "method";
+ goto print_opline;
case PHPDBG_BREAK_FUNCTION_OPLINE:
+ type = "function";
+ goto print_opline;
case PHPDBG_BREAK_FILE_OPLINE:
- phpdbg_writeln("opline", "id=\"%d\" num=\"%#lx\" type=\"%s\" disabled=\"%s\"", "#%d\t\t%#lx\t\t(%s breakpoint)%s", brake->id, brake->opline,
- brake->type == PHPDBG_BREAK_METHOD_OPLINE ? "method" :
- brake->type == PHPDBG_BREAK_FUNCTION_OPLINE ? "function" :
- brake->type == PHPDBG_BREAK_FILE_OPLINE ? "file" :
- "--- error ---",
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- break;
+ type = "method";
+
+ print_opline: {
+ if (brake->type == PHPDBG_BREAK_METHOD_OPLINE) {
+ type = "method";
+ } else if (brake->type == PHPDBG_BREAK_FUNCTION_OPLINE) {
+ type = "function";
+ } else if (brake->type == PHPDBG_BREAK_FILE_OPLINE) {
+ type = "file";
+ }
+
+ phpdbg_writeln("opline", "id=\"%d\" num=\"%#lx\" type=\"%s\" disabled=\"%s\"", "#%d\t\t%#lx\t\t(%s breakpoint)%s",
+ brake->id, brake->opline, type,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
+ } break;
default:
- phpdbg_writeln("opline", "id=\"%d\" num=\"%#lx\" disabled=\"%s\"", "#%d\t\t%#lx%s", brake->id, brake->opline, ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
+ phpdbg_writeln("opline", "id=\"%d\" num=\"%#lx\" disabled=\"%s\"", "#%d\t\t%#lx%s",
+ brake->id, brake->opline,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
break;
}
- }
+ } ZEND_HASH_FOREACH_END();
} break;
case PHPDBG_BREAK_METHOD_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_METHOD_OPLINE_BP)) {
- HashPosition position[3];
HashTable *class_table, *method_table;
- char *class_name = NULL, *method_name = NULL;
- zend_uint class_len = 0, method_len = 0;
- zend_ulong class_idx = 0L, method_idx = 0L;
phpdbg_out(SEPARATE "\n");
phpdbg_out("Method opline Breakpoints:\n");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], (void**) &class_table, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], &position[0])) {
-
- if (zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE],
- &class_name, &class_len, &class_idx, 0, &position[0]) == HASH_KEY_IS_STRING) {
-
- for (zend_hash_internal_pointer_reset_ex(class_table, &position[1]);
- zend_hash_get_current_data_ex(class_table, (void**) &method_table, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex(class_table, &position[1])) {
-
- if (zend_hash_get_current_key_ex(class_table,
- &method_name, &method_len, &method_idx, 0, &position[0]) == HASH_KEY_IS_STRING) {
-
- phpdbg_breakopline_t *brake;
-
- for (zend_hash_internal_pointer_reset_ex(method_table, &position[2]);
- zend_hash_get_current_data_ex(method_table, (void**)&brake, &position[2]) == SUCCESS;
- zend_hash_move_forward_ex(method_table, &position[2])) {
- phpdbg_writeln("methodopline", "id=\"%d\" name=\"%s::%s\" num=\"%ld\" disabled=\"%s\"", "#%d\t\t%s::%s opline %ld%s",
- brake->id, brake->class_name, brake->func_name, brake->opline_num,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
- }
- }
- }
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE], class_table) {
+ ZEND_HASH_FOREACH_PTR(class_table, method_table) {
+ phpdbg_breakopline_t *brake;
- }
+ ZEND_HASH_FOREACH_PTR(method_table, brake) {
+ phpdbg_writeln("methodopline", "id=\"%d\" name=\"%s::%s\" num=\"%ld\" disabled=\"%s\"", "#%d\t\t%s::%s opline %ld%s",
+ brake->id, brake->class_name, brake->func_name, brake->opline_num,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
+ } ZEND_HASH_FOREACH_END();
+ } ZEND_HASH_FOREACH_END();
+ } ZEND_HASH_FOREACH_END();
} break;
case PHPDBG_BREAK_FUNCTION_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_FUNCTION_OPLINE_BP)) {
- HashPosition position[2];
HashTable *function_table;
- char *function_name = NULL;
- zend_uint function_len = 0;
- zend_ulong function_idx = 0L;
phpdbg_out(SEPARATE "\n");
phpdbg_out("Function opline Breakpoints:\n");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], (void**) &function_table, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], &position[0])) {
-
- if (zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE],
- &function_name, &function_len, &function_idx, 0, &position[0]) == HASH_KEY_IS_STRING) {
-
- phpdbg_breakopline_t *brake;
-
- for (zend_hash_internal_pointer_reset_ex(function_table, &position[1]);
- zend_hash_get_current_data_ex(function_table, (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex(function_table, &position[1])) {
- phpdbg_writeln("functionopline", "id=\"%d\" name=\"%s\" num=\"%ld\" disabled=\"%s\"", "#%d\t\t%s opline %ld%s",
- brake->id, brake->func_name, brake->opline_num,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
- }
-
- }
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE], function_table) {
+ phpdbg_breakopline_t *brake;
+
+ ZEND_HASH_FOREACH_PTR(function_table, brake) {
+ phpdbg_writeln("functionopline", "id=\"%d\" name=\"%s\" num=\"%ld\" disabled=\"%s\"", "#%d\t\t%s opline %ld%s",
+ brake->id, brake->func_name, brake->opline_num,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
+ } ZEND_HASH_FOREACH_END();
+ } ZEND_HASH_FOREACH_END();
} break;
case PHPDBG_BREAK_FILE_OPLINE: if ((PHPDBG_G(flags) & PHPDBG_HAS_FILE_OPLINE_BP)) {
- HashPosition position[2];
HashTable *file_table;
- char *file_name = NULL;
- zend_uint file_len = 0;
- zend_ulong file_idx = 0L;
phpdbg_out(SEPARATE "\n");
phpdbg_out("File opline Breakpoints:\n");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], &position[0]);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], (void**) &file_table, &position[0]) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], &position[0])) {
-
- if (zend_hash_get_current_key_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE],
- &file_name, &file_len, &file_idx, 0, &position[0]) == HASH_KEY_IS_STRING) {
-
- phpdbg_breakopline_t *brake;
-
- for (zend_hash_internal_pointer_reset_ex(file_table, &position[1]);
- zend_hash_get_current_data_ex(file_table, (void**)&brake, &position[1]) == SUCCESS;
- zend_hash_move_forward_ex(file_table, &position[1])) {
- phpdbg_writeln("fileopline", "id=\"%d\" name=\"%s\" num=\"%ld\" disabled=\"%s\"", "#%d\t\t%s opline %ld%s",
- brake->id, brake->class_name, brake->opline_num,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
- }
- }
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_OPLINE], file_table) {
+ phpdbg_breakopline_t *brake;
+
+ ZEND_HASH_FOREACH_PTR(file_table, brake) {
+ phpdbg_writeln("fileopline", "id=\"%d\" name=\"%s\" num=\"%ld\" disabled=\"%s\"", "#%d\t\t%s opline %ld%s",
+ brake->id, brake->class_name, brake->opline_num,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
+ } ZEND_HASH_FOREACH_END();
+ } ZEND_HASH_FOREACH_END();
} break;
case PHPDBG_BREAK_COND: if ((PHPDBG_G(flags) & PHPDBG_HAS_COND_BP)) {
- HashPosition position;
phpdbg_breakcond_t *brake;
phpdbg_out(SEPARATE "\n");
phpdbg_out("Conditional Breakpoints:\n");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], (void**) &brake, &position) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], &position)) {
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], brake) {
if (brake->paramed) {
switch (brake->param.type) {
case STR_PARAM:
phpdbg_writeln("evalfunction", "id=\"%d\" name=\"%s\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s if %s%s",
- brake->id,
- brake->param.str,
- brake->code,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
+ brake->id, brake->param.str, brake->code,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
break;
case NUMERIC_FUNCTION_PARAM:
phpdbg_writeln("evalfunctionopline", "id=\"%d\" name=\"%s\" num=\"%ld\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s#%ld if %s%s",
- brake->id,
- brake->param.str,
- brake->param.num,
- brake->code,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
+ brake->id, brake->param.str, brake->param.num, brake->code,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
break;
case METHOD_PARAM:
phpdbg_writeln("evalmethod", "id=\"%d\" name=\"%s::%s\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s::%s if %s%s",
- brake->id,
- brake->param.method.class,
- brake->param.method.name,
- brake->code,
+ brake->id, brake->param.method.class, brake->param.method.name, brake->code,
((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
break;
case NUMERIC_METHOD_PARAM:
phpdbg_writeln("evalmethodopline", "id=\"%d\" name=\"%s::%s\" num=\"%d\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s::%s#%ld if %s%s",
- brake->id,
- brake->param.method.class,
- brake->param.method.name,
- brake->param.num,
- brake->code,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
+ brake->id, brake->param.method.class, brake->param.method.name, brake->param.num, brake->code,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
break;
case FILE_PARAM:
phpdbg_writeln("evalfile", "id=\"%d\" name=\"%s\" line=\"%d\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat %s:%lu if %s%s",
- brake->id,
- brake->param.file.name,
- brake->param.file.line,
- brake->code,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
+ brake->id, brake->param.file.name, brake->param.file.line, brake->code,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
break;
case ADDR_PARAM:
phpdbg_writeln("evalopline", "id=\"%d\" opline=\"%#lx\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tat #%lx if %s%s",
- brake->id,
- brake->param.addr,
- brake->code,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
+ brake->id, brake->param.addr, brake->code,
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
break;
default:
@@ -1598,24 +1427,21 @@ PHPDBG_API void phpdbg_print_breakpoints(zend_ulong type TSRMLS_DC) /* {{{ */
} else {
phpdbg_writeln("eval", "id=\"%d\" eval=\"%s\" disabled=\"%s\"", "#%d\t\tif %s%s",
brake->id, brake->code,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
}
- }
+ } ZEND_HASH_FOREACH_END();
} break;
case PHPDBG_BREAK_OPCODE: if (PHPDBG_G(flags) & PHPDBG_HAS_OPCODE_BP) {
- HashPosition position;
phpdbg_breakop_t *brake;
phpdbg_out(SEPARATE "\n");
phpdbg_out("Opcode Breakpoints:\n");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], &position);
- zend_hash_get_current_data_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], (void**) &brake, &position) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], &position)) {
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(bp)[PHPDBG_BREAK_OPCODE], brake) {
phpdbg_writeln("opcode", "id=\"%d\" name=\"%s\" disabled=\"%s\"", "#%d\t\t%s%s",
brake->id, brake->name,
- ((phpdbg_breakbase_t*)brake)->disabled ? " [disabled]" : "");
- }
+ ((phpdbg_breakbase_t *) brake)->disabled ? " [disabled]" : "");
+ } ZEND_HASH_FOREACH_END();
} break;
}
diff --git a/sapi/phpdbg/phpdbg_bp.h b/sapi/phpdbg/phpdbg_bp.h
index a6227cba6c..4090d90f91 100644
--- a/sapi/phpdbg/phpdbg_bp.h
+++ b/sapi/phpdbg/phpdbg_bp.h
@@ -151,7 +151,7 @@ PHPDBG_API void phpdbg_disable_breakpoints(TSRMLS_D); /* }}} */
/* {{{ Breakbase API */
PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase(zend_ulong id TSRMLS_DC);
-PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable ***table, HashPosition *position TSRMLS_DC); /* }}} */
+PHPDBG_API phpdbg_breakbase_t *phpdbg_find_breakbase_ex(zend_ulong id, HashTable **table, zend_ulong *numkey, zend_string **strkey TSRMLS_DC); /* }}} */
/* {{{ Breakpoint Exportation API */
PHPDBG_API void phpdbg_export_breakpoints(FILE *handle TSRMLS_DC); /* }}} */
diff --git a/sapi/phpdbg/phpdbg_btree.c b/sapi/phpdbg/phpdbg_btree.c
index 491445399b..918bc0d68f 100644
--- a/sapi/phpdbg/phpdbg_btree.c
+++ b/sapi/phpdbg/phpdbg_btree.c
@@ -219,3 +219,18 @@ check_branch_existence:
return SUCCESS;
}
+
+void phpdbg_btree_branch_dump(phpdbg_btree_branch *branch, zend_ulong depth) {
+ if (branch) {
+ if (depth--) {
+ phpdbg_btree_branch_dump(branch->branches[0], depth);
+ phpdbg_btree_branch_dump(branch->branches[1], depth);
+ } else {
+ fprintf(stderr, "%p: %p\n", (void *) branch->result.idx, branch->result.ptr);
+ }
+ }
+}
+
+void phpdbg_btree_dump(phpdbg_btree *tree) {
+ phpdbg_btree_branch_dump(tree->branch, tree->depth);
+}
diff --git a/sapi/phpdbg/phpdbg_btree.h b/sapi/phpdbg/phpdbg_btree.h
index af2a6ac314..27230572f7 100644
--- a/sapi/phpdbg/phpdbg_btree.h
+++ b/sapi/phpdbg/phpdbg_btree.h
@@ -62,4 +62,9 @@ int phpdbg_btree_insert_or_update(phpdbg_btree *tree, zend_ulong idx, void *ptr,
#define phpdbg_btree_update(tree, idx, ptr) phpdbg_btree_insert_or_update(tree, idx, ptr, PHPDBG_BTREE_UPDATE)
#define phpdbg_btree_overwrite(tree, idx, ptr) phpdbg_btree_insert_or_update(tree, idx, ptr, PHPDBG_BTREE_OWERWRITE)
+
+/* debugging functions */
+void phpdbg_btree_branch_dump(phpdbg_btree_branch *branch, zend_ulong depth);
+void phpdbg_btree_dump(phpdbg_btree *tree);
+
#endif
diff --git a/sapi/phpdbg/phpdbg_cmd.c b/sapi/phpdbg/phpdbg_cmd.c
index 30ea48cfbe..729babefca 100644
--- a/sapi/phpdbg/phpdbg_cmd.c
+++ b/sapi/phpdbg/phpdbg_cmd.c
@@ -168,59 +168,39 @@ PHPDBG_API char* phpdbg_param_tostring(const phpdbg_param_t *param, char **point
{
switch (param->type) {
case STR_PARAM:
- asprintf(pointer,
- "%s", param->str);
+ asprintf(pointer, "%s", param->str);
break;
case ADDR_PARAM:
- asprintf(pointer,
- "%#lx", param->addr);
+ asprintf(pointer, "%#llx", param->addr);
break;
case NUMERIC_PARAM:
- asprintf(pointer,
- "%li",
- param->num);
+ asprintf(pointer, "%li", param->num);
break;
case METHOD_PARAM:
- asprintf(pointer,
- "%s::%s",
- param->method.class,
- param->method.name);
+ asprintf(pointer, "%s::%s", param->method.class, param->method.name);
break;
case FILE_PARAM:
if (param->num) {
- asprintf(pointer,
- "%s:%lu#%lu",
- param->file.name,
- param->file.line,
- param->num);
+ asprintf(pointer, "%s:%lu#%lu", param->file.name, param->file.line, param->num);
} else {
- asprintf(pointer,
- "%s:%lu",
- param->file.name,
- param->file.line);
+ asprintf(pointer, "%s:%lu", param->file.name, param->file.line);
}
break;
case NUMERIC_FUNCTION_PARAM:
- asprintf(pointer,
- "%s#%lu", param->str, param->num);
+ asprintf(pointer, "%s#%lu", param->str, param->num);
break;
case NUMERIC_METHOD_PARAM:
- asprintf(pointer,
- "%s::%s#%lu",
- param->method.class,
- param->method.name,
- param->num);
+ asprintf(pointer, "%s::%s#%lu", param->method.class, param->method.name, param->num);
break;
default:
- asprintf(pointer,
- "%s", "unknown");
+ *pointer = strdup("unknown");
}
return *pointer;
@@ -422,7 +402,7 @@ PHPDBG_API void phpdbg_param_debug(const phpdbg_param_t *param, const char *msg)
break;
case ADDR_PARAM:
- fprintf(stderr, "%s ADDR_PARAM(%lu)\n", msg, param->addr);
+ fprintf(stderr, "%s ADDR_PARAM(%llu)\n", msg, param->addr);
break;
case NUMERIC_FILE_PARAM:
@@ -692,7 +672,7 @@ PHPDBG_API const phpdbg_command_t *phpdbg_stack_resolve(const phpdbg_command_t *
default: {
char *list = NULL;
- zend_uint it = 0;
+ uint32_t it = 0;
size_t pos = 0;
while (it < matches) {
diff --git a/sapi/phpdbg/phpdbg_frame.c b/sapi/phpdbg/phpdbg_frame.c
index df304e3541..4429a7fb73 100644
--- a/sapi/phpdbg/phpdbg_frame.c
+++ b/sapi/phpdbg/phpdbg_frame.c
@@ -37,13 +37,7 @@ void phpdbg_restore_frame(TSRMLS_D) /* {{{ */
/* move things back */
EG(current_execute_data) = PHPDBG_FRAME(execute_data);
- EG(opline_ptr) = &PHPDBG_EX(opline);
- EG(active_op_array) = PHPDBG_EX(op_array);
- EG(return_value_ptr_ptr) = PHPDBG_EX(original_return_value);
- EG(active_symbol_table) = PHPDBG_EX(symbol_table);
- EG(This) = PHPDBG_EX(current_this);
- EG(scope) = PHPDBG_EX(current_scope);
- EG(called_scope) = PHPDBG_EX(current_called_scope);
+ EG(scope) = PHPDBG_EX(scope);
} /* }}} */
void phpdbg_switch_frame(int frame TSRMLS_DC) /* {{{ */
@@ -85,89 +79,72 @@ void phpdbg_switch_frame(int frame TSRMLS_DC) /* {{{ */
PHPDBG_FRAME(execute_data) = EG(current_execute_data);
EG(current_execute_data) = execute_data;
- EG(opline_ptr) = &PHPDBG_EX(opline);
- EG(active_op_array) = PHPDBG_EX(op_array);
- PHPDBG_FRAME(execute_data)->original_return_value = EG(return_value_ptr_ptr);
- EG(return_value_ptr_ptr) = PHPDBG_EX(original_return_value);
- EG(active_symbol_table) = PHPDBG_EX(symbol_table);
- EG(This) = PHPDBG_EX(current_this);
- EG(scope) = PHPDBG_EX(current_scope);
- EG(called_scope) = PHPDBG_EX(current_called_scope);
+ EG(scope) = PHPDBG_EX(scope);
}
phpdbg_notice("frame", "id=\"%d\"", "Switched to frame #%d", frame);
- phpdbg_list_file(
- zend_get_executed_filename(TSRMLS_C),
- 3,
- zend_get_executed_lineno(TSRMLS_C)-1,
- zend_get_executed_lineno(TSRMLS_C)
- TSRMLS_CC
- );
+
+ {
+ const char *file_chr = zend_get_executed_filename(TSRMLS_C);
+ zend_string *file = zend_string_init(file_chr, strlen(file_chr), 0);
+ phpdbg_list_file(file, 3, zend_get_executed_lineno(TSRMLS_C) - 1, zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC);
+ efree(file);
+ }
} /* }}} */
-static void phpdbg_dump_prototype(zval **tmp TSRMLS_DC) /* {{{ */
+static void phpdbg_dump_prototype(zval *tmp TSRMLS_DC) /* {{{ */
{
- zval **funcname, **class, **type, **args, **argstmp;
- char is_class;
- int has_args = FAILURE;
+ zval *funcname, *class, class_zv, *type, *args, *argstmp;
- zend_hash_find(Z_ARRVAL_PP(tmp), "function", sizeof("function"), (void **) &funcname);
+ funcname = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("function"));
- if ((is_class = zend_hash_find(Z_ARRVAL_PP(tmp), "object", sizeof("object"), (void **) &class)) == FAILURE) {
- is_class = zend_hash_find(Z_ARRVAL_PP(tmp), "class", sizeof("class"), (void **)&class);
+ if ((class = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("object")))) {
+ ZVAL_NEW_STR(&class_zv, Z_OBJCE_P(class)->name);
+ class = &class_zv;
} else {
- zend_get_object_classname(*class, (const char **) &Z_STRVAL_PP(class), (zend_uint *) &Z_STRLEN_PP(class) TSRMLS_CC);
+ class = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("class"));
}
- if (is_class == SUCCESS) {
- zend_hash_find(Z_ARRVAL_PP(tmp), "type", sizeof("type"), (void **)&type);
+ if (class) {
+ type = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("type"));
}
- has_args = zend_hash_find(Z_ARRVAL_PP(tmp), "args", sizeof("args"), (void **)&args) == SUCCESS;
+ args = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("args"));
+
+ phpdbg_xml(" symbol=\"%s%s%s\"", class ? Z_STRVAL_P(class) : "", class ? Z_STRVAL_P(type) : "", Z_STRVAL_P(funcname));
- phpdbg_xml(" symbol=\"%s%s%s\"",
- is_class == FAILURE?"":Z_STRVAL_PP(class),
- is_class == FAILURE?"":Z_STRVAL_PP(type),
- Z_STRVAL_PP(funcname)
- );
- if (has_args) {
+ if (args) {
phpdbg_xml(">");
} else {
phpdbg_xml(" />");
}
- phpdbg_out("%s%s%s(",
- is_class == FAILURE?"":Z_STRVAL_PP(class),
- is_class == FAILURE?"":Z_STRVAL_PP(type),
- Z_STRVAL_PP(funcname)
- );
+ phpdbg_out("%s%s%s(", class ? Z_STRVAL_P(class) : "", class ? Z_STRVAL_P(type) : "", Z_STRVAL_P(funcname));
- if (has_args) {
- HashPosition iterator;
+ if (args) {
const zend_function *func = NULL;
const zend_arg_info *arginfo = NULL;
- int j = 0, m;
zend_bool is_variadic = 0;
+ int j = 0, m;
phpdbg_try_access {
/* assuming no autoloader call is necessary, class should have been loaded if it's in backtrace ... */
- if ((func = phpdbg_get_function(Z_STRVAL_PP(funcname), is_class == FAILURE ? NULL : Z_STRVAL_PP(class) TSRMLS_CC))) {
+ if ((func = phpdbg_get_function(Z_STRVAL_P(funcname), class ? Z_STRVAL_P(class) : NULL TSRMLS_CC))) {
arginfo = func->common.arg_info;
}
} phpdbg_end_try_access();
m = func ? func->common.num_args : 0;
- zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(args), &iterator);
- while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(args), (void **) &argstmp, &iterator) == SUCCESS) {
+ ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args), argstmp) {
if (j) {
phpdbg_out(", ");
}
phpdbg_xml("<arg %r");
if (m && j < m) {
-#if PHP_VERSION_ID >= 50600
- is_variadic = arginfo ? arginfo[j].is_variadic : 0;
-#endif
+ if (!is_variadic) {
+ is_variadic = arginfo ? arginfo[j].is_variadic : 0;
+ }
phpdbg_xml(" variadic=\"%s\" name=\"%s\">", is_variadic ? "variadic" : "", arginfo ? arginfo[j].name : "");
phpdbg_out("%s=%s", arginfo ? arginfo[j].name : "?", is_variadic ? "[": "");
@@ -176,11 +153,11 @@ static void phpdbg_dump_prototype(zval **tmp TSRMLS_DC) /* {{{ */
}
++j;
- zend_print_flat_zval_r(*argstmp TSRMLS_CC);
- zend_hash_move_forward_ex(Z_ARRVAL_PP(args), &iterator);
+ zend_print_flat_zval_r(argstmp TSRMLS_CC);
phpdbg_xml("</arg>");
- }
+ } ZEND_HASH_FOREACH_END();
+
if (is_variadic) {
phpdbg_out("]");
}
@@ -191,12 +168,11 @@ static void phpdbg_dump_prototype(zval **tmp TSRMLS_DC) /* {{{ */
void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */
{
- zval zbacktrace;
- zval **tmp;
- zval **file, **line;
HashPosition position;
+ zval zbacktrace;
+ zval *tmp;
+ zval *file, *line;
int i = 0, limit = num;
- int user_defined;
if (limit < 0) {
phpdbg_error("backtrace", "type=\"minnum\"", "Invalid backtrace size %d", limit);
@@ -213,22 +189,22 @@ void phpdbg_dump_backtrace(size_t num TSRMLS_DC) /* {{{ */
phpdbg_xml("<backtrace %r>");
zend_hash_internal_pointer_reset_ex(Z_ARRVAL(zbacktrace), &position);
- zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), (void **) &tmp, &position);
+ tmp = zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), &position);
while (1) {
- user_defined = zend_hash_find(Z_ARRVAL_PP(tmp), "file", sizeof("file"), (void **) &file);
- zend_hash_find(Z_ARRVAL_PP(tmp), "line", sizeof("line"), (void **) &line);
+ file = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("file"));
+ line = zend_hash_str_find(Z_ARRVAL_P(tmp), ZEND_STRL("line"));
zend_hash_move_forward_ex(Z_ARRVAL(zbacktrace), &position);
- if (zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), (void **) &tmp, &position) == FAILURE) {
- phpdbg_write("frame", "id=\"%d\" symbol=\"{main}\" file=\"%s\" line=\"%d\"", "frame #%d: {main} at %s:%ld", i, Z_STRVAL_PP(file), Z_LVAL_PP(line));
+ if (!(tmp = zend_hash_get_current_data_ex(Z_ARRVAL(zbacktrace), &position))) {
+ phpdbg_write("frame", "id=\"%d\" symbol=\"{main}\" file=\"%s\" line=\"%d\"", "frame #%d: {main} at %s:%ld", i, Z_STRVAL_P(file), Z_LVAL_P(line));
break;
}
- if (user_defined == SUCCESS) {
+ if (file) { /* userland */
phpdbg_out("frame #%d: ", i);
- phpdbg_xml("<frame %r id=\"%d\" file=\"%s\" line=\"%d\"", i, Z_STRVAL_PP(file), Z_LVAL_PP(line));
+ phpdbg_xml("<frame %r id=\"%d\" file=\"%s\" line=\"%d\"", i, Z_STRVAL_P(file), Z_LVAL_P(line));
phpdbg_dump_prototype(tmp TSRMLS_CC);
- phpdbg_out(" at %s:%ld\n", Z_STRVAL_PP(file), Z_LVAL_PP(line));
+ phpdbg_out(" at %s:%ld\n", Z_STRVAL_P(file), Z_LVAL_P(line));
i++;
} else {
phpdbg_out(" => ");
diff --git a/sapi/phpdbg/phpdbg_info.c b/sapi/phpdbg/phpdbg_info.c
index 4774fa5a9e..01633e4feb 100644
--- a/sapi/phpdbg/phpdbg_info.c
+++ b/sapi/phpdbg/phpdbg_info.c
@@ -61,21 +61,19 @@ PHPDBG_INFO(break) /* {{{ */
PHPDBG_INFO(files) /* {{{ */
{
- HashPosition pos;
- char *fname;
+ zend_string *fname;
phpdbg_try_access {
phpdbg_notice("includedfilecount", "num=\"%d\"", "Included files: %d", zend_hash_num_elements(&EG(included_files)));
} phpdbg_catch_access {
phpdbg_error("signalsegv", "", "Could not fetch included file count, invalid data source");
+ return SUCCESS;
} phpdbg_end_try_access();
phpdbg_try_access {
- zend_hash_internal_pointer_reset_ex(&EG(included_files), &pos);
- while (zend_hash_get_current_key_ex(&EG(included_files), &fname, NULL, NULL, 0, &pos) == HASH_KEY_IS_STRING) {
+ ZEND_HASH_FOREACH_STR_KEY(&EG(included_files), fname) {
phpdbg_writeln("includedfile", "name=\"%s\"", "File: %s", fname);
- zend_hash_move_forward_ex(&EG(included_files), &pos);
- }
+ } ZEND_HASH_FOREACH_END();
} phpdbg_catch_access {
phpdbg_error("signalsegv", "", "Could not fetch file name, invalid data source, aborting included file listing");
} phpdbg_end_try_access();
@@ -99,7 +97,6 @@ PHPDBG_INFO(error) /* {{{ */
PHPDBG_INFO(constants) /* {{{ */
{
- HashPosition pos;
HashTable consts;
zend_constant *data;
@@ -107,13 +104,11 @@ PHPDBG_INFO(constants) /* {{{ */
if (EG(zend_constants)) {
phpdbg_try_access {
- zend_hash_internal_pointer_reset_ex(EG(zend_constants), &pos);
- while (zend_hash_get_current_data_ex(EG(zend_constants), (void **) &data, &pos) == SUCCESS) {
+ ZEND_HASH_FOREACH_PTR(EG(zend_constants), data) {
if (data->module_number == PHP_USER_CONSTANT) {
- zend_hash_update(&consts, data->name, data->name_len, (void **) &data, sizeof(zend_constant *), NULL);
+ zend_hash_update_ptr(&consts, data->name, data);
}
- zend_hash_move_forward_ex(EG(zend_constants), &pos);
- }
+ } ZEND_HASH_FOREACH_END();
} phpdbg_catch_access {
phpdbg_error("signalsegv", "", "Cannot fetch all the constants, invalid data source");
} phpdbg_end_try_access();
@@ -123,12 +118,9 @@ PHPDBG_INFO(constants) /* {{{ */
if (zend_hash_num_elements(&consts)) {
phpdbg_out("Address Refs Type Constant\n");
- for (zend_hash_internal_pointer_reset_ex(&consts, &pos);
- zend_hash_get_current_data_ex(&consts, (void **) &data, &pos) == SUCCESS;
- zend_hash_move_forward_ex(&consts, &pos)) {
- data = *(zend_constant **) data;
+ ZEND_HASH_FOREACH_PTR(&consts, data) {
-#define VARIABLEINFO(attrs, msg, ...) phpdbg_writeln("constant", "address=\"%p\" refcount=\"%d\" type=\"%s\" name=\"%.*s\" " attrs, "%-18p %-7d %-9s %.*s" msg, &data->value, Z_REFCOUNT(data->value), zend_zval_type_name(&data->value), data->name_len - 1, data->name, ##__VA_ARGS__)
+#define VARIABLEINFO(attrs, msg, ...) phpdbg_writeln("constant", "address=\"%p\" refcount=\"%d\" type=\"%s\" name=\"%.*s\" " attrs, "%-18p %-7d %-9s %.*s" msg, &data->value, Z_REFCOUNT(data->value), zend_zval_type_name(&data->value), data->name->len, data->name->val, ##__VA_ARGS__)
switch (Z_TYPE(data->value)) {
case IS_STRING:
@@ -138,8 +130,11 @@ PHPDBG_INFO(constants) /* {{{ */
VARIABLEINFO("", "");
} phpdbg_end_try_access();
break;
- case IS_BOOL:
- VARIABLEINFO("value=\"%s\"", "\nbool (%s)", Z_LVAL(data->value) ? "true" : "false");
+ case IS_TRUE:
+ VARIABLEINFO("value=\"true\"", "\nbool (true)");
+ break;
+ case IS_FALSE:
+ VARIABLEINFO("value=\"false\"", "\nbool (false)");
break;
case IS_LONG:
VARIABLEINFO("value=\"%ld\"", "\nint (%ld)", Z_LVAL(data->value));
@@ -152,7 +147,7 @@ PHPDBG_INFO(constants) /* {{{ */
#undef VARIABLEINFO
}
- }
+ } ZEND_HASH_FOREACH_END();
}
return SUCCESS;
@@ -161,9 +156,9 @@ PHPDBG_INFO(constants) /* {{{ */
static int phpdbg_arm_auto_global(zend_auto_global *auto_global TSRMLS_DC) {
if (auto_global->armed) {
if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) {
- phpdbg_notice("variableinfo", "unreachable=\"%.*s\"", "Cannot show information about superglobal variable %.*s", auto_global->name_len, auto_global->name);
+ phpdbg_notice("variableinfo", "unreachable=\"%.*s\"", "Cannot show information about superglobal variable %.*s", auto_global->name->len, auto_global->name->val);
} else {
- auto_global->armed = auto_global->auto_global_callback(auto_global->name, auto_global->name_len TSRMLS_CC);
+ auto_global->armed = auto_global->auto_global_callback(auto_global->name TSRMLS_CC);
}
}
@@ -171,45 +166,33 @@ static int phpdbg_arm_auto_global(zend_auto_global *auto_global TSRMLS_DC) {
}
static int phpdbg_print_symbols(zend_bool show_globals TSRMLS_DC) {
- HashTable vars, *symtable;
- HashPosition pos;
- char *var;
- zval **data;
+ HashTable vars;
+ zend_array *symtable;
+ zend_string *var;
+ zval *data;
- if (!EG(active_op_array)) {
+ if (!EG(current_execute_data) || !EG(current_execute_data)->func) {
phpdbg_error("inactive", "type=\"op_array\"", "No active op array!");
return SUCCESS;
}
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
-
- if (!EG(active_symbol_table)) {
- phpdbg_error("inactive", "type=\"symbol_table\"", "No active symbol table!");
- return SUCCESS;
- }
- }
-
-
if (show_globals) {
/* that array should only be manipulated during init, so safe for async access during execution */
zend_hash_apply(CG(auto_globals), (apply_func_t) phpdbg_arm_auto_global TSRMLS_CC);
symtable = &EG(symbol_table);
- } else {
- symtable = EG(active_symbol_table);
+ } else if (!(symtable = zend_rebuild_symbol_table(TSRMLS_C))) {
+ phpdbg_error("inactive", "type=\"symbol_table\"", "No active symbol table!");
+ return SUCCESS;
}
zend_hash_init(&vars, 8, NULL, NULL, 0);
phpdbg_try_access {
- zend_hash_internal_pointer_reset_ex(symtable, &pos);
- while (zend_hash_get_current_key_ex(symtable, &var, NULL, NULL, 0, &pos) == HASH_KEY_IS_STRING) {
- zend_hash_get_current_data_ex(symtable, (void **)&data, &pos);
- if (zend_is_auto_global(var, strlen(var) TSRMLS_CC) ^ !show_globals) {
- zend_hash_update(&vars, var, strlen(var)+1, (void**)data, sizeof(zval*), NULL);
+ ZEND_HASH_FOREACH_STR_KEY_VAL(&symtable->ht, var, data) {
+ if (zend_is_auto_global(var TSRMLS_CC) ^ !show_globals) {
+ zend_hash_update(&vars, var, data);
}
- zend_hash_move_forward_ex(symtable, &pos);
- }
+ } ZEND_HASH_FOREACH_END();
} phpdbg_catch_access {
phpdbg_error("signalsegv", "", "Cannot fetch all data from the symbol table, invalid data source");
} phpdbg_end_try_access();
@@ -217,7 +200,7 @@ static int phpdbg_print_symbols(zend_bool show_globals TSRMLS_DC) {
if (show_globals) {
phpdbg_notice("variableinfo", "num=\"%d\"", "Superglobal variables (%d)", zend_hash_num_elements(&vars));
} else {
- zend_op_array *ops = EG(active_op_array);
+ zend_op_array *ops = &EG(current_execute_data)->func->op_array;
if (ops->function_name) {
if (ops->scope) {
@@ -227,7 +210,7 @@ static int phpdbg_print_symbols(zend_bool show_globals TSRMLS_DC) {
}
} else {
if (ops->filename) {
- phpdbg_notice("variableinfo", "file=\"%s\" num=\"%d\"", "Variables in %s (%d)", ops->filename, zend_hash_num_elements(&vars));
+ phpdbg_notice("variableinfo", "file=\"%s\" num=\"%d\"", "Variables in %s (%d)", ops->filename->val, zend_hash_num_elements(&vars));
} else {
phpdbg_notice("variableinfo", "opline=\"%p\" num=\"%d\"", "Variables @ %p (%d)", ops, zend_hash_num_elements(&vars));
}
@@ -236,62 +219,54 @@ static int phpdbg_print_symbols(zend_bool show_globals TSRMLS_DC) {
if (zend_hash_num_elements(&vars)) {
phpdbg_out("Address Refs Type Variable\n");
- for (zend_hash_internal_pointer_reset_ex(&vars, &pos);
- zend_hash_get_current_data_ex(&vars, (void**) &data, &pos) == SUCCESS;
- zend_hash_move_forward_ex(&vars, &pos)) {
- char *var;
- zend_bool invalid_data = 1;
-
- zend_hash_get_current_key_ex(&vars, &var, NULL, NULL, 0, &pos);
-
+ ZEND_HASH_FOREACH_STR_KEY_VAL(&vars, var, data) {
phpdbg_try_access {
- if (!(invalid_data = !*data)) {
-#define VARIABLEINFO(attrs, msg, ...) phpdbg_writeln("variable", "address=\"%p\" refcount=\"%d\" type=\"%s\" refstatus=\"%s\" name=\"%s\" " attrs, "%-18p %-7d %-9s %s$%s" msg, *data, Z_REFCOUNT_PP(data), zend_zval_type_name(*data), Z_ISREF_PP(data) ? "&": "", var, ##__VA_ARGS__)
-
- switch (Z_TYPE_PP(data)) {
- case IS_RESOURCE:
- phpdbg_try_access {
- int type;
- VARIABLEINFO("type=\"%s\"", "\n|-------(typeof)------> (%s)\n", zend_list_find(Z_RESVAL_PP(data), &type) ? zend_rsrc_list_get_rsrc_type(type TSRMLS_CC) : "unknown");
- } phpdbg_catch_access {
- VARIABLEINFO("type=\"unknown\"", "\n|-------(typeof)------> (unknown)\n");
- } phpdbg_end_try_access();
- break;
- case IS_OBJECT:
- phpdbg_try_access {
- VARIABLEINFO("instanceof=\"%s\"", "\n|-----(instanceof)----> (%s)\n", Z_OBJCE_PP(data)->name);
- } phpdbg_catch_access {
- VARIABLEINFO("instanceof=\"%s\"", "\n|-----(instanceof)----> (unknown)\n");
- } phpdbg_end_try_access();
- break;
- case IS_STRING:
- phpdbg_try_access {
- VARIABLEINFO("length=\"%d\" value=\"%.*s\"", "\nstring (%d) \"%.*s%s\"", Z_STRLEN_PP(data), Z_STRLEN_PP(data) < 255 ? Z_STRLEN_PP(data) : 255, Z_STRVAL_PP(data), Z_STRLEN_PP(data) > 255 ? "..." : "");
- } phpdbg_catch_access {
- VARIABLEINFO("", "");
- } phpdbg_end_try_access();
- break;
- case IS_BOOL:
- VARIABLEINFO("value=\"%s\"", "\nbool (%s)", Z_LVAL_PP(data) ? "true" : "false");
- break;
- case IS_LONG:
- VARIABLEINFO("value=\"%ld\"", "\nint (%ld)", Z_LVAL_PP(data));
- break;
- case IS_DOUBLE:
- VARIABLEINFO("value=\"%lf\"", "\ndouble (%lf)", Z_DVAL_PP(data));
- break;
- default:
+#define VARIABLEINFO(attrs, msg, ...) phpdbg_writeln("variable", "address=\"%p\" refcount=\"%d\" type=\"%s\" refstatus=\"%s\" name=\"%.*s\" " attrs, "%-18p %-7d %-9s %s$%.*s" msg, data, Z_REFCOUNT_P(data), zend_zval_type_name(data), Z_ISREF_P(data) ? "&": "", var->len, var->val, ##__VA_ARGS__)
+
+ switch (Z_TYPE_P(data)) {
+ case IS_RESOURCE:
+ phpdbg_try_access {
+ const char *type = zend_rsrc_list_get_rsrc_type(Z_RES_P(data) TSRMLS_CC);
+ VARIABLEINFO("type=\"%s\"", "\n|-------(typeof)------> (%s)\n", type ? type : "unknown");
+ } phpdbg_catch_access {
+ VARIABLEINFO("type=\"unknown\"", "\n|-------(typeof)------> (unknown)\n");
+ } phpdbg_end_try_access();
+ break;
+ case IS_OBJECT:
+ phpdbg_try_access {
+ VARIABLEINFO("instanceof=\"%s\"", "\n|-----(instanceof)----> (%s)\n", Z_OBJCE_P(data)->name);
+ } phpdbg_catch_access {
+ VARIABLEINFO("instanceof=\"%s\"", "\n|-----(instanceof)----> (unknown)\n");
+ } phpdbg_end_try_access();
+ break;
+ case IS_STRING:
+ phpdbg_try_access {
+ VARIABLEINFO("length=\"%d\" value=\"%.*s\"", "\nstring (%d) \"%.*s%s\"", Z_STRLEN_P(data), Z_STRLEN_P(data) < 255 ? Z_STRLEN_P(data) : 255, Z_STRVAL_P(data), Z_STRLEN_P(data) > 255 ? "..." : "");
+ } phpdbg_catch_access {
VARIABLEINFO("", "");
- }
+ } phpdbg_end_try_access();
+ break;
+ case IS_TRUE:
+ VARIABLEINFO("value=\"true\"", "\nbool (true)");
+ break;
+ case IS_FALSE:
+ VARIABLEINFO("value=\"false\"", "\nbool (false)");
+ break;
+ case IS_LONG:
+ VARIABLEINFO("value=\"%ld\"", "\nint (%ld)", Z_LVAL_P(data));
+ break;
+ case IS_DOUBLE:
+ VARIABLEINFO("value=\"%lf\"", "\ndouble (%lf)", Z_DVAL_P(data));
+ break;
+ default:
+ VARIABLEINFO("", "");
}
#undef VARIABLEINFO
+ } phpdbg_catch_access {
+ phpdbg_writeln("variable", "address=\"%p\" name=\"%s\"", "%p\tn/a\tn/a\t$%s", data, var);
} phpdbg_end_try_access();
-
- if (invalid_data) {
- phpdbg_writeln("variable", "name=\"%s\"", "n/a\tn/a\tn/a\t$%s", var);
- }
- }
+ } ZEND_HASH_FOREACH_END();
}
zend_hash_destroy(&vars);
@@ -312,8 +287,9 @@ PHPDBG_INFO(globals) /* {{{ */
PHPDBG_INFO(literal) /* {{{ */
{
/* literals are assumed to not be manipulated during executing of their op_array and as such async safe */
- if ((EG(in_execution) && EG(active_op_array)) || PHPDBG_G(ops)) {
- zend_op_array *ops = EG(active_op_array) ? EG(active_op_array) : PHPDBG_G(ops);
+ zend_bool in_executor = PHPDBG_G(in_execution) && EG(current_execute_data) && EG(current_execute_data)->func;
+ if (in_executor || PHPDBG_G(ops)) {
+ zend_op_array *ops = in_executor ? &EG(current_execute_data)->func->op_array : PHPDBG_G(ops);
int literal = 0, count = ops->last_literal-1;
if (ops->function_name) {
@@ -324,16 +300,16 @@ PHPDBG_INFO(literal) /* {{{ */
}
} else {
if (ops->filename) {
- phpdbg_notice("literalinfo", "file=\"%s\" num=\"%d\"", "Literal Constants in %s (%d)", ops->filename, count);
+ phpdbg_notice("literalinfo", "file=\"%s\" num=\"%d\"", "Literal Constants in %s (%d)", ops->filename->val, count);
} else {
phpdbg_notice("literalinfo", "opline=\"%p\" num=\"%d\"", "Literal Constants @ %p (%d)", ops, count);
}
}
while (literal < ops->last_literal) {
- if (Z_TYPE(ops->literals[literal].constant) != IS_NULL) {
+ if (Z_TYPE(ops->literals[literal]) != IS_NULL) {
phpdbg_write("literal", "id=\"%u\"", "|-------- C%u -------> [", literal);
- zend_print_zval(&ops->literals[literal].constant, 0);
+ zend_print_zval(&ops->literals[literal], 0 TSRMLS_CC);
phpdbg_out("]\n");
}
literal++;
@@ -378,35 +354,27 @@ PHPDBG_INFO(memory) /* {{{ */
return SUCCESS;
} /* }}} */
-static inline void phpdbg_print_class_name(zend_class_entry **ce TSRMLS_DC) /* {{{ */
+static inline void phpdbg_print_class_name(zend_class_entry *ce TSRMLS_DC) /* {{{ */
{
- phpdbg_writeln("class", "type=\"%s\" flags=\"%s\" name=\"%s\" methodcount=\"%d\"", "%s %s %s (%d)",
- ((*ce)->type == ZEND_USER_CLASS) ?
- "User" : "Internal",
- ((*ce)->ce_flags & ZEND_ACC_INTERFACE) ?
- "Interface" :
- ((*ce)->ce_flags & ZEND_ACC_ABSTRACT) ?
- "Abstract Class" :
- "Class",
- (*ce)->name, zend_hash_num_elements(&(*ce)->function_table));
+ const char *visibility = ce->type == ZEND_USER_CLASS ? "User" : "Internal";
+ const char *type = (ce->ce_flags & ZEND_ACC_INTERFACE) ? "Interface" : (ce->ce_flags & ZEND_ACC_ABSTRACT) ? "Abstract Class" : "Class";
+
+ phpdbg_writeln("class", "type=\"%s\" flags=\"%s\" name=\"%.*s\" methodcount=\"%d\"", "%s %s %.*s (%d)", visibility, type, ce->name->len, ce->name->val, zend_hash_num_elements(&ce->function_table));
} /* }}} */
PHPDBG_INFO(classes) /* {{{ */
{
- HashPosition position;
- zend_class_entry **ce;
+ zend_class_entry *ce;
HashTable classes;
zend_hash_init(&classes, 8, NULL, NULL, 0);
phpdbg_try_access {
- for (zend_hash_internal_pointer_reset_ex(EG(class_table), &position);
- zend_hash_get_current_data_ex(EG(class_table), (void**)&ce, &position) == SUCCESS;
- zend_hash_move_forward_ex(EG(class_table), &position)) {
- if ((*ce)->type == ZEND_USER_CLASS) {
- zend_hash_next_index_insert(&classes, ce, sizeof(ce), NULL);
+ ZEND_HASH_FOREACH_PTR(EG(class_table), ce) {
+ if (ce->type == ZEND_USER_CLASS) {
+ zend_hash_next_index_insert_ptr(&classes, ce);
}
- }
+ } ZEND_HASH_FOREACH_END();
} phpdbg_catch_access {
phpdbg_notice("signalsegv", "", "Not all classes could be fetched, possibly invalid data source");
} phpdbg_end_try_access();
@@ -414,30 +382,25 @@ PHPDBG_INFO(classes) /* {{{ */
phpdbg_notice("classinfo", "num=\"%d\"", "User Classes (%d)", zend_hash_num_elements(&classes));
/* once added, assume that classes are stable... until shutdown. */
- for (zend_hash_internal_pointer_reset_ex(&classes, &position);
- zend_hash_get_current_data_ex(&classes, (void**)&ce, &position) == SUCCESS;
- zend_hash_move_forward_ex(&classes, &position)) {
-
+ ZEND_HASH_FOREACH_PTR(&classes, ce) {
phpdbg_print_class_name(ce TSRMLS_CC);
- if ((*ce)->parent) {
- zend_class_entry *pce;
-
+ if (ce->parent) {
phpdbg_xml("<parents %r>");
- pce = (*ce)->parent;
+ zend_class_entry *pce = ce->parent;
do {
phpdbg_out("|-------- ");
- phpdbg_print_class_name(&pce TSRMLS_CC);
+ phpdbg_print_class_name(pce TSRMLS_CC);
} while ((pce = pce->parent));
phpdbg_xml("</parents>");
}
- if ((*ce)->info.user.filename) {
- phpdbg_writeln("classsource", "file=\"%s\" line=\"%u\"", "|---- in %s on line %u", (*ce)->info.user.filename, (*ce)->info.user.line_start);
+ if (ce->info.user.filename) {
+ phpdbg_writeln("classsource", "file=\"%s\" line=\"%u\"", "|---- in %s on line %u", ce->info.user.filename->val, ce->info.user.line_start);
} else {
phpdbg_writeln("classsource", "", "|---- no source code");
}
- }
+ } ZEND_HASH_FOREACH_END();
zend_hash_destroy(&classes);
@@ -446,41 +409,34 @@ PHPDBG_INFO(classes) /* {{{ */
PHPDBG_INFO(funcs) /* {{{ */
{
- HashPosition position;
- zend_function *zf, **pzf;
+ zend_function *zf;
HashTable functions;
zend_hash_init(&functions, 8, NULL, NULL, 0);
phpdbg_try_access {
- for (zend_hash_internal_pointer_reset_ex(EG(function_table), &position);
- zend_hash_get_current_data_ex(EG(function_table), (void**)&zf, &position) == SUCCESS;
- zend_hash_move_forward_ex(EG(function_table), &position)) {
+ ZEND_HASH_FOREACH_PTR(EG(function_table), zf) {
if (zf->type == ZEND_USER_FUNCTION) {
- zend_hash_next_index_insert(&functions, (void**) &zf, sizeof(zend_function), NULL);
+ zend_hash_next_index_insert_ptr(&functions, zf);
}
- }
+ } ZEND_HASH_FOREACH_END();
} phpdbg_catch_access {
phpdbg_notice("signalsegv", "", "Not all functions could be fetched, possibly invalid data source");
} phpdbg_end_try_access();
phpdbg_notice("functioninfo", "num=\"%d\"", "User Functions (%d)", zend_hash_num_elements(&functions));
- for (zend_hash_internal_pointer_reset_ex(&functions, &position);
- zend_hash_get_current_data_ex(&functions, (void**)&pzf, &position) == SUCCESS;
- zend_hash_move_forward_ex(&functions, &position)) {
- zend_op_array *op_array = &((*pzf)->op_array);
+ ZEND_HASH_FOREACH_PTR(&functions, zf) {
+ zend_op_array *op_array = &zf->op_array;
- phpdbg_write("function", "name=\"%s\"", "|-------- %s", op_array->function_name ? op_array->function_name : "{main}");
+ phpdbg_write("function", "name=\"%s\"", "|-------- %s", op_array->function_name ? op_array->function_name->val : "{main}");
if (op_array->filename) {
- phpdbg_writeln("functionsource", "file=\"%s\" line=\"%d\"", " in %s on line %d",
- op_array->filename,
- op_array->line_start);
+ phpdbg_writeln("functionsource", "file=\"%s\" line=\"%d\"", " in %s on line %d", op_array->filename->val, op_array->line_start);
} else {
phpdbg_writeln("functionsource", "", " (no source code)");
}
- }
+ } ZEND_HASH_FOREACH_END();
zend_hash_destroy(&functions);
diff --git a/sapi/phpdbg/phpdbg_list.c b/sapi/phpdbg/phpdbg_list.c
index 80b5d2b189..de03a3651e 100644
--- a/sapi/phpdbg/phpdbg_list.c
+++ b/sapi/phpdbg/phpdbg_list.c
@@ -53,16 +53,18 @@ PHPDBG_LIST(lines) /* {{{ */
}
switch (param->type) {
- case NUMERIC_PARAM:
- phpdbg_list_file(phpdbg_current_file(TSRMLS_C),
- (param->num < 0 ? 1 - param->num : param->num),
- (param->num < 0 ? param->num : 0) + zend_get_executed_lineno(TSRMLS_C),
- 0 TSRMLS_CC);
- break;
-
- case FILE_PARAM:
- phpdbg_list_file(param->file.name, param->file.line, 0, 0 TSRMLS_CC);
- break;
+ case NUMERIC_PARAM: {
+ const char *char_file = phpdbg_current_file(TSRMLS_C);
+ zend_string *file = zend_string_init(char_file, strlen(char_file), 0);
+ phpdbg_list_file(file, param->num < 0 ? 1 - param->num : param->num, (param->num < 0 ? param->num : 0) + zend_get_executed_lineno(TSRMLS_C), 0 TSRMLS_CC);
+ efree(file);
+ } break;
+
+ case FILE_PARAM: {
+ zend_string *file = zend_string_init(param->file.name, strlen(param->file.name), 0);
+ phpdbg_list_file(file, param->file.line, 0, 0 TSRMLS_CC);
+ efree(file);
+ } break;
phpdbg_default_switch_case();
}
@@ -79,13 +81,13 @@ PHPDBG_LIST(func) /* {{{ */
PHPDBG_LIST(method) /* {{{ */
{
- zend_class_entry **ce;
+ zend_class_entry *ce;
if (phpdbg_safe_class_lookup(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) {
+ if ((function = zend_hash_str_find_ptr(&ce->function_table, lcname, strlen(lcname)))) {
phpdbg_list_function(function TSRMLS_CC);
} else {
phpdbg_error("list", "type=\"notfound\" method=\"%s::%s\"", "Could not find %s::%s", param->method.class, param->method.name);
@@ -101,21 +103,17 @@ PHPDBG_LIST(method) /* {{{ */
PHPDBG_LIST(class) /* {{{ */
{
- zend_class_entry **ce;
+ zend_class_entry *ce;
if (phpdbg_safe_class_lookup(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, 0 TSRMLS_CC
- );
+ 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, 0 TSRMLS_CC);
} else {
- phpdbg_error("list", "type=\"nosource\" class=\"%s\"", "The source of the requested class (%s) cannot be found", (*ce)->name);
+ phpdbg_error("list", "type=\"nosource\" class=\"%s\"", "The source of the requested class (%s) cannot be found", ce->name);
}
} else {
- phpdbg_error("list", "type=\"internalclass\" class=\"%s\"", "The class requested (%s) is not user defined", (*ce)->name);
+ phpdbg_error("list", "type=\"internalclass\" class=\"%s\"", "The class requested (%s) is not user defined", ce->name);
}
} else {
phpdbg_error("list", "type=\"notfound\" class=\"%s\"", "The requested class (%s) could not be found", param->str);
@@ -124,12 +122,12 @@ PHPDBG_LIST(class) /* {{{ */
return SUCCESS;
} /* }}} */
-void phpdbg_list_file(const char *filename, uint count, int offset, uint highlight TSRMLS_DC) /* {{{ */
+void phpdbg_list_file(zend_string *filename, uint count, int offset, uint highlight TSRMLS_DC) /* {{{ */
{
uint line, lastline;
- phpdbg_file_source **data;
+ phpdbg_file_source *data;
- if (zend_hash_find(&PHPDBG_G(file_sources), filename, strlen(filename), (void **) &data) == FAILURE) {
+ if (!(data = zend_hash_find_ptr(&PHPDBG_G(file_sources), filename))) {
phpdbg_error("list", "type=\"unknownfile\"", "Could not find information about included file...");
return;
}
@@ -141,16 +139,16 @@ void phpdbg_list_file(const char *filename, uint count, int offset, uint highlig
lastline = offset + count;
- if (lastline > (*data)->lines) {
- lastline = (*data)->lines;
+ if (lastline > data->lines) {
+ lastline = data->lines;
}
phpdbg_xml("<list %r file=\"%s\">", filename);
for (line = offset; line < lastline;) {
- uint linestart = (*data)->line[line++];
- uint linelen = (*data)->line[line] - linestart;
- char *buffer = (*data)->buf + linestart;
+ uint linestart = data->line[line++];
+ uint linelen = data->line[line] - linestart;
+ char *buffer = data->buf + linestart;
if (!highlight) {
phpdbg_write("line", "line=\"%u\" code=\"%.*s\"", " %05u: %.*s", line, linelen, buffer);
@@ -179,7 +177,7 @@ void phpdbg_list_function(const zend_function *fbc TSRMLS_DC) /* {{{ */
return;
}
- ops = (zend_op_array *)fbc;
+ ops = (zend_op_array *) fbc;
phpdbg_list_file(ops->filename, ops->line_end - ops->line_start + 1, ops->line_start, 0 TSRMLS_CC);
} /* }}} */
@@ -213,7 +211,7 @@ void phpdbg_list_function_byname(const char *str, size_t len TSRMLS_DC) /* {{{ *
func_name = zend_str_tolower_dup(func_name, func_name_len);
phpdbg_try_access {
- if (zend_hash_find(func_table, func_name, func_name_len+1, (void**)&fbc) == SUCCESS) {
+ if ((fbc = zend_hash_str_find_ptr(func_table, func_name, func_name_len))) {
phpdbg_list_function(fbc TSRMLS_CC);
} else {
phpdbg_error("list", "type=\"nofunction\" function=\"%s\"", "Function %s not found", func_name);
@@ -227,7 +225,7 @@ void phpdbg_list_function_byname(const char *str, size_t len TSRMLS_DC) /* {{{ *
zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type TSRMLS_DC) {
phpdbg_file_source data, *dataptr;
- zend_file_handle fake = {0};
+ zend_file_handle fake = {{0}};
zend_op_array *ret;
char *filename = (char *)(file->opened_path ? file->opened_path : file->filename);
uint line;
@@ -258,7 +256,6 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type TSRMLS_DC) {
fake.opened_path = file->opened_path;
*(dataptr = emalloc(sizeof(phpdbg_file_source) + sizeof(uint) * data.len)) = data;
- zend_hash_add(&PHPDBG_G(file_sources), filename, strlen(filename), &dataptr, sizeof(phpdbg_file_source *), NULL);
for (line = 0, bufptr = data.buf - 1, endptr = data.buf + data.len; ++bufptr < endptr;) {
if (*bufptr == '\n') {
@@ -269,6 +266,8 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type TSRMLS_DC) {
dataptr->line[line] = endptr - data.buf;
dataptr = erealloc(dataptr, sizeof(phpdbg_file_source) + sizeof(uint) * line);
+ zend_hash_str_add_ptr(&PHPDBG_G(file_sources), filename, strlen(filename), dataptr);
+
ret = PHPDBG_G(compile_file)(&fake, type TSRMLS_CC);
fake.opened_path = NULL;
diff --git a/sapi/phpdbg/phpdbg_list.h b/sapi/phpdbg/phpdbg_list.h
index c88328bfea..43a2d474d5 100644
--- a/sapi/phpdbg/phpdbg_list.h
+++ b/sapi/phpdbg/phpdbg_list.h
@@ -33,8 +33,8 @@ PHPDBG_LIST(method);
PHPDBG_LIST(func);
void phpdbg_list_function_byname(const char *, size_t TSRMLS_DC);
-void phpdbg_list_function(const zend_function* TSRMLS_DC);
-void phpdbg_list_file(const char*, uint, int, uint TSRMLS_DC);
+void phpdbg_list_function(const zend_function * TSRMLS_DC);
+void phpdbg_list_file(zend_string *, uint, int, uint TSRMLS_DC);
extern const phpdbg_command_t phpdbg_list_commands[];
diff --git a/sapi/phpdbg/phpdbg_opcode.c b/sapi/phpdbg/phpdbg_opcode.c
index 331718accc..99f43344a4 100644
--- a/sapi/phpdbg/phpdbg_opcode.c
+++ b/sapi/phpdbg/phpdbg_opcode.c
@@ -26,7 +26,7 @@
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
-static inline zend_uint phpdbg_decode_literal(zend_op_array *ops, zend_literal *literal TSRMLS_DC) /* {{{ */
+static inline uint32_t phpdbg_decode_literal(zend_op_array *ops, zval *literal TSRMLS_DC) /* {{{ */
{
int iter = 0;
@@ -40,32 +40,31 @@ static inline zend_uint phpdbg_decode_literal(zend_op_array *ops, zend_literal *
return 0;
} /* }}} */
-static inline char *phpdbg_decode_op(zend_op_array *ops, znode_op *op, zend_uint type, HashTable *vars TSRMLS_DC) /* {{{ */
+static inline char *phpdbg_decode_op(zend_op_array *ops, znode_op *op, uint32_t type, HashTable *vars TSRMLS_DC) /* {{{ */
{
char *decode = NULL;
switch (type &~ EXT_TYPE_UNUSED) {
case IS_CV:
- asprintf(&decode, "$%s", ops->vars[op->var].name);
+ asprintf(&decode, "$%s", ops->vars[EX_VAR_TO_NUM(op->var)]->val);
break;
case IS_VAR:
case IS_TMP_VAR: {
zend_ulong id = 0, *pid = NULL;
if (vars != NULL) {
- if (zend_hash_index_find(vars, (zend_ulong) ops->vars - op->var, (void**) &pid) != SUCCESS) {
+ if ((pid = zend_hash_index_find_ptr(vars, (zend_ulong) ops->vars - op->var))) {
+ id = *pid;
+ } else {
id = zend_hash_num_elements(vars);
- zend_hash_index_update(
- vars, (zend_ulong) ops->vars - op->var,
- (void**) &id,
- sizeof(zend_ulong), NULL);
- } else id = *pid;
+ zend_hash_index_update_mem(vars, (zend_ulong) ops->vars - op->var, &id, sizeof(zend_ulong));
+ }
}
- asprintf(&decode, "@%lu", id);
+ asprintf(&decode, "@%llu", id);
} break;
case IS_CONST:
- asprintf(&decode, "C%u", phpdbg_decode_literal(ops, op->literal TSRMLS_CC));
+ asprintf(&decode, "C%u", phpdbg_decode_literal(ops, op->zv TSRMLS_CC));
break;
case IS_UNUSED:
@@ -92,7 +91,7 @@ char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op, HashTable *vars TSRM
case ZEND_JMPZNZ:
decode[1] = phpdbg_decode_op(ops, &op->op1, op->op1_type, vars TSRMLS_CC);
- asprintf(&decode[2], "J%u or J%lu", op->op2.opline_num, op->extended_value);
+ asprintf(&decode[2], "J%u or J%llu", op->op2.opline_num, op->extended_value);
goto result;
case ZEND_JMPZ:
@@ -142,8 +141,8 @@ void phpdbg_print_opline_ex(zend_execute_data *execute_data, HashTable *vars, ze
(PHPDBG_G(flags) & PHPDBG_IS_STEPPING) ||
(PHPDBG_G(oplog)))) {
- zend_op *opline = execute_data->opline;
- char *decode = phpdbg_decode_opline(execute_data->op_array, opline, vars TSRMLS_CC);
+ zend_op *opline = (zend_op *) execute_data->opline;
+ char *decode = phpdbg_decode_opline(&execute_data->func->op_array, opline, vars TSRMLS_CC);
if (ignore_flags || (!(PHPDBG_G(flags) & PHPDBG_IS_QUIET) || (PHPDBG_G(flags) & PHPDBG_IS_STEPPING))) {
/* output line info */
@@ -152,7 +151,7 @@ void phpdbg_print_opline_ex(zend_execute_data *execute_data, HashTable *vars, ze
opline,
phpdbg_decode_opcode(opline->opcode),
decode,
- execute_data->op_array->filename ? execute_data->op_array->filename : "unknown");
+ execute_data->func->op_array.filename ? execute_data->func->op_array.filename->val : "unknown");
}
if (!ignore_flags && PHPDBG_G(oplog)) {
@@ -161,7 +160,7 @@ void phpdbg_print_opline_ex(zend_execute_data *execute_data, HashTable *vars, ze
opline,
phpdbg_decode_opcode(opline->opcode),
decode,
- execute_data->op_array->filename ? execute_data->op_array->filename : "unknown");
+ execute_data->func->op_array.filename ? execute_data->func->op_array.filename->val : "unknown");
}
if (decode) {
@@ -177,180 +176,6 @@ void phpdbg_print_opline(zend_execute_data *execute_data, zend_bool ignore_flags
const char *phpdbg_decode_opcode(zend_uchar opcode) /* {{{ */
{
-#if ZEND_EXTENSION_API_NO <= PHP_5_5_API_NO
-#define CASE(s) case s: return #s
- switch (opcode) {
- CASE(ZEND_NOP);
- CASE(ZEND_ADD);
- CASE(ZEND_SUB);
- CASE(ZEND_MUL);
- CASE(ZEND_DIV);
- CASE(ZEND_MOD);
- CASE(ZEND_SL);
- CASE(ZEND_SR);
- CASE(ZEND_CONCAT);
- CASE(ZEND_BW_OR);
- CASE(ZEND_BW_AND);
- CASE(ZEND_BW_XOR);
- CASE(ZEND_BW_NOT);
- CASE(ZEND_BOOL_NOT);
- CASE(ZEND_BOOL_XOR);
- CASE(ZEND_IS_IDENTICAL);
- CASE(ZEND_IS_NOT_IDENTICAL);
- CASE(ZEND_IS_EQUAL);
- CASE(ZEND_IS_NOT_EQUAL);
- CASE(ZEND_IS_SMALLER);
- CASE(ZEND_IS_SMALLER_OR_EQUAL);
- CASE(ZEND_CAST);
- CASE(ZEND_QM_ASSIGN);
- CASE(ZEND_ASSIGN_ADD);
- CASE(ZEND_ASSIGN_SUB);
- CASE(ZEND_ASSIGN_MUL);
- CASE(ZEND_ASSIGN_DIV);
- CASE(ZEND_ASSIGN_MOD);
- CASE(ZEND_ASSIGN_SL);
- CASE(ZEND_ASSIGN_SR);
- CASE(ZEND_ASSIGN_CONCAT);
- CASE(ZEND_ASSIGN_BW_OR);
- CASE(ZEND_ASSIGN_BW_AND);
- CASE(ZEND_ASSIGN_BW_XOR);
- CASE(ZEND_PRE_INC);
- CASE(ZEND_PRE_DEC);
- CASE(ZEND_POST_INC);
- CASE(ZEND_POST_DEC);
- CASE(ZEND_ASSIGN);
- CASE(ZEND_ASSIGN_REF);
- CASE(ZEND_ECHO);
- CASE(ZEND_PRINT);
- CASE(ZEND_JMP);
- CASE(ZEND_JMPZ);
- CASE(ZEND_JMPNZ);
- CASE(ZEND_JMPZNZ);
- CASE(ZEND_JMPZ_EX);
- CASE(ZEND_JMPNZ_EX);
- CASE(ZEND_CASE);
- CASE(ZEND_SWITCH_FREE);
- CASE(ZEND_BRK);
- CASE(ZEND_CONT);
- CASE(ZEND_BOOL);
- CASE(ZEND_INIT_STRING);
- CASE(ZEND_ADD_CHAR);
- CASE(ZEND_ADD_STRING);
- CASE(ZEND_ADD_VAR);
- CASE(ZEND_BEGIN_SILENCE);
- CASE(ZEND_END_SILENCE);
- CASE(ZEND_INIT_FCALL_BY_NAME);
- CASE(ZEND_DO_FCALL);
- CASE(ZEND_DO_FCALL_BY_NAME);
- CASE(ZEND_RETURN);
- CASE(ZEND_RECV);
- CASE(ZEND_RECV_INIT);
- CASE(ZEND_SEND_VAL);
- CASE(ZEND_SEND_VAR);
- CASE(ZEND_SEND_REF);
- CASE(ZEND_NEW);
- CASE(ZEND_INIT_NS_FCALL_BY_NAME);
- CASE(ZEND_FREE);
- CASE(ZEND_INIT_ARRAY);
- CASE(ZEND_ADD_ARRAY_ELEMENT);
- CASE(ZEND_INCLUDE_OR_EVAL);
- CASE(ZEND_UNSET_VAR);
- CASE(ZEND_UNSET_DIM);
- CASE(ZEND_UNSET_OBJ);
- CASE(ZEND_FE_RESET);
- CASE(ZEND_FE_FETCH);
- CASE(ZEND_EXIT);
- CASE(ZEND_FETCH_R);
- CASE(ZEND_FETCH_DIM_R);
- CASE(ZEND_FETCH_OBJ_R);
- CASE(ZEND_FETCH_W);
- CASE(ZEND_FETCH_DIM_W);
- CASE(ZEND_FETCH_OBJ_W);
- CASE(ZEND_FETCH_RW);
- CASE(ZEND_FETCH_DIM_RW);
- CASE(ZEND_FETCH_OBJ_RW);
- CASE(ZEND_FETCH_IS);
- CASE(ZEND_FETCH_DIM_IS);
- CASE(ZEND_FETCH_OBJ_IS);
- CASE(ZEND_FETCH_FUNC_ARG);
- CASE(ZEND_FETCH_DIM_FUNC_ARG);
- CASE(ZEND_FETCH_OBJ_FUNC_ARG);
- CASE(ZEND_FETCH_UNSET);
- CASE(ZEND_FETCH_DIM_UNSET);
- CASE(ZEND_FETCH_OBJ_UNSET);
- CASE(ZEND_FETCH_DIM_TMP_VAR);
- CASE(ZEND_FETCH_CONSTANT);
- CASE(ZEND_GOTO);
- CASE(ZEND_EXT_STMT);
- CASE(ZEND_EXT_FCALL_BEGIN);
- CASE(ZEND_EXT_FCALL_END);
- CASE(ZEND_EXT_NOP);
- CASE(ZEND_TICKS);
- CASE(ZEND_SEND_VAR_NO_REF);
- CASE(ZEND_CATCH);
- CASE(ZEND_THROW);
- CASE(ZEND_FETCH_CLASS);
- CASE(ZEND_CLONE);
- CASE(ZEND_RETURN_BY_REF);
- CASE(ZEND_INIT_METHOD_CALL);
- CASE(ZEND_INIT_STATIC_METHOD_CALL);
- CASE(ZEND_ISSET_ISEMPTY_VAR);
- CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ);
- CASE(ZEND_PRE_INC_OBJ);
- CASE(ZEND_PRE_DEC_OBJ);
- CASE(ZEND_POST_INC_OBJ);
- CASE(ZEND_POST_DEC_OBJ);
- CASE(ZEND_ASSIGN_OBJ);
- CASE(ZEND_INSTANCEOF);
- CASE(ZEND_DECLARE_CLASS);
- CASE(ZEND_DECLARE_INHERITED_CLASS);
- CASE(ZEND_DECLARE_FUNCTION);
- CASE(ZEND_RAISE_ABSTRACT_ERROR);
- CASE(ZEND_DECLARE_CONST);
- CASE(ZEND_ADD_INTERFACE);
- CASE(ZEND_DECLARE_INHERITED_CLASS_DELAYED);
- CASE(ZEND_VERIFY_ABSTRACT_CLASS);
- CASE(ZEND_ASSIGN_DIM);
- CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ);
- CASE(ZEND_HANDLE_EXCEPTION);
- CASE(ZEND_USER_OPCODE);
-#ifdef ZEND_JMP_SET
- CASE(ZEND_JMP_SET);
-#endif
- CASE(ZEND_DECLARE_LAMBDA_FUNCTION);
-#ifdef ZEND_ADD_TRAIT
- CASE(ZEND_ADD_TRAIT);
-#endif
-#ifdef ZEND_BIND_TRAITS
- CASE(ZEND_BIND_TRAITS);
-#endif
-#ifdef ZEND_SEPARATE
- CASE(ZEND_SEPARATE);
-#endif
-#ifdef ZEND_DISCARD_EXCEPTION
- CASE(ZEND_DISCARD_EXCEPTION);
-#endif
-#ifdef ZEND_YIELD
- CASE(ZEND_YIELD);
-#endif
-#ifdef ZEND_GENERATOR_RETURN
- CASE(ZEND_GENERATOR_RETURN);
-#endif
-#ifdef ZEND_FAST_CALL
- CASE(ZEND_FAST_CALL);
-#endif
-#ifdef ZEND_FAST_RET
- CASE(ZEND_FAST_RET);
-#endif
-#ifdef ZEND_RECV_VARIADIC
- CASE(ZEND_RECV_VARIADIC);
-#endif
- CASE(ZEND_OP_DATA);
- default:
- return "UNKNOWN";
- }
-#else
const char *ret = zend_get_opcode_name(opcode);
return ret?ret:"UNKNOWN";
-#endif
} /* }}} */
diff --git a/sapi/phpdbg/phpdbg_out.c b/sapi/phpdbg/phpdbg_out.c
index a4793f144f..4d70381533 100644
--- a/sapi/phpdbg/phpdbg_out.c
+++ b/sapi/phpdbg/phpdbg_out.c
@@ -136,7 +136,8 @@ static int format_converter(register buffy *odp, const char *fmt, zend_bool esca
int i;
char *s = NULL, *free_s = NULL;
- int s_len, free_zcopy;
+ size_t s_len;
+ zend_bool free_zcopy;
zval *zvp, zcopy;
int min_width = 0;
@@ -331,8 +332,8 @@ static int format_converter(register buffy *odp, const char *fmt, zend_bool esca
*/
switch (*fmt) {
case 'Z':
- zvp = (zval*) va_arg(ap, zval*);
- zend_make_printable_zval(zvp, &zcopy, &free_zcopy);
+ zvp = (zval *) va_arg(ap, zval *);
+ free_zcopy = zend_make_printable_zval(zvp, &zcopy TSRMLS_CC);
if (free_zcopy) {
zvp = &zcopy;
}
@@ -1021,6 +1022,8 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m
if (msg) {
PHPDBG_G(last_was_newline) = msg[msglen - 1] == '\n';
if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
+ zend_string *encoded;
+
if (PHPDBG_G(in_script_xml) != type) {
char *stream_buf;
int stream_buflen = phpdbg_asprintf(&stream_buf, "<stream type=\"%s\">", type == P_STDERR ? "stderr" : "stdout");
@@ -1028,11 +1031,9 @@ static int phpdbg_process_print(int fd, int type, const char *tag, const char *m
efree(stream_buf);
PHPDBG_G(in_script_xml) = type;
}
-#if PHP_VERSION_ID >= 50600
- buf = php_escape_html_entities((unsigned char *) msg, msglen, (size_t *) &buflen, 0, ENT_NOQUOTES, PG(internal_encoding) && PG(internal_encoding)[0] ? PG(internal_encoding) : (SG(default_charset) ? SG(default_charset) : "UTF-8") TSRMLS_CC);
-#else
- buf = php_escape_html_entities((unsigned char *) msg, msglen, (size_t *) &buflen, 0, ENT_NOQUOTES, SG(default_charset) ? SG(default_charset) : "UTF-8" TSRMLS_CC);
-#endif
+ encoded = php_escape_html_entities((unsigned char *) msg, msglen, 0, ENT_NOQUOTES, PG(internal_encoding) && PG(internal_encoding)[0] ? PG(internal_encoding) : (SG(default_charset) ? SG(default_charset) : "UTF-8") TSRMLS_CC);
+ buflen = encoded->len;
+ memcpy(buf = emalloc(buflen + 1), encoded->val, buflen);
phpdbg_encode_ctrl_chars(&buf, &buflen);
phpdbg_mixed_write(fd, buf, buflen TSRMLS_CC);
efree(buf);
diff --git a/sapi/phpdbg/phpdbg_parser.c b/sapi/phpdbg/phpdbg_parser.c
index c766868369..8bb9103a98 100644
--- a/sapi/phpdbg/phpdbg_parser.c
+++ b/sapi/phpdbg/phpdbg_parser.c
@@ -1,8 +1,8 @@
-/* A Bison parser, made by GNU Bison 2.5. */
+/* A Bison parser, made by GNU Bison 2.6. */
/* Bison implementation for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -44,7 +44,7 @@
#define YYBISON 1
/* Bison version. */
-#define YYBISON_VERSION "2.5"
+#define YYBISON_VERSION "2.6"
/* Skeleton name. */
#define YYSKELETON_NAME "yacc.c"
@@ -58,8 +58,6 @@
/* Pull parsers. */
#define YYPULL 1
-/* Using locations. */
-#define YYLSP_NEEDED 0
/* Substitute the variable and function names. */
#define yyparse phpdbg_parse
@@ -70,11 +68,10 @@
#define yydebug phpdbg_debug
#define yynerrs phpdbg_nerrs
-
/* Copy the first part of user declarations. */
-/* Line 268 of yacc.c */
-#line 1 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 336 of yacc.c */
+#line 1 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
/*
@@ -102,13 +99,16 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
-/* Line 268 of yacc.c */
-#line 107 "sapi/phpdbg/phpdbg_parser.c"
+/* Line 336 of yacc.c */
+#line 104 "sapi/phpdbg/phpdbg_parser.c"
-/* Enabling traces. */
-#ifndef YYDEBUG
-# define YYDEBUG 0
-#endif
+# ifndef YY_NULL
+# if defined __cplusplus && 201103L <= __cplusplus
+# define YY_NULL nullptr
+# else
+# define YY_NULL 0
+# endif
+# endif
/* Enabling verbose error messages. */
#ifdef YYERROR_VERBOSE
@@ -118,15 +118,21 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
# define YYERROR_VERBOSE 1
#endif
-/* Enabling the token table. */
-#ifndef YYTOKEN_TABLE
-# define YYTOKEN_TABLE 0
+/* In a future release of Bison, this section will be replaced
+ by #include "phpdbg_parser.h". */
+#ifndef PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H
+# define PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int phpdbg_debug;
#endif
-
/* "%code requires" blocks. */
-/* Line 288 of yacc.c */
-#line 31 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 350 of yacc.c */
+#line 31 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
#include "phpdbg.h"
#ifndef YY_TYPEDEF_YY_SCANNER_T
@@ -136,8 +142,8 @@ typedef void* yyscan_t;
-/* Line 288 of yacc.c */
-#line 141 "sapi/phpdbg/phpdbg_parser.c"
+/* Line 350 of yacc.c */
+#line 147 "sapi/phpdbg/phpdbg_parser.c"
/* Tokens. */
#ifndef YYTOKENTYPE
@@ -189,7 +195,6 @@ typedef void* yyscan_t;
-
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
@@ -198,11 +203,27 @@ typedef int YYSTYPE;
#endif
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int phpdbg_parse (void *YYPARSE_PARAM);
+#else
+int phpdbg_parse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int phpdbg_parse (void *tsrm_ls);
+#else
+int phpdbg_parse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+#endif /* !PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H */
+
/* Copy the second part of user declarations. */
-/* Line 343 of yacc.c */
-#line 206 "sapi/phpdbg/phpdbg_parser.c"
+/* Line 353 of yacc.c */
+#line 227 "sapi/phpdbg/phpdbg_parser.c"
#ifdef short
# undef short
@@ -308,6 +329,7 @@ YYID (yyi)
# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+ /* Use EXIT_SUCCESS as a witness for stdlib.h. */
# ifndef EXIT_SUCCESS
# define EXIT_SUCCESS 0
# endif
@@ -399,20 +421,20 @@ union yyalloc
#endif
#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
-/* Copy COUNT objects from FROM to TO. The source and destination do
+/* Copy COUNT objects from SRC to DST. The source and destination do
not overlap. */
# ifndef YYCOPY
# if defined __GNUC__ && 1 < __GNUC__
-# define YYCOPY(To, From, Count) \
- __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# define YYCOPY(Dst, Src, Count) \
+ __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
# else
-# define YYCOPY(To, From, Count) \
- do \
- { \
- YYSIZE_T yyi; \
- for (yyi = 0; yyi < (Count); yyi++) \
- (To)[yyi] = (From)[yyi]; \
- } \
+# define YYCOPY(Dst, Src, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (Dst)[yyi] = (Src)[yyi]; \
+ } \
while (YYID (0))
# endif
# endif
@@ -505,7 +527,7 @@ static const yytype_uint8 yyrline[] =
};
#endif
-#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+#if YYDEBUG || YYERROR_VERBOSE || 1
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
@@ -519,7 +541,7 @@ static const char *const yytname[] =
"\"opcode\"", "\"identifier (command or function name)\"",
"\"input (input string or data)\"", "\"input\"",
"\"request id (-r %d)\"", "$accept", "input", "parameters", "parameter",
- "req_id", "full_expression", 0
+ "req_id", "full_expression", YY_NULL
};
#endif
@@ -652,17 +674,18 @@ static const yytype_uint8 yystos[] =
#define YYRECOVERING() (!!yyerrstatus)
-#define YYBACKUP(Token, Value) \
-do \
- if (yychar == YYEMPTY && yylen == 1) \
- { \
- yychar = (Token); \
- yylval = (Value); \
- YYPOPSTACK (1); \
- goto yybackup; \
- } \
- else \
- { \
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ YYPOPSTACK (yylen); \
+ yystate = *yyssp; \
+ goto yybackup; \
+ } \
+ else \
+ { \
yyerror (tsrm_ls, YY_("syntax error: cannot back up")); \
YYERROR; \
} \
@@ -672,32 +695,33 @@ while (YYID (0))
#define YYTERROR 1
#define YYERRCODE 256
-
/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
If N is 0, then set CURRENT to the empty location which ends
the previous symbol: RHS[0] (always defined). */
-#define YYRHSLOC(Rhs, K) ((Rhs)[K])
#ifndef YYLLOC_DEFAULT
-# define YYLLOC_DEFAULT(Current, Rhs, N) \
- do \
- if (YYID (N)) \
- { \
- (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
- (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
- (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
- (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
- } \
- else \
- { \
- (Current).first_line = (Current).last_line = \
- YYRHSLOC (Rhs, 0).last_line; \
- (Current).first_column = (Current).last_column = \
- YYRHSLOC (Rhs, 0).last_column; \
- } \
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (YYID (N)) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
while (YYID (0))
#endif
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+
+
/* This macro is provided for backward compatibility. */
@@ -758,6 +782,8 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, tsrm_ls)
void *tsrm_ls;
#endif
{
+ FILE *yyo = yyoutput;
+ YYUSE (yyo);
if (!yyvaluep)
return;
YYUSE (tsrm_ls);
@@ -1012,12 +1038,12 @@ static int
yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
yytype_int16 *yyssp, int yytoken)
{
- YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
+ YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]);
YYSIZE_T yysize = yysize0;
YYSIZE_T yysize1;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */
- const char *yyformat = 0;
+ const char *yyformat = YY_NULL;
/* Arguments of yyformat. */
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
/* Number of reported tokens (one for the "unexpected", one per
@@ -1077,7 +1103,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
break;
}
yyarg[yycount++] = yytname[yyx];
- yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]);
if (! (yysize <= yysize1
&& yysize1 <= YYSTACK_ALLOC_MAXIMUM))
return 2;
@@ -1171,20 +1197,6 @@ yydestruct (yymsg, yytype, yyvaluep, tsrm_ls)
}
-/* Prevent warnings from -Wmissing-prototypes. */
-#ifdef YYPARSE_PARAM
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *YYPARSE_PARAM);
-#else
-int yyparse ();
-#endif
-#else /* ! YYPARSE_PARAM */
-#if defined __STDC__ || defined __cplusplus
-int yyparse (void *tsrm_ls);
-#else
-int yyparse ();
-#endif
-#endif /* ! YYPARSE_PARAM */
/*----------.
@@ -1230,7 +1242,7 @@ YYSTYPE yylval;
`yyss': related to states.
`yyvs': related to semantic values.
- Refer to the stacks thru separate pointers, to allow yyoverflow
+ Refer to the stacks through separate pointers, to allow yyoverflow
to reallocate them elsewhere. */
/* The state stack. */
@@ -1463,36 +1475,36 @@ yyreduce:
{
case 3:
-/* Line 1806 of yacc.c */
-#line 68 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 68 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(1) - (1)])); }
break;
case 5:
-/* Line 1806 of yacc.c */
-#line 73 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 73 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(1) - (1)])); }
break;
case 6:
-/* Line 1806 of yacc.c */
-#line 74 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 74 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ phpdbg_stack_push(PHPDBG_G(parser_stack), &(yyvsp[(2) - (2)])); }
break;
case 7:
-/* Line 1806 of yacc.c */
-#line 75 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 75 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ (yyval) = (yyvsp[(1) - (2)]); }
break;
case 8:
-/* Line 1806 of yacc.c */
-#line 79 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 79 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = FILE_PARAM;
(yyval).file.name = (yyvsp[(2) - (3)]).str;
@@ -1502,8 +1514,8 @@ yyreduce:
case 9:
-/* Line 1806 of yacc.c */
-#line 84 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 84 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = NUMERIC_FILE_PARAM;
(yyval).file.name = (yyvsp[(1) - (4)]).str;
@@ -1513,8 +1525,8 @@ yyreduce:
case 10:
-/* Line 1806 of yacc.c */
-#line 89 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 89 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = FILE_PARAM;
(yyval).file.name = malloc((yyvsp[(1) - (4)]).len + (yyvsp[(2) - (4)]).len + 1);
@@ -1529,8 +1541,8 @@ yyreduce:
case 11:
-/* Line 1806 of yacc.c */
-#line 99 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 99 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = NUMERIC_FILE_PARAM;
(yyval).file.name = malloc((yyvsp[(1) - (5)]).len + (yyvsp[(2) - (5)]).len + 1);
@@ -1545,8 +1557,8 @@ yyreduce:
case 12:
-/* Line 1806 of yacc.c */
-#line 109 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 109 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = METHOD_PARAM;
(yyval).method.class = (yyvsp[(1) - (3)]).str;
@@ -1556,8 +1568,8 @@ yyreduce:
case 13:
-/* Line 1806 of yacc.c */
-#line 114 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 114 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = NUMERIC_METHOD_PARAM;
(yyval).method.class = (yyvsp[(1) - (5)]).str;
@@ -1568,8 +1580,8 @@ yyreduce:
case 14:
-/* Line 1806 of yacc.c */
-#line 120 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 120 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = NUMERIC_FUNCTION_PARAM;
(yyval).str = (yyvsp[(1) - (3)]).str;
@@ -1580,8 +1592,8 @@ yyreduce:
case 15:
-/* Line 1806 of yacc.c */
-#line 126 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 126 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = COND_PARAM;
(yyval).str = (yyvsp[(2) - (2)]).str;
@@ -1591,64 +1603,64 @@ yyreduce:
case 16:
-/* Line 1806 of yacc.c */
-#line 131 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 131 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 17:
-/* Line 1806 of yacc.c */
-#line 132 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 132 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 18:
-/* Line 1806 of yacc.c */
-#line 133 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 133 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 19:
-/* Line 1806 of yacc.c */
-#line 134 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 134 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 20:
-/* Line 1806 of yacc.c */
-#line 135 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 135 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 21:
-/* Line 1806 of yacc.c */
-#line 136 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 136 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 22:
-/* Line 1806 of yacc.c */
-#line 137 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 137 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ (yyval) = (yyvsp[(1) - (1)]); }
break;
case 23:
-/* Line 1806 of yacc.c */
-#line 141 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 141 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{ PHPDBG_G(req_id) = (yyvsp[(1) - (1)]).num; }
break;
case 25:
-/* Line 1806 of yacc.c */
-#line 146 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 146 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = EVAL_PARAM;
(yyval).str = (yyvsp[(3) - (3)]).str;
@@ -1658,8 +1670,8 @@ yyreduce:
case 26:
-/* Line 1806 of yacc.c */
-#line 151 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 151 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = SHELL_PARAM;
(yyval).str = (yyvsp[(3) - (3)]).str;
@@ -1669,8 +1681,8 @@ yyreduce:
case 27:
-/* Line 1806 of yacc.c */
-#line 156 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 156 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = RUN_PARAM;
(yyval).len = 0;
@@ -1679,8 +1691,8 @@ yyreduce:
case 28:
-/* Line 1806 of yacc.c */
-#line 160 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 1803 of yacc.c */
+#line 160 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
{
(yyval).type = RUN_PARAM;
(yyval).str = (yyvsp[(3) - (3)]).str;
@@ -1690,8 +1702,8 @@ yyreduce:
-/* Line 1806 of yacc.c */
-#line 1695 "sapi/phpdbg/phpdbg_parser.c"
+/* Line 1803 of yacc.c */
+#line 1707 "sapi/phpdbg/phpdbg_parser.c"
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
@@ -1878,7 +1890,7 @@ yyabortlab:
yyresult = 1;
goto yyreturn;
-#if !defined(yyoverflow) || YYERROR_VERBOSE
+#if !defined yyoverflow || YYERROR_VERBOSE
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
`-------------------------------------------------*/
@@ -1921,8 +1933,8 @@ yyreturn:
-/* Line 2067 of yacc.c */
-#line 167 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 2049 of yacc.c */
+#line 167 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
static int yyerror(void ***tsrm_ls, const char *msg) {
diff --git a/sapi/phpdbg/phpdbg_parser.h b/sapi/phpdbg/phpdbg_parser.h
index dfa155d718..e8ab7a6503 100644
--- a/sapi/phpdbg/phpdbg_parser.h
+++ b/sapi/phpdbg/phpdbg_parser.h
@@ -1,8 +1,8 @@
-/* A Bison parser, made by GNU Bison 2.5. */
+/* A Bison parser, made by GNU Bison 2.6. */
/* Bison interface for Yacc-like parsers in C
- Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
+ Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,10 +30,19 @@
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
+#ifndef PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H
+# define PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+#if YYDEBUG
+extern int phpdbg_debug;
+#endif
/* "%code requires" blocks. */
-/* Line 2068 of yacc.c */
-#line 31 "/root/php-src-xml-data-phpdbg/sapi/phpdbg/phpdbg_parser.y"
+/* Line 2056 of yacc.c */
+#line 31 "/Users/Bob/php-src-X/sapi/phpdbg/phpdbg_parser.y"
#include "phpdbg.h"
#ifndef YY_TYPEDEF_YY_SCANNER_T
@@ -43,8 +52,8 @@ typedef void* yyscan_t;
-/* Line 2068 of yacc.c */
-#line 48 "sapi/phpdbg/phpdbg_parser.h"
+/* Line 2056 of yacc.c */
+#line 57 "sapi/phpdbg/phpdbg_parser.h"
/* Tokens. */
#ifndef YYTOKENTYPE
@@ -96,7 +105,6 @@ typedef void* yyscan_t;
-
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
@@ -105,5 +113,18 @@ typedef int YYSTYPE;
#endif
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int phpdbg_parse (void *YYPARSE_PARAM);
+#else
+int phpdbg_parse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int phpdbg_parse (void *tsrm_ls);
+#else
+int phpdbg_parse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
-
+#endif /* !PHPDBG_SAPI_PHPDBG_PHPDBG_PARSER_H */
diff --git a/sapi/phpdbg/phpdbg_print.c b/sapi/phpdbg/phpdbg_print.c
index 80eeddb39d..62a614281d 100644
--- a/sapi/phpdbg/phpdbg_print.c
+++ b/sapi/phpdbg/phpdbg_print.c
@@ -41,7 +41,7 @@ const phpdbg_command_t phpdbg_print_commands[] = {
PHPDBG_PRINT(opline) /* {{{ */
{
- if (EG(in_execution) && EG(current_execute_data)) {
+ if (PHPDBG_G(in_execution) && EG(current_execute_data)) {
phpdbg_print_opline(EG(current_execute_data), 1 TSRMLS_CC);
} else {
phpdbg_error("inactive", "type=\"execution\"", "Not Executing!");
@@ -59,22 +59,22 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC)
if (op_array) {
zend_op *opline = &(op_array->opcodes[0]);
- zend_uint opcode = 0,
+ uint32_t opcode = 0,
end = op_array->last-1;
if (method->common.scope) {
phpdbg_writeln("printoplineinfo", "type=\"User\" startline=\"%d\" endline=\"%d\" method=\"%s::%s\" file=\"%s\"", "\tL%d-%d %s::%s() %s",
op_array->line_start,
op_array->line_end,
- method->common.scope->name,
- method->common.function_name,
- op_array->filename ? op_array->filename : "unknown");
+ method->common.scope->name->val,
+ method->common.function_name->val,
+ op_array->filename ? op_array->filename->val : "unknown");
} else {
phpdbg_writeln("printoplineinfo", "type=\"User\" startline=\"%d\" endline=\"%d\" function=\"%s\" file=\"%s\"", "\tL%d-%d %s() %s",
method->common.function_name ? op_array->line_start : 0,
method->common.function_name ? op_array->line_end : 0,
- method->common.function_name ? method->common.function_name : "{main}",
- op_array->filename ? op_array->filename : "unknown");
+ method->common.function_name ? method->common.function_name->val : "{main}",
+ op_array->filename ? op_array->filename->val : "unknown");
}
zend_hash_init(&vars, op_array->last, NULL, NULL, 0);
@@ -98,9 +98,9 @@ static inline void phpdbg_print_function_helper(zend_function *method TSRMLS_DC)
default: {
if (method->common.scope) {
- phpdbg_writeln("printoplineinfo", "type=\"Internal\" method=\"%s::%s\"", "Internal %s::%s()", method->common.scope->name, method->common.function_name);
+ phpdbg_writeln("printoplineinfo", "type=\"Internal\" method=\"%s::%s\"", "\tInternal %s::%s()", method->common.scope->name->val, method->common.function_name->val);
} else {
- phpdbg_writeln("printoplineinfo", "type=\"Internal\" function=\"%s\"", "\tInternal %s()", method->common.function_name);
+ phpdbg_writeln("printoplineinfo", "type=\"Internal\" function=\"%s\"", "\tInternal %s()", method->common.function_name->val);
}
}
}
@@ -127,18 +127,17 @@ return SUCCESS;
PHPDBG_PRINT(stack) /* {{{ */
{
- zend_op_array *ops = EG(active_op_array);
-
- if (EG(in_execution) && ops) {
+ if (PHPDBG_G(in_execution) && EG(current_execute_data)) {
+ zend_op_array *ops = &EG(current_execute_data)->func->op_array;
if (ops->function_name) {
if (ops->scope) {
- phpdbg_notice("printinfo", "method=\"%s::%s\" num=\"%d\"", "Stack in %s::%s() (%d ops)", ops->scope->name, ops->function_name, ops->last);
+ phpdbg_notice("printinfo", "method=\"%s::%s\" num=\"%d\"", "Stack in %s::%s() (%d ops)", ops->scope->name->val, ops->function_name->val, ops->last);
} else {
- phpdbg_notice("printinfo", "function=\"%s\" num=\"%d\"", "Stack in %s() (%d ops)", ops->function_name, ops->last);
+ phpdbg_notice("printinfo", "function=\"%s\" num=\"%d\"", "Stack in %s() (%d ops)", ops->function_name->val, ops->last);
}
} else {
if (ops->filename) {
- phpdbg_notice("printinfo", "file=\"%s\" num=\"%d\"", "Stack in %s (%d ops)", ops->filename, ops->last);
+ phpdbg_notice("printinfo", "file=\"%s\" num=\"%d\"", "Stack in %s (%d ops)", ops->filename->val, ops->last);
} else {
phpdbg_notice("printinfo", "opline=\"%p\" num=\"%d\"", "Stack @ %p (%d ops)", ops, ops->last);
}
@@ -153,31 +152,28 @@ PHPDBG_PRINT(stack) /* {{{ */
PHPDBG_PRINT(class) /* {{{ */
{
- zend_class_entry **ce;
+ zend_class_entry *ce;
if (phpdbg_safe_class_lookup(param->str, param->len, &ce TSRMLS_CC) == SUCCESS) {
phpdbg_notice("printinfo", "type=\"%s\" flag=\"%s\" class=\"%s\" num=\"%d\"", "%s %s: %s (%d methods)",
- ((*ce)->type == ZEND_USER_CLASS) ?
+ (ce->type == ZEND_USER_CLASS) ?
"User" : "Internal",
- ((*ce)->ce_flags & ZEND_ACC_INTERFACE) ?
+ (ce->ce_flags & ZEND_ACC_INTERFACE) ?
"Interface" :
- ((*ce)->ce_flags & ZEND_ACC_ABSTRACT) ?
+ (ce->ce_flags & ZEND_ACC_ABSTRACT) ?
"Abstract Class" :
"Class",
- (*ce)->name,
- zend_hash_num_elements(&(*ce)->function_table));
+ ce->name->val,
+ zend_hash_num_elements(&ce->function_table));
phpdbg_xml("<printmethods %r>");
- if (zend_hash_num_elements(&(*ce)->function_table)) {
- HashPosition position;
+ if (zend_hash_num_elements(&ce->function_table)) {
zend_function *method;
- for (zend_hash_internal_pointer_reset_ex(&(*ce)->function_table, &position);
- zend_hash_get_current_data_ex(&(*ce)->function_table, (void**) &method, &position) == SUCCESS;
- zend_hash_move_forward_ex(&(*ce)->function_table, &position)) {
+ ZEND_HASH_FOREACH_PTR(&ce->function_table, method) {
phpdbg_print_function_helper(method TSRMLS_CC);
- }
+ } ZEND_HASH_FOREACH_END();
}
phpdbg_xml("</printmethods>");
@@ -190,16 +186,17 @@ PHPDBG_PRINT(class) /* {{{ */
PHPDBG_PRINT(method) /* {{{ */
{
- zend_class_entry **ce;
+ zend_class_entry *ce;
if (phpdbg_safe_class_lookup(param->method.class, strlen(param->method.class), &ce TSRMLS_CC) == SUCCESS) {
zend_function *fbc;
- char *lcname = zend_str_tolower_dup(param->method.name, strlen(param->method.name));
+ zend_string *lcname = zend_string_alloc(strlen(param->method.name), 0);
+ zend_str_tolower_copy(lcname->val, param->method.name, lcname->len);
- if (zend_hash_find(&(*ce)->function_table, lcname, strlen(lcname)+1, (void**)&fbc) == SUCCESS) {
+ if ((fbc = zend_hash_find_ptr(&ce->function_table, lcname))) {
phpdbg_notice("printinfo", "type=\"%s\" flags=\"Method\" symbol=\"%s\" num=\"%d\"", "%s Method %s (%d ops)",
(fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal",
- fbc->common.function_name,
+ fbc->common.function_name->val,
(fbc->type == ZEND_USER_FUNCTION) ? fbc->op_array.last : 0);
phpdbg_print_function_helper(fbc TSRMLS_CC);
@@ -207,7 +204,7 @@ PHPDBG_PRINT(method) /* {{{ */
phpdbg_error("print", "type=\"nomethod\" method=\"%s::%s\"", "The method %s::%s could not be found", param->method.class, param->method.name);
}
- efree(lcname);
+ zend_string_release(lcname);
} else {
phpdbg_error("print", "type=\"noclass\" class=\"%s\"", "The class %s could not be found", param->method.class);
}
@@ -221,7 +218,7 @@ PHPDBG_PRINT(func) /* {{{ */
zend_function* fbc;
const char *func_name = param->str;
size_t func_name_len = param->len;
- char *lcname;
+ zend_string *lcname;
/* search active scope if begins with period */
if (func_name[0] == '.') {
if (EG(scope)) {
@@ -240,14 +237,15 @@ PHPDBG_PRINT(func) /* {{{ */
func_table = EG(function_table);
}
- lcname = zend_str_tolower_dup(func_name, func_name_len);
+ lcname = zend_string_alloc(func_name_len, 0);
+ zend_str_tolower_copy(lcname->val, func_name, lcname->len);
phpdbg_try_access {
- if (zend_hash_find(func_table, lcname, func_name_len + 1, (void **) &fbc) == SUCCESS) {
+ if ((fbc = zend_hash_find_ptr(func_table, lcname))) {
phpdbg_notice("printinfo", "type=\"%s\" flags=\"%s\" symbol=\"%s\" num=\"%d\"", "%s %s %s (%d ops)",
(fbc->type == ZEND_USER_FUNCTION) ? "User" : "Internal",
(fbc->common.scope) ? "Method" : "Function",
- fbc->common.function_name,
+ fbc->common.function_name->val,
(fbc->type == ZEND_USER_FUNCTION) ? fbc->op_array.last : 0);
phpdbg_print_function_helper(fbc TSRMLS_CC);
diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c
index 82444fbf1d..190907e687 100644
--- a/sapi/phpdbg/phpdbg_prompt.c
+++ b/sapi/phpdbg/phpdbg_prompt.c
@@ -22,6 +22,7 @@
#include <string.h>
#include "zend.h"
#include "zend_compile.h"
+#include "zend_exceptions.h"
#include "phpdbg.h"
#include "phpdbg_help.h"
@@ -103,20 +104,18 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ *
lc_name = zend_str_tolower_dup(name->str, name->len);
- if (zend_hash_exists(&PHPDBG_G(registered), lc_name, name->len+1)) {
- zval fname, *fretval;
+ if (zend_hash_str_exists(&PHPDBG_G(registered), lc_name, name->len)) {
+ zval fretval;
zend_fcall_info fci;
- ZVAL_STRINGL(&fname, lc_name, name->len, 1);
-
memset(&fci, 0, sizeof(zend_fcall_info));
+ ZVAL_STRINGL(&fci.function_name, lc_name, name->len);
fci.size = sizeof(zend_fcall_info);
fci.function_table = &PHPDBG_G(registered);
- fci.function_name = &fname;
- fci.symbol_table = EG(active_symbol_table);
- fci.object_ptr = NULL;
- fci.retval_ptr_ptr = &fretval;
+ fci.symbol_table = zend_rebuild_symbol_table(TSRMLS_C);
+ fci.object = NULL;
+ fci.retval = &fretval;
fci.no_separation = 1;
if (name->next) {
@@ -132,7 +131,7 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ *
case OP_PARAM:
case COND_PARAM:
case STR_PARAM:
- add_next_index_stringl(&params, next->str, next->len, 1);
+ add_next_index_stringl(&params, next->str, next->len);
break;
case NUMERIC_PARAM:
@@ -140,33 +139,28 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ *
break;
case METHOD_PARAM:
- spprintf(&buffered, 0, "%s::%s",
- next->method.class, next->method.name);
- add_next_index_string(&params, buffered, 0);
+ spprintf(&buffered, 0, "%s::%s", next->method.class, next->method.name);
+ add_next_index_string(&params, buffered);
break;
case NUMERIC_METHOD_PARAM:
- spprintf(&buffered, 0, "%s::%s#%ld",
- next->method.class, next->method.name, next->num);
- add_next_index_string(&params, buffered, 0);
+ spprintf(&buffered, 0, "%s::%s#%ld", next->method.class, next->method.name, next->num);
+ add_next_index_string(&params, buffered);
break;
case NUMERIC_FUNCTION_PARAM:
- spprintf(&buffered, 0, "%s#%ld",
- next->str, next->num);
- add_next_index_string(&params, buffered, 0);
+ spprintf(&buffered, 0, "%s#%ld", next->str, next->num);
+ add_next_index_string(&params, buffered);
break;
case FILE_PARAM:
- spprintf(&buffered, 0, "%s:%ld",
- next->file.name, next->file.line);
- add_next_index_string(&params, buffered, 0);
+ spprintf(&buffered, 0, "%s:%ld", next->file.name, next->file.line);
+ add_next_index_string(&params, buffered);
break;
case NUMERIC_FILE_PARAM:
- spprintf(&buffered, 0, "%s:#%ld",
- next->file.name, next->file.line);
- add_next_index_string(&params, buffered, 0);
+ spprintf(&buffered, 0, "%s:#%ld", next->file.name, next->file.line);
+ add_next_index_string(&params, buffered);
break;
default: {
@@ -188,14 +182,13 @@ static inline int phpdbg_call_register(phpdbg_param_t *stack TSRMLS_DC) /* {{{ *
phpdbg_debug("created %d params from arguments", fci.param_count);
- zend_call_function(&fci, NULL TSRMLS_CC);
-
- if (fretval) {
- zend_print_zval_r(fretval, 0 TSRMLS_CC);
+ if (zend_call_function(&fci, NULL TSRMLS_CC) == SUCCESS) {
+ zend_print_zval_r(&fretval, 0 TSRMLS_CC);
phpdbg_out("\n");
+ zval_ptr_dtor(&fretval);
}
- zval_dtor(&fname);
+ zval_dtor(&fci.function_name);
efree(lc_name);
return SUCCESS;
@@ -401,13 +394,12 @@ int phpdbg_compile(TSRMLS_D) /* {{{ */
return SUCCESS;
}
- if (EG(in_execution)) {
+ if (PHPDBG_G(in_execution)) {
phpdbg_error("inactive", "type=\"isrunning\"", "Cannot compile while in execution");
return FAILURE;
}
if (php_stream_open_for_zend_ex(PHPDBG_G(exec), &fh, USE_PATH|STREAM_OPEN_FOR_INCLUDE TSRMLS_CC) == SUCCESS) {
-
PHPDBG_G(ops) = zend_compile_file(&fh, ZEND_INCLUDE TSRMLS_CC);
zend_destroy_file_handle(&fh TSRMLS_CC);
@@ -422,7 +414,7 @@ int phpdbg_compile(TSRMLS_D) /* {{{ */
PHPDBG_COMMAND(step) /* {{{ */
{
- if (EG(in_execution)) {
+ if (PHPDBG_G(in_execution)) {
PHPDBG_G(flags) |= PHPDBG_IS_STEPPING;
}
@@ -436,19 +428,19 @@ PHPDBG_COMMAND(continue) /* {{{ */
PHPDBG_COMMAND(until) /* {{{ */
{
- if (!EG(in_execution)) {
+ if (!PHPDBG_G(in_execution)) {
phpdbg_error("inactive", "type=\"noexec\"", "Not executing");
return SUCCESS;
}
PHPDBG_G(flags) |= PHPDBG_IN_UNTIL;
{
- zend_uint next = 0, self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes);
- zend_op *opline = &EG(active_op_array)->opcodes[self];
+ const zend_op *opline = EG(current_execute_data)->opline;
+ const zend_op_array *op_array = &EG(current_execute_data)->func->op_array;
- for (next = self; next < EG(active_op_array)->last; next++) {
- if (EG(active_op_array)->opcodes[next].lineno != opline->lineno) {
- zend_hash_index_update(&PHPDBG_G(seek), (zend_ulong) &EG(active_op_array)->opcodes[next], &EG(active_op_array)->opcodes[next], sizeof(zend_op), NULL);
+ while (++opline < op_array->opcodes + op_array->last) {
+ if (opline->lineno != EG(current_execute_data)->opline->lineno) {
+ zend_hash_index_update_ptr(&PHPDBG_G(seek), (zend_ulong) opline, (void *) opline);
break;
}
}
@@ -457,58 +449,46 @@ PHPDBG_COMMAND(until) /* {{{ */
return PHPDBG_UNTIL;
} /* }}} */
+static void phpdbg_seek_to_end(TSRMLS_D) {
+ const zend_op *opline = EG(current_execute_data)->opline;
+ const zend_op_array *op_array = &EG(current_execute_data)->func->op_array - 1;
+
+ while (++opline < op_array->opcodes + op_array->last) {
+ switch (opline->opcode) {
+ case ZEND_RETURN:
+ case ZEND_THROW:
+ case ZEND_EXIT:
+#ifdef ZEND_YIELD
+ case ZEND_YIELD:
+#endif
+ zend_hash_index_update_ptr(&PHPDBG_G(seek), (zend_ulong) opline, (void *) opline);
+ return;
+ }
+ }
+}
+
PHPDBG_COMMAND(finish) /* {{{ */
{
- if (!EG(in_execution)) {
+ if (!PHPDBG_G(in_execution)) {
phpdbg_error("inactive", "type=\"noexec\"", "Not executing");
return SUCCESS;
}
PHPDBG_G(flags) |= PHPDBG_IN_FINISH;
- {
- zend_uint next = 0, self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes);
-
- for (next = self; next < EG(active_op_array)->last; next++) {
- switch (EG(active_op_array)->opcodes[next].opcode) {
- case ZEND_RETURN:
- case ZEND_THROW:
- case ZEND_EXIT:
-#ifdef ZEND_YIELD
- case ZEND_YIELD:
-#endif
- zend_hash_index_update(&PHPDBG_G(seek), (zend_ulong) &EG(active_op_array)->opcodes[next], &EG(active_op_array)->opcodes[next], sizeof(zend_op), NULL);
- break;
- }
- }
- }
+ phpdbg_seek_to_end(TSRMLS_C);
return PHPDBG_FINISH;
} /* }}} */
PHPDBG_COMMAND(leave) /* {{{ */
{
- if (!EG(in_execution)) {
+ if (!PHPDBG_G(in_execution)) {
phpdbg_error("inactive", "type=\"noexec\"", "Not executing");
return SUCCESS;
}
PHPDBG_G(flags) |= PHPDBG_IN_LEAVE;
- {
- zend_uint next = 0, self = (EG(current_execute_data)->opline - EG(active_op_array)->opcodes);
-
- for (next = self; next < EG(active_op_array)->last; next++) {
- switch (EG(active_op_array)->opcodes[next].opcode) {
- case ZEND_RETURN:
- case ZEND_THROW:
- case ZEND_EXIT:
-#ifdef ZEND_YIELD
- case ZEND_YIELD:
-#endif
- zend_hash_index_update(&PHPDBG_G(seek), (zend_ulong) &EG(active_op_array)->opcodes[next], &EG(active_op_array)->opcodes[next], sizeof(zend_op), NULL);
- break;
- }
- }
- }
+ phpdbg_seek_to_end(TSRMLS_C);
return PHPDBG_LEAVE;
} /* }}} */
@@ -527,59 +507,47 @@ PHPDBG_COMMAND(frame) /* {{{ */
static inline void phpdbg_handle_exception(TSRMLS_D) /* }}} */
{
zend_fcall_info fci;
-
- zval fname, *trace, exception;
+ zval trace;
/* get filename and linenumber before unsetting exception */
const char *filename = zend_get_executed_filename(TSRMLS_C);
- zend_uint lineno = zend_get_executed_lineno(TSRMLS_C);
-
- /* copy exception */
- exception = *EG(exception);
- zval_copy_ctor(&exception);
- EG(exception) = NULL;
+ uint32_t lineno = zend_get_executed_lineno(TSRMLS_C);
/* call __toString */
- ZVAL_STRINGL(&fname, "__tostring", sizeof("__tostring")-1, 1);
+ ZVAL_STRINGL(&fci.function_name, "__tostring", sizeof("__tostring") - 1);
fci.size = sizeof(fci);
- fci.function_table = &Z_OBJCE(exception)->function_table;
- fci.function_name = &fname;
+ fci.function_table = &EG(exception)->ce->function_table;
fci.symbol_table = NULL;
- fci.object_ptr = &exception;
- fci.retval_ptr_ptr = &trace;
+ fci.object = EG(exception);
+ fci.retval = &trace;
fci.param_count = 0;
fci.params = NULL;
fci.no_separation = 1;
- zend_call_function(&fci, NULL TSRMLS_CC);
-
- if (trace) {
- phpdbg_writeln("exception", "name=\"%s\" trace=\"%.*s\"", "Uncaught %s!\n%.*s", Z_OBJCE(exception)->name, Z_STRLEN_P(trace), Z_STRVAL_P(trace));
+ if (zend_call_function(&fci, NULL TSRMLS_CC) == SUCCESS) {
+ phpdbg_writeln("exception", "name=\"%s\" trace=\"%.*s\"", "Uncaught %s!\n%.*s", EG(exception)->ce->name->val, Z_STRLEN(trace), Z_STRVAL(trace));
zval_ptr_dtor(&trace);
} else {
- phpdbg_error("exception", "name=\"%s\"", "Uncaught %s!", Z_OBJCE(exception)->name);
+ phpdbg_error("exception", "name=\"%s\"" "Uncaught %s!", EG(exception)->ce->name->val);
}
/* output useful information about address */
- phpdbg_writeln("exception", "opline=\"%p\" file=\"%s\" line=\"%u\"", "Stack entered at %p in %s on line %u", EG(active_op_array)->opcodes, filename, lineno);
+ phpdbg_writeln("exception", "opline=\"%p\" file=\"%s\" line=\"%u\"", "Stack entered at %p in %s on line %u", EG(current_execute_data)->func->op_array.opcodes, filename, lineno);
- zval_dtor(&fname);
- zval_dtor(&exception);
+ zval_dtor(&fci.function_name);
+ zend_clear_exception(TSRMLS_C);
} /* }}} */
PHPDBG_COMMAND(run) /* {{{ */
{
- if (EG(in_execution)) {
+ if (PHPDBG_G(in_execution)) {
phpdbg_error("inactive", "type=\"isrunning\"", "Cannot start another execution while one is in progress");
return SUCCESS;
}
if (PHPDBG_G(ops) || PHPDBG_G(exec)) {
- zend_op **orig_opline = EG(opline_ptr);
- zend_op_array *orig_op_array = EG(active_op_array);
- zval **orig_retval_ptr = EG(return_value_ptr_ptr);
- zend_bool restore = 1;
zend_execute_data *ex = EG(current_execute_data);
+ zend_bool restore = 1;
if (!PHPDBG_G(ops)) {
if (phpdbg_compile(TSRMLS_C) == FAILURE) {
@@ -588,21 +556,16 @@ PHPDBG_COMMAND(run) /* {{{ */
}
}
- EG(active_op_array) = PHPDBG_G(ops);
- EG(return_value_ptr_ptr) = &PHPDBG_G(retval);
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
-
/* clean up from last execution */
if (ex && ex->symbol_table) {
- zend_hash_clean(ex->symbol_table);
+ zend_hash_clean(&ex->symbol_table->ht);
+ } else {
+ zend_rebuild_symbol_table(TSRMLS_C);
}
/* clean seek state */
PHPDBG_G(flags) &= ~PHPDBG_SEEK_MASK;
- zend_hash_clean(
- &PHPDBG_G(seek));
+ zend_hash_clean(&PHPDBG_G(seek));
/* reset hit counters */
phpdbg_reset_breakpoints(TSRMLS_C);
@@ -634,14 +597,11 @@ PHPDBG_COMMAND(run) /* {{{ */
zend_try {
PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE;
- zend_execute(EG(active_op_array) TSRMLS_CC);
+ zend_execute(PHPDBG_G(ops), &PHPDBG_G(retval) TSRMLS_CC);
PHPDBG_G(flags) ^= PHPDBG_IS_INTERACTIVE;
phpdbg_notice("stop", "type=\"normal\"", "Script ended normally");
} zend_catch {
- EG(active_op_array) = orig_op_array;
- EG(opline_ptr) = orig_opline;
- EG(return_value_ptr_ptr) = orig_retval_ptr;
-
+ PHPDBG_G(in_execution) = 0;
if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
phpdbg_error("stop", "type=\"bailout\"", "Caught exit/error from VM");
restore = 0;
@@ -657,10 +617,6 @@ PHPDBG_COMMAND(run) /* {{{ */
if (EG(exception)) {
phpdbg_handle_exception(TSRMLS_C);
}
-
- EG(active_op_array) = orig_op_array;
- EG(opline_ptr) = orig_opline;
- EG(return_value_ptr_ptr) = orig_retval_ptr;
}
} else {
phpdbg_error("inactive", "type=\"nocontext\"", "Nothing to execute!");
@@ -671,10 +627,10 @@ out:
return SUCCESS;
} /* }}} */
-int phpdbg_output_ev_variable(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval **zv TSRMLS_DC) {
+int phpdbg_output_ev_variable(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval *zv TSRMLS_DC) {
phpdbg_notice("eval", "variable=\"%.*s\"", "Printing variable %.*s", (int) len, name);
phpdbg_xml("<eval %r>");
- zend_print_zval_r(*zv, 0 TSRMLS_CC);
+ zend_print_zval_r(zv, 0 TSRMLS_CC);
phpdbg_xml("</eval>");
phpdbg_out("\n");
@@ -691,7 +647,7 @@ PHPDBG_COMMAND(ev) /* {{{ */
if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) {
phpdbg_try_access {
- phpdbg_parse_variable(param->str, param->len, &EG(symbol_table), 0, phpdbg_output_ev_variable, 0 TSRMLS_CC);
+ phpdbg_parse_variable(param->str, param->len, &EG(symbol_table).ht, 0, phpdbg_output_ev_variable, 0 TSRMLS_CC);
} phpdbg_catch_access {
phpdbg_error("signalsegv", "", "Could not fetch data, invalid data source");
} phpdbg_end_try_access();
@@ -705,16 +661,16 @@ PHPDBG_COMMAND(ev) /* {{{ */
/* disable stepping while eval() in progress */
PHPDBG_G(flags) |= PHPDBG_IN_EVAL;
zend_try {
- if (zend_eval_stringl(param->str, param->len,&retval, "eval()'d code" TSRMLS_CC) == SUCCESS) {
+ if (zend_eval_stringl(param->str, param->len, &retval, "eval()'d code" TSRMLS_CC) == SUCCESS) {
phpdbg_xml("<eval %r>");
if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
zval *zvp = &retval;
- phpdbg_xml_var_dump(&zvp TSRMLS_CC);
+ phpdbg_xml_var_dump(zvp TSRMLS_CC);
}
zend_print_zval_r(&retval, 0 TSRMLS_CC);
phpdbg_xml("</eval>");
phpdbg_out("\n");
- zval_dtor(&retval);
+ zval_ptr_dtor(&retval);
}
} zend_end_try();
PHPDBG_G(flags) &= ~PHPDBG_IN_EVAL;
@@ -731,7 +687,7 @@ PHPDBG_COMMAND(ev) /* {{{ */
PHPDBG_COMMAND(back) /* {{{ */
{
- if (!EG(in_execution)) {
+ if (!PHPDBG_G(in_execution)) {
phpdbg_error("inactive", "type=\"noexec\"", "Not executing!");
return SUCCESS;
}
@@ -771,8 +727,8 @@ PHPDBG_COMMAND(print) /* {{{ */
phpdbg_writeln("print", "vars=\"%d\"", "Variables %d", PHPDBG_G(ops)->last_var ? PHPDBG_G(ops)->last_var - 1 : 0);
}
- phpdbg_writeln("print", "executing=\"%d\"", "Executing %s", EG(in_execution) ? "yes" : "no");
- if (EG(in_execution)) {
+ phpdbg_writeln("print", "executing=\"%d\"", "Executing %s", PHPDBG_G(in_execution) ? "yes" : "no");
+ if (PHPDBG_G(in_execution)) {
phpdbg_writeln("print", "vmret=\"%d\"", "VM Return %d", PHPDBG_G(vmret));
}
@@ -939,7 +895,7 @@ PHPDBG_API const char *phpdbg_load_module_or_extension(char **path, char **name
*name = new_extension->name;
- zend_register_extension(new_extension, handle);
+ zend_register_extension(new_extension, handle TSRMLS_CC);
if (new_extension->startup) {
if (new_extension->startup(new_extension) != SUCCESS) {
@@ -1080,9 +1036,9 @@ PHPDBG_COMMAND(register) /* {{{ */
char *lcname = zend_str_tolower_dup(param->str, param->len);
size_t lcname_len = strlen(lcname);
- if (!zend_hash_exists(&PHPDBG_G(registered), lcname, lcname_len+1)) {
- if (zend_hash_find(EG(function_table), lcname, lcname_len+1, (void**) &function) == SUCCESS) {
- zend_hash_update(&PHPDBG_G(registered), lcname, lcname_len+1, (void*)&function, sizeof(zend_function), NULL);
+ if (!zend_hash_str_exists(&PHPDBG_G(registered), lcname, lcname_len)) {
+ if ((function = zend_hash_str_find_ptr(EG(function_table), lcname, lcname_len))) {
+ zend_hash_str_update_ptr(&PHPDBG_G(registered), lcname, lcname_len, function);
function_add_ref(function);
phpdbg_notice("register", "function=\"%s\"", "Registered %s", lcname);
@@ -1110,7 +1066,7 @@ PHPDBG_COMMAND(quit) /* {{{ */
PHPDBG_COMMAND(clean) /* {{{ */
{
- if (EG(in_execution)) {
+ if (PHPDBG_G(in_execution)) {
phpdbg_error("inactive", "type=\"isrunning\"", "Cannot clean environment while executing");
return SUCCESS;
}
@@ -1230,7 +1186,7 @@ int phpdbg_interactive(zend_bool allow_async_unsafe TSRMLS_DC) /* {{{ */
case PHPDBG_NEXT: {
phpdbg_activate_err_buf(0 TSRMLS_CC);
phpdbg_free_err_buf(TSRMLS_C);
- if (!EG(in_execution) && !(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
+ if (!PHPDBG_G(in_execution) && !(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
phpdbg_error("command", "type=\"noexec\"", "Not running");
}
goto out;
@@ -1260,7 +1216,7 @@ out:
PHPDBG_G(req_id) = 0;
}
- if (EG(in_execution)) {
+ if (PHPDBG_G(in_execution)) {
phpdbg_restore_frame(TSRMLS_C);
}
@@ -1287,76 +1243,12 @@ void phpdbg_clean(zend_bool full TSRMLS_DC) /* {{{ */
}
} /* }}} */
-static inline zend_execute_data *phpdbg_create_execute_data(zend_op_array *op_array, zend_bool nested TSRMLS_DC) /* {{{ */
-{
-#if PHP_VERSION_ID >= 50500
- return zend_create_execute_data_from_op_array(op_array, nested TSRMLS_CC);
-#else
-
-#undef EX
-#define EX(element) execute_data->element
-#undef EX_CV
-#define EX_CV(var) EX(CVs)[var]
-#undef EX_CVs
-#define EX_CVs() EX(CVs)
-#undef EX_T
-#define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset))
-#undef EX_Ts
-#define EX_Ts() EX(Ts)
-
- zend_execute_data *execute_data = (zend_execute_data *)zend_vm_stack_alloc(
- ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)) +
- ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)) +
- ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T TSRMLS_CC);
-
- EX(CVs) = (zval ***)((char *)execute_data + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)));
- memset(EX(CVs), 0, sizeof(zval **) * op_array->last_var);
- EX(Ts) = (temp_variable *)(((char *) EX(CVs)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval **) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)));
- EX(fbc) = NULL;
- EX(called_scope) = NULL;
- EX(object) = NULL;
- EX(old_error_reporting) = NULL;
- EX(op_array) = op_array;
- EX(symbol_table) = EG(active_symbol_table);
- EX(prev_execute_data) = EG(current_execute_data);
- EG(current_execute_data) = execute_data;
- EX(nested) = nested;
-
- if (!op_array->run_time_cache && op_array->last_cache_slot) {
- op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
- }
-
- if (op_array->this_var != -1 && EG(This)) {
- Z_ADDREF_P(EG(This)); /* For $this pointer */
- if (!EG(active_symbol_table)) {
- EX_CV(op_array->this_var) = (zval**) EX_CVs() + (op_array->last_var + op_array->this_var);
- *EX_CV(op_array->this_var) = EG(This);
- } else {
- if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), (void **) &EX_CV(op_array->this_var))==FAILURE) {
- Z_DELREF_P(EG(This));
- }
- }
- }
-
- EX(opline) = op_array->opcodes;
- EG(opline_ptr) = &EX(opline);
-
- EX(function_state).function = (zend_function *) op_array;
- EX(function_state).arguments = NULL;
-
- return execute_data;
-#endif
-} /* }}} */
-
#define DO_INTERACTIVE(allow_async_unsafe) do { \
if (!(PHPDBG_G(flags) & PHPDBG_IN_EVAL)) { \
- phpdbg_list_file( \
- zend_get_executed_filename(TSRMLS_C), \
- 3, \
- zend_get_executed_lineno(TSRMLS_C)-1, \
- zend_get_executed_lineno(TSRMLS_C) \
- TSRMLS_CC \
- ); \
+ const char *file_char = zend_get_executed_filename(TSRMLS_C); \
+ zend_string *file = zend_string_init(file_char, strlen(file_char), 0); \
+ phpdbg_list_file(file, 3, zend_get_executed_lineno(TSRMLS_C)-1, zend_get_executed_lineno(TSRMLS_C) TSRMLS_CC); \
+ efree(file); \
} \
\
switch (phpdbg_interactive(allow_async_unsafe TSRMLS_CC)) { \
@@ -1369,45 +1261,19 @@ static inline zend_execute_data *phpdbg_create_execute_data(zend_op_array *op_ar
} \
} while (0)
-#if PHP_VERSION_ID >= 50500
void phpdbg_execute_ex(zend_execute_data *execute_data TSRMLS_DC) /* {{{ */
{
-#else
-void phpdbg_execute_ex(zend_op_array *op_array TSRMLS_DC) /* {{{ */
-{
- long long flags = 0;
- zend_ulong address = 0L;
- zend_execute_data *execute_data;
- zend_bool nested = 0;
-#endif
- zend_bool original_in_execution = EG(in_execution);
+ zend_bool original_in_execution = PHPDBG_G(in_execution);
HashTable vars;
-#if PHP_VERSION_ID < 50500
- if (EG(exception)) {
- return;
- }
-#endif
+ zend_hash_init(&vars, execute_data->func->op_array.last, NULL, NULL, 0);
- EG(in_execution) = 1;
-
-#if PHP_VERSION_ID >= 50500
- if (0) {
-zend_vm_enter:
- execute_data = phpdbg_create_execute_data(EG(active_op_array), 1 TSRMLS_CC);
- }
- zend_hash_init(&vars, EG(active_op_array)->last, NULL, NULL, 0);
-#else
-zend_vm_enter:
- execute_data = phpdbg_create_execute_data(op_array, nested TSRMLS_CC);
- nested = 1;
- zend_hash_init(&vars, EG(active_op_array)->last, NULL, NULL, 0);
-#endif
+ PHPDBG_G(in_execution) = 1;
while (1) {
if ((PHPDBG_G(flags) & PHPDBG_BP_RESOLVE_MASK)) {
/* resolve nth opline breakpoints */
- phpdbg_resolve_op_array_breaks(EG(active_op_array) TSRMLS_CC);
+ phpdbg_resolve_op_array_breaks(&execute_data->func->op_array TSRMLS_CC);
}
#ifdef ZEND_WIN32
@@ -1507,38 +1373,19 @@ next:
PHPDBG_G(last_line) = execute_data->opline->lineno;
/* stupid hack to make zend_do_fcall_common_helper return ZEND_VM_ENTER() instead of recursively calling zend_execute() and eventually segfaulting */
- if ((execute_data->opline->opcode == ZEND_DO_FCALL_BY_NAME || execute_data->opline->opcode == ZEND_DO_FCALL) && execute_data->function_state.function->type == ZEND_USER_FUNCTION) {
-#if PHP_VERSION_ID < 50500
- zend_execute = execute;
-#else
+ if (execute_data->opline->opcode == ZEND_DO_FCALL && execute_data->func->type == ZEND_USER_FUNCTION) {
zend_execute_ex = execute_ex;
-#endif
}
PHPDBG_G(vmret) = execute_data->opline->handler(execute_data TSRMLS_CC);
-#if PHP_VERSION_ID < 50500
- zend_execute = phpdbg_execute_ex;
-#else
zend_execute_ex = phpdbg_execute_ex;
-#endif
- if (PHPDBG_G(vmret) > 0) {
- switch (PHPDBG_G(vmret)) {
- case 1:
- EG(in_execution) = original_in_execution;
- zend_hash_destroy(&vars);
- return;
- case 2:
-#if PHP_VERSION_ID < 50500
- op_array = EG(active_op_array);
-#endif
- zend_hash_destroy(&vars);
- goto zend_vm_enter;
- break;
- case 3:
- execute_data = EG(current_execute_data);
- break;
- default:
- break;
+ if (PHPDBG_G(vmret) != 0) {
+ if (PHPDBG_G(vmret) < 0) {
+ zend_hash_destroy(&vars);
+ PHPDBG_G(in_execution) = original_in_execution;
+ return;
+ } else {
+ execute_data = EG(current_execute_data);
}
}
}
@@ -1552,8 +1399,8 @@ void phpdbg_force_interruption(TSRMLS_D) {
PHPDBG_G(flags) |= PHPDBG_IN_SIGNAL_HANDLER;
if (data) {
- if (data->op_array) {
- phpdbg_notice("hardinterrupt", "opline=\"%p\" num=\"%lu\" file=\"%s\" line=\"%u\"", "Current opline: %p (op #%lu) in %s:%u", data->opline, (data->opline - data->op_array->opcodes) / sizeof(data->opline), data->op_array->filename, data->opline->lineno);
+ if (data->func) {
+ phpdbg_notice("hardinterrupt", "opline=\"%p\" num=\"%lu\" file=\"%s\" line=\"%u\"", "Current opline: %p (op #%lu) in %s:%u", data->opline, (data->opline - data->func->op_array.opcodes) / sizeof(data->opline), data->func->op_array.filename, data->opline->lineno);
} else {
phpdbg_notice("hardinterrupt", "opline=\"%p\"", "Current opline: %p (op_array information unavailable)", data->opline);
}
diff --git a/sapi/phpdbg/phpdbg_rinit_hook.c b/sapi/phpdbg/phpdbg_rinit_hook.c
index 049a782d9d..1bf891654d 100644
--- a/sapi/phpdbg/phpdbg_rinit_hook.c
+++ b/sapi/phpdbg/phpdbg_rinit_hook.c
@@ -45,10 +45,10 @@ static PHP_MINIT_FUNCTION(phpdbg_webhelper) /* {{{ */
static PHP_RINIT_FUNCTION(phpdbg_webhelper) /* {{{ */
{
- zval *cookies = PG(http_globals)[TRACK_VARS_COOKIE];
- zval **auth;
+ zval cookies = PG(http_globals)[TRACK_VARS_COOKIE];
+ zval *auth;
- if (!cookies || zend_hash_find(Z_ARRVAL_P(cookies), PHPDBG_NAME "_AUTH_COOKIE", sizeof(PHPDBG_NAME "_AUTH_COOKIE"), (void **) &auth) == FAILURE || Z_STRLEN_PP(auth) != strlen(PHPDBG_WG(auth)) || strcmp(Z_STRVAL_PP(auth), PHPDBG_WG(auth))) {
+ if (Z_TYPE(cookies) == IS_ARRAY || (auth = zend_hash_str_find(Z_ARRVAL(cookies), PHPDBG_NAME "_AUTH_COOKIE", sizeof(PHPDBG_NAME "_AUTH_COOKIE"))) || Z_STRLEN_P(auth) != strlen(PHPDBG_WG(auth)) || strcmp(Z_STRVAL_P(auth), PHPDBG_WG(auth))) {
return SUCCESS;
}
diff --git a/sapi/phpdbg/phpdbg_set.c b/sapi/phpdbg/phpdbg_set.c
index fc7e788fa0..82b9f69f7a 100644
--- a/sapi/phpdbg/phpdbg_set.c
+++ b/sapi/phpdbg/phpdbg_set.c
@@ -215,9 +215,9 @@ PHPDBG_SET(stepping) /* {{{ */
phpdbg_writeln("setstepping", "type=\"%s\"", "Stepping %s", PHPDBG_G(flags) & PHPDBG_STEP_OPCODE ? "opcode" : "line");
} else switch (param->type) {
case STR_PARAM: {
- if ((param->len == sizeof("opcode") - 1) && memcmp(param->str, "opcode", sizeof("opcode")) == SUCCESS) {
+ if (param->len == sizeof("opcode") - 1 && !memcmp(param->str, "opcode", sizeof("opcode"))) {
PHPDBG_G(flags) |= PHPDBG_STEP_OPCODE;
- } else if ((param->len == sizeof("line")-1) && memcmp(param->str, "line", sizeof("line")) == SUCCESS) {
+ } else if (param->len == sizeof("line") - 1 && !memcmp(param->str, "line", sizeof("line"))) {
PHPDBG_G(flags) &= ~PHPDBG_STEP_OPCODE;
} else {
phpdbg_error("setstepping", "type=\"wrongargs\"", "usage set stepping [<opcode|line>]");
diff --git a/sapi/phpdbg/phpdbg_sigsafe.c b/sapi/phpdbg/phpdbg_sigsafe.c
index 7238ad102f..1ca7bf230c 100644
--- a/sapi/phpdbg/phpdbg_sigsafe.c
+++ b/sapi/phpdbg/phpdbg_sigsafe.c
@@ -3,50 +3,15 @@
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
-static inline void zend_mm_init(zend_mm_heap *heap) {
- zend_mm_free_block *p;
- int i;
-
- heap->free_bitmap = 0;
- heap->large_free_bitmap = 0;
-#if ZEND_MM_CACHE
- heap->cached = 0;
- memset(heap->cache, 0, sizeof(heap->cache));
-#endif
-#if ZEND_MM_CACHE_STAT
- for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
- heap->cache_stat[i].count = 0;
- }
-#endif
- p = ZEND_MM_SMALL_FREE_BUCKET(heap, 0);
- for (i = 0; i < ZEND_MM_NUM_BUCKETS; i++) {
- p->next_free_block = p;
- p->prev_free_block = p;
- p = (zend_mm_free_block *)((char *)p + sizeof(zend_mm_free_block *) * 2);
- heap->large_free_buckets[i] = NULL;
- }
- heap->rest_buckets[0] = heap->rest_buckets[1] = ZEND_MM_REST_BUCKET(heap);
- heap->rest_count = 0;
-}
-
-static zend_mm_storage* zend_mm_mem_init(void *params) {
- TSRMLS_FETCH();
-
- return &PHPDBG_G(sigsafe_mem).storage;
-}
-
-static void zend_mm_mem_dummy(zend_mm_storage *storage) {
-}
-
#define STR(x) #x
#define EXP_STR(x) STR(x)
-static zend_mm_segment* zend_mm_mem_alloc(zend_mm_storage *storage, size_t size) {
+static void* zend_mm_mem_alloc(zend_mm_storage *storage, size_t size, size_t alignment) {
TSRMLS_FETCH();
if (EXPECTED(size == PHPDBG_SIGSAFE_MEM_SIZE && !PHPDBG_G(sigsafe_mem).allocated)) {
PHPDBG_G(sigsafe_mem).allocated = 1;
- return (zend_mm_segment *) PHPDBG_G(sigsafe_mem).mem;
+ return PHPDBG_G(sigsafe_mem).mem;
}
write(PHPDBG_G(io)[PHPDBG_STDERR].fd, ZEND_STRL("Tried to allocate more than " EXP_STR(PHPDBG_SIGSAFE_MEM_SIZE) " bytes from stack memory in signal handler ... bailing out of signal handler\n"));
@@ -60,40 +25,20 @@ static zend_mm_segment* zend_mm_mem_alloc(zend_mm_storage *storage, size_t size)
return NULL;
}
-static zend_mm_segment* zend_mm_mem_realloc(zend_mm_storage *storage, zend_mm_segment *ptr, size_t size) {
- return zend_mm_mem_alloc(storage, size);
-}
-
-static void zend_mm_mem_free(zend_mm_storage *storage, zend_mm_segment *ptr) {
+static void zend_mm_mem_free(zend_mm_storage *storage, void *ptr, size_t size) {
}
-static const zend_mm_mem_handlers phpdbg_handlers_sigsafe_mem = { "stack", zend_mm_mem_init, zend_mm_mem_dummy, zend_mm_mem_dummy, zend_mm_mem_alloc, zend_mm_mem_realloc, zend_mm_mem_free };
-
void phpdbg_set_sigsafe_mem(char *buffer TSRMLS_DC) {
phpdbg_signal_safe_mem *mem = &PHPDBG_G(sigsafe_mem);
- mem->old_heap = zend_mm_set_heap(&mem->heap TSRMLS_CC);
mem->mem = buffer;
mem->allocated = 0;
- mem->storage.handlers = &phpdbg_handlers_sigsafe_mem;
- mem->heap.storage = &mem->storage;
- mem->heap.block_size = PHPDBG_SIGSAFE_MEM_SIZE;
- mem->heap.compact_size = 0;
- mem->heap.segments_list = NULL;
- zend_mm_init(&mem->heap);
-#if ZEND_MM_CACHE_STAT
- memset(mem->heap.cache_stat, 0, sizeof(mem->heap.cache_stat));
-#endif
- mem->heap.use_zend_alloc = 1;
- mem->heap.real_size = 0;
- mem->heap.overflow = 0;
- mem->heap.real_peak = 0;
- mem->heap.limit = PHPDBG_SIGSAFE_MEM_SIZE;
- mem->heap.size = 0;
- mem->heap.peak = 0;
- mem->heap.internal = 0;
- mem->heap.reserve = NULL;
- mem->heap.reserve_size = 0;
+ mem->storage.chunk_alloc = zend_mm_mem_alloc;
+ mem->storage.chunk_free = zend_mm_mem_free;
+
+ mem->heap = zend_mm_startup_ex(&mem->storage);
+
+ mem->old_heap = zend_mm_set_heap(mem->heap TSRMLS_CC);
}
zend_mm_heap *phpdbg_original_heap_sigsafe_mem(TSRMLS_D) {
diff --git a/sapi/phpdbg/phpdbg_sigsafe.h b/sapi/phpdbg/phpdbg_sigsafe.h
index 6ed74f53db..9ef723fdca 100644
--- a/sapi/phpdbg/phpdbg_sigsafe.h
+++ b/sapi/phpdbg/phpdbg_sigsafe.h
@@ -1,14 +1,17 @@
#ifndef PHPDBG_SIGSAFE_H
#define PHPDBG_SIGSAFE_H
-#include "zend_mm_structs.h"
+//#include "zend_mm_structs.h"
-#define PHPDBG_SIGSAFE_MEM_SIZE (1 << 20)
+#define PHPDBG_SIGSAFE_MEM_SIZE ZEND_MM_CHUNK_SIZE
+//(1 << 20)
+
+#include "zend.h"
typedef struct {
char *mem;
zend_bool allocated;
- zend_mm_heap heap;
+ zend_mm_heap *heap;
zend_mm_heap *old_heap;
zend_mm_storage storage;
} phpdbg_signal_safe_mem;
diff --git a/sapi/phpdbg/phpdbg_utils.c b/sapi/phpdbg/phpdbg_utils.c
index 85b6eeb3b5..bff971d4cf 100644
--- a/sapi/phpdbg/phpdbg_utils.c
+++ b/sapi/phpdbg/phpdbg_utils.c
@@ -165,27 +165,25 @@ PHPDBG_API const char *phpdbg_current_file(TSRMLS_D) /* {{{ */
PHPDBG_API const zend_function *phpdbg_get_function(const char *fname, const char *cname TSRMLS_DC) /* {{{ */
{
zend_function *func = NULL;
- size_t fname_len = strlen(fname);
- char *lcname = zend_str_tolower_dup(fname, fname_len);
+ zend_string *lfname = zend_string_alloc(strlen(fname), 0);
+ memcpy(lfname->val, zend_str_tolower_dup(fname, lfname->len), lfname->len + 1);
if (cname) {
- zend_class_entry **ce;
- size_t cname_len = strlen(cname);
- char *lc_cname = zend_str_tolower_dup(cname, cname_len);
- int ret = zend_lookup_class(lc_cname, cname_len, &ce TSRMLS_CC);
+ zend_class_entry *ce;
+ zend_string *lcname = zend_string_alloc(strlen(cname), 0);
+ memcpy(lcname->val, zend_str_tolower_dup(cname, lcname->len), lcname->len + 1);
+ ce = zend_lookup_class(lcname TSRMLS_CC);
- efree(lc_cname);
+ efree(lcname);
- if (ret == SUCCESS) {
- zend_hash_find(&(*ce)->function_table, lcname, fname_len+1,
- (void**)&func);
+ if (ce) {
+ func = zend_hash_find_ptr(&ce->function_table, lfname);
}
} else {
- zend_hash_find(EG(function_table), lcname, fname_len+1,
- (void**)&func);
+ func = zend_hash_find_ptr(EG(function_table), lfname);
}
- efree(lcname);
+ efree(lfname);
return func;
} /* }}} */
@@ -315,18 +313,14 @@ PHPDBG_API const char *phpdbg_get_prompt(TSRMLS_D) /* {{{ */
} /* }}} */
int phpdbg_rebuild_symtable(TSRMLS_D) {
- if (!EG(active_op_array)) {
+ if (!EG(current_execute_data) || !EG(current_execute_data)->func) {
phpdbg_error("inactive", "type=\"op_array\"", "No active op array!");
return FAILURE;
}
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
-
- if (!EG(active_symbol_table)) {
- phpdbg_error("inactive", "type=\"symbol_table\"", "No active symbol table!");
- return FAILURE;
- }
+ if (!zend_rebuild_symbol_table(TSRMLS_C)) {
+ phpdbg_error("inactive", "type=\"symbol_table\"", "No active symbol table!");
+ return FAILURE;
}
return SUCCESS;
@@ -359,10 +353,10 @@ PHPDBG_API void phpdbg_set_async_io(int fd) {
#endif
}
-int phpdbg_safe_class_lookup(const char *name, int name_length, zend_class_entry ***ce TSRMLS_DC) {
+int phpdbg_safe_class_lookup(const char *name, int name_length, zend_class_entry **ce TSRMLS_DC) {
if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) {
char *lc_name, *lc_free;
- int lc_length, ret = FAILURE;
+ int lc_length;
if (name == NULL || !name_length) {
return FAILURE;
@@ -378,16 +372,19 @@ int phpdbg_safe_class_lookup(const char *name, int name_length, zend_class_entry
}
phpdbg_try_access {
- ret = zend_hash_find(EG(class_table), lc_name, lc_length, (void **) &ce);
+ *ce = zend_hash_str_find_ptr(EG(class_table), lc_name, lc_length);
} phpdbg_catch_access {
phpdbg_error("signalsegv", "class=\"%.*s\"", "Could not fetch class %.*s, invalid data source", name_length, name);
} phpdbg_end_try_access();
efree(lc_free);
- return ret;
} else {
- return zend_lookup_class(name, name_length, ce TSRMLS_CC);
+ zend_string *str_name = zend_string_init(name, name_length, 0);
+ *ce = zend_lookup_class(str_name TSRMLS_CC);
+ efree(str_name);
}
+
+ return ce ? SUCCESS : FAILURE;
}
char *phpdbg_get_property_key(char *key) {
@@ -397,7 +394,7 @@ char *phpdbg_get_property_key(char *key) {
return strchr(key + 1, 0) + 1;
}
-static int phpdbg_parse_variable_arg_wrapper(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval **zv, phpdbg_parse_var_func callback TSRMLS_DC) {
+static int phpdbg_parse_variable_arg_wrapper(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval *zv, phpdbg_parse_var_func callback TSRMLS_DC) {
return callback(name, len, keyname, keylen, parent, zv TSRMLS_CC);
}
@@ -410,7 +407,7 @@ PHPDBG_API int phpdbg_parse_variable_with_arg(char *input, size_t len, HashTable
zend_bool new_index = 1;
char *last_index;
size_t index_len = 0;
- zval **zv;
+ zval *zv;
if (len < 2 || *input != '$') {
goto error;
@@ -446,50 +443,64 @@ PHPDBG_API int phpdbg_parse_variable_with_arg(char *input, size_t len, HashTable
}
if (new_index && index_len == 0) {
- HashPosition position;
- for (zend_hash_internal_pointer_reset_ex(parent, &position);
- zend_hash_get_current_data_ex(parent, (void **)&zv, &position) == SUCCESS;
- zend_hash_move_forward_ex(parent, &position)) {
+ zend_ulong numkey;
+ zend_string *strkey;
+ ZEND_HASH_FOREACH_KEY_PTR(parent, numkey, strkey, zv) {
+ while (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+
if (i == len || (i == len - 1 && input[len - 1] == ']')) {
- zval *key = emalloc(sizeof(zval));
- size_t namelen;
+ char *key, *propkey;
+ size_t namelen, keylen;
char *name;
char *keyname = estrndup(last_index, index_len);
- zend_hash_get_current_key_zval_ex(parent, key, &position);
- convert_to_string(key);
- name = emalloc(i + Z_STRLEN_P(key) + 2);
- namelen = sprintf(name, "%.*s%s%s", (int)i, input, phpdbg_get_property_key(Z_STRVAL_P(key)), input[len - 1] == ']'?"]":"");
- efree(key);
+ if (strkey) {
+ key = strkey->val;
+ keylen = strkey->len;
+ } else {
+ keylen = spprintf(&key, 0, "%llu", numkey);
+ }
+ propkey = phpdbg_get_property_key(key);
+ name = emalloc(i + keylen + 2);
+ namelen = sprintf(name, "%.*s%.*s%s", (int) i, input, keylen - (propkey - key), propkey, input[len - 1] == ']'?"]":"");
+ if (!strkey) {
+ efree(key);
+ }
ret = callback(name, namelen, keyname, index_len, parent, zv, arg TSRMLS_CC) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE;
- } else if (Z_TYPE_PP(zv) == IS_OBJECT) {
- phpdbg_parse_variable_with_arg(input, len, Z_OBJPROP_PP(zv), i, callback, silent, arg TSRMLS_CC);
- } else if (Z_TYPE_PP(zv) == IS_ARRAY) {
- phpdbg_parse_variable_with_arg(input, len, Z_ARRVAL_PP(zv), i, callback, silent, arg TSRMLS_CC);
+ } else if (Z_TYPE_P(zv) == IS_OBJECT) {
+ phpdbg_parse_variable_with_arg(input, len, Z_OBJPROP_P(zv), i, callback, silent, arg TSRMLS_CC);
+ } else if (Z_TYPE_P(zv) == IS_ARRAY) {
+ phpdbg_parse_variable_with_arg(input, len, Z_ARRVAL_P(zv), i, callback, silent, arg TSRMLS_CC);
} else {
/* Ignore silently */
}
- }
+ } ZEND_HASH_FOREACH_END();
return ret;
} else if (new_index) {
char last_chr = last_index[index_len];
last_index[index_len] = 0;
- if (zend_symtable_find(parent, last_index, index_len + 1, (void **)&zv) == FAILURE) {
+ if (!(zv = zend_symtable_str_find(parent, last_index, index_len))) {
if (!silent) {
phpdbg_error("variable", "type=\"undefined\" variable=\"%.*s\"", "%.*s is undefined", (int) i, input);
}
return FAILURE;
}
+ while (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+
last_index[index_len] = last_chr;
if (i == len) {
char *name = estrndup(input, len);
char *keyname = estrndup(last_index, index_len);
ret = callback(name, len, keyname, index_len, parent, zv, arg TSRMLS_CC) == SUCCESS || ret == SUCCESS?SUCCESS:FAILURE;
- } else if (Z_TYPE_PP(zv) == IS_OBJECT) {
- parent = Z_OBJPROP_PP(zv);
- } else if (Z_TYPE_PP(zv) == IS_ARRAY) {
- parent = Z_ARRVAL_PP(zv);
+ } else if (Z_TYPE_P(zv) == IS_OBJECT) {
+ parent = Z_OBJPROP_P(zv);
+ } else if (Z_TYPE_P(zv) == IS_ARRAY) {
+ parent = Z_ARRVAL_P(zv);
} else {
phpdbg_error("variable", "type=\"notiterable\" variable=\"%.*s\"", "%.*s is nor an array nor an object", (int) i, input);
return FAILURE;
@@ -504,14 +515,22 @@ PHPDBG_API int phpdbg_parse_variable_with_arg(char *input, size_t len, HashTable
return FAILURE;
}
-static int phpdbg_xml_array_element_dump(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) {
+int phpdbg_is_auto_global(char *name, int len TSRMLS_DC) {
+ int ret;
+ zend_string *str = zend_string_init(name, len, 0);
+ ret = zend_is_auto_global(str TSRMLS_CC);
+ efree(str);
+ return ret;
+}
+
+static int phpdbg_xml_array_element_dump(zval *zv, zend_string *key, zend_ulong num TSRMLS_DC) {
phpdbg_xml("<element");
phpdbg_try_access {
- if (hash_key->nKeyLength == 0) { /* numeric key */
- phpdbg_xml(" name=\"%ld\"", hash_key->h);
- } else { /* string key */
- phpdbg_xml(" name=\"%.*s\"", hash_key->nKeyLength - 1, hash_key->arKey);
+ if (key) { /* string key */
+ phpdbg_xml(" name=\"%.*s\"", key->len, key->val);
+ } else { /* numeric key */
+ phpdbg_xml(" name=\"%ld\"", num);
}
} phpdbg_catch_access {
phpdbg_xml(" severity=\"error\" ></element>");
@@ -527,15 +546,13 @@ static int phpdbg_xml_array_element_dump(zval **zv TSRMLS_DC, int num_args, va_l
return 0;
}
-static int phpdbg_xml_object_property_dump(zval **zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) {
+static int phpdbg_xml_object_property_dump(zval *zv, zend_string *key, zend_ulong num TSRMLS_DC) {
phpdbg_xml("<property");
phpdbg_try_access {
- if (hash_key->nKeyLength == 0) { /* numeric key */
- phpdbg_xml(" name=\"%ld\"", hash_key->h);
- } else { /* string key */
+ if (key) { /* string key */
const char *prop_name, *class_name;
- int unmangle = zend_unmangle_property_name(hash_key->arKey, hash_key->nKeyLength - 1, &class_name, &prop_name);
+ int unmangle = zend_unmangle_property_name(key, &class_name, &prop_name);
if (class_name && unmangle == SUCCESS) {
phpdbg_xml(" name=\"%s\"", prop_name);
@@ -545,8 +562,10 @@ static int phpdbg_xml_object_property_dump(zval **zv TSRMLS_DC, int num_args, va
phpdbg_xml(" class=\"%s\" protection=\"private\"", class_name);
}
} else {
- phpdbg_xml(" name=\"%.*s\" protection=\"public\"", hash_key->nKeyLength - 1, hash_key->arKey);
+ phpdbg_xml(" name=\"%.*s\" protection=\"public\"", key->len, key->val);
}
+ } else { /* numeric key */
+ phpdbg_xml(" name=\"%ld\" protection=\"public\"", num);
}
} phpdbg_catch_access {
phpdbg_xml(" severity=\"error\" ></property>");
@@ -562,37 +581,46 @@ static int phpdbg_xml_object_property_dump(zval **zv TSRMLS_DC, int num_args, va
return 0;
}
-#define COMMON (Z_ISREF_PP(zv) ? "&" : "")
+#define COMMON (is_ref ? "&" : "")
-PHPDBG_API void phpdbg_xml_var_dump(zval **zv TSRMLS_DC) {
+PHPDBG_API void phpdbg_xml_var_dump(zval *zv TSRMLS_DC) {
HashTable *myht;
- const char *class_name;
- zend_uint class_name_len;
- int (*element_dump_func)(zval** TSRMLS_DC, int, va_list, zend_hash_key*);
+ zend_string *class_name, *key;
+ zend_ulong num;
+ zval *val;
+ int (*element_dump_func)(zval *zv, zend_string *key, zend_ulong num TSRMLS_DC);
+ zend_bool is_ref = 0;
+
int is_temp;
phpdbg_try_access {
- switch (Z_TYPE_PP(zv)) {
- case IS_BOOL:
- phpdbg_xml("<bool refstatus=\"%s\" value=\"%s\" />", COMMON, Z_LVAL_PP(zv) ? "true" : "false");
+ is_ref = Z_ISREF_P(zv) && GC_REFCOUNT(Z_COUNTED_P(zv)) > 1;
+ ZVAL_DEREF(zv);
+
+ switch (Z_TYPE_P(zv)) {
+ case IS_TRUE:
+ phpdbg_xml("<bool refstatus=\"%s\" value=\"true\" />", COMMON);
+ break;
+ case IS_FALSE:
+ phpdbg_xml("<bool refstatus=\"%s\" value=\"false\" />", COMMON);
break;
case IS_NULL:
phpdbg_xml("<null refstatus=\"%s\" />", COMMON);
break;
case IS_LONG:
- phpdbg_xml("<int refstatus=\"%s\" value=\"%ld\" />", COMMON, Z_LVAL_PP(zv));
+ phpdbg_xml("<int refstatus=\"%s\" value=\"" ZEND_LONG_FMT "\" />", COMMON, Z_LVAL_P(zv));
break;
case IS_DOUBLE:
- phpdbg_xml("<float refstatus=\"%s\" value=\"%.*G\" />", COMMON, (int) EG(precision), Z_DVAL_PP(zv));
+ phpdbg_xml("<float refstatus=\"%s\" value=\"%.*G\" />", COMMON, (int) EG(precision), Z_DVAL_P(zv));
break;
case IS_STRING:
- phpdbg_xml("<string refstatus=\"%s\" length=\"%d\" value=\"%.*s\" />", COMMON, Z_STRLEN_PP(zv), Z_STRLEN_PP(zv), Z_STRVAL_PP(zv));
- break;
+ phpdbg_xml("<string refstatus=\"%s\" length=\"%d\" value=\"%.*s\" />", COMMON, Z_STRLEN_P(zv), Z_STRLEN_P(zv), Z_STRVAL_P(zv));
+ break;
case IS_ARRAY:
- myht = Z_ARRVAL_PP(zv);
- if (++myht->nApplyCount > 1) {
+ myht = Z_ARRVAL_P(zv);
+ if (ZEND_HASH_APPLY_PROTECTION(myht) && ++myht->u.v.nApplyCount > 1) {
phpdbg_xml("<recursion />");
- --myht->nApplyCount;
+ --myht->u.v.nApplyCount;
break;
}
phpdbg_xml("<array refstatus=\"%s\" num=\"%d\">", COMMON, zend_hash_num_elements(myht));
@@ -600,39 +628,39 @@ PHPDBG_API void phpdbg_xml_var_dump(zval **zv TSRMLS_DC) {
is_temp = 0;
goto head_done;
case IS_OBJECT:
- myht = Z_OBJDEBUG_PP(zv, is_temp);
- if (myht && ++myht->nApplyCount > 1) {
+ myht = Z_OBJDEBUG_P(zv, is_temp);
+ if (myht && ++myht->u.v.nApplyCount > 1) {
phpdbg_xml("<recursion />");
- --myht->nApplyCount;
+ --myht->u.v.nApplyCount;
break;
}
-
- if (Z_OBJ_HANDLER(**zv, get_class_name)) {
- Z_OBJ_HANDLER(**zv, get_class_name)(*zv, &class_name, &class_name_len, 0 TSRMLS_CC);
- phpdbg_xml("<object refstatus=\"%s\" class=\"%s\" id=\"%d\" num=\"%d\">", COMMON, class_name, Z_OBJ_HANDLE_PP(zv), myht ? zend_hash_num_elements(myht) : 0);
- efree((char*)class_name);
- } else {
- phpdbg_xml("<object refstatus=\"%s\" class=\"\" id=\"%d\" num=\"%d\">", COMMON, Z_OBJ_HANDLE_PP(zv), myht ? zend_hash_num_elements(myht) : 0);
- }
+
+ class_name = Z_OBJ_HANDLER_P(zv, get_class_name)(Z_OBJ_P(zv) TSRMLS_CC);
+ phpdbg_xml("<object refstatus=\"%s\" class=\"%.*s\" id=\"%d\" num=\"%d\">", COMMON, class_name->len, class_name->val, Z_OBJ_HANDLE_P(zv), myht ? zend_hash_num_elements(myht) : 0);
+ zend_string_release(class_name);
+
element_dump_func = phpdbg_xml_object_property_dump;
head_done:
if (myht) {
+ ZEND_HASH_FOREACH_KEY_VAL_IND(myht, num, key, val) {
+ element_dump_func(val, key, num TSRMLS_CC);
+ } ZEND_HASH_FOREACH_END();
zend_hash_apply_with_arguments(myht TSRMLS_CC, (apply_func_args_t) element_dump_func, 0);
- --myht->nApplyCount;
+ --myht->u.v.nApplyCount;
if (is_temp) {
zend_hash_destroy(myht);
efree(myht);
}
}
- if (Z_TYPE_PP(zv) == IS_ARRAY) {
+ if (Z_TYPE_P(zv) == IS_ARRAY) {
phpdbg_xml("</array>");
} else {
phpdbg_xml("</object>");
}
break;
case IS_RESOURCE: {
- const char *type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(zv) TSRMLS_CC);
- phpdbg_xml("<resource refstatus=\"%s\" id=\"%ld\" type=\"%ld\" />", COMMON, Z_LVAL_PP(zv), type_name ? type_name : "unknown");
+ const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(zv) TSRMLS_CC);
+ phpdbg_xml("<resource refstatus=\"%s\" id=\"%pd\" type=\"%ld\" />", COMMON, Z_RES_P(zv)->handle, type_name ? type_name : "unknown");
break;
}
default:
diff --git a/sapi/phpdbg/phpdbg_utils.h b/sapi/phpdbg/phpdbg_utils.h
index d657dc79fd..83dc8e9694 100644
--- a/sapi/phpdbg/phpdbg_utils.h
+++ b/sapi/phpdbg/phpdbg_utils.h
@@ -80,36 +80,18 @@ PHPDBG_API void phpdbg_set_async_io(int fd);
int phpdbg_rebuild_symtable(TSRMLS_D);
-#if PHP_VERSION_ID < 50500
-/* copy from zend_hash.c PHP 5.5 for 5.4 compatibility */
-static void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos) {
- Bucket *p;
-
- p = pos ? (*pos) : ht->pInternalPointer;
-
- if (!p) {
- Z_TYPE_P(key) = IS_NULL;
- } else if (p->nKeyLength) {
- Z_TYPE_P(key) = IS_STRING;
- Z_STRVAL_P(key) = IS_INTERNED(p->arKey) ? (char*)p->arKey : estrndup(p->arKey, p->nKeyLength - 1);
- Z_STRLEN_P(key) = p->nKeyLength - 1;
- } else {
- Z_TYPE_P(key) = IS_LONG;
- Z_LVAL_P(key) = p->h;
- }
-}
-#endif
-
-int phpdbg_safe_class_lookup(const char *name, int name_length, zend_class_entry ***ce TSRMLS_DC);
+int phpdbg_safe_class_lookup(const char *name, int name_length, zend_class_entry **ce TSRMLS_DC);
char *phpdbg_get_property_key(char *key);
-typedef int (*phpdbg_parse_var_func)(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval **zv TSRMLS_DC);
-typedef int (*phpdbg_parse_var_with_arg_func)(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval **zv, void *arg TSRMLS_DC);
+typedef int (*phpdbg_parse_var_func)(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval *zv TSRMLS_DC);
+typedef int (*phpdbg_parse_var_with_arg_func)(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval *zv, void *arg TSRMLS_DC);
PHPDBG_API int phpdbg_parse_variable(char *input, size_t len, HashTable *parent, size_t i, phpdbg_parse_var_func callback, zend_bool silent TSRMLS_DC);
PHPDBG_API int phpdbg_parse_variable_with_arg(char *input, size_t len, HashTable *parent, size_t i, phpdbg_parse_var_with_arg_func callback, zend_bool silent, void *arg TSRMLS_DC);
-PHPDBG_API void phpdbg_xml_var_dump(zval **zv TSRMLS_DC);
+int phpdbg_is_auto_global(char *name, int len TSRMLS_DC);
+
+PHPDBG_API void phpdbg_xml_var_dump(zval *zv TSRMLS_DC);
#endif /* PHPDBG_UTILS_H */
diff --git a/sapi/phpdbg/phpdbg_wait.c b/sapi/phpdbg/phpdbg_wait.c
index ea506a2d93..9051ca379f 100644
--- a/sapi/phpdbg/phpdbg_wait.c
+++ b/sapi/phpdbg/phpdbg_wait.c
@@ -25,19 +25,19 @@ ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
ZEND_EXTERN_MODULE_GLOBALS(json);
static void phpdbg_rebuild_http_globals_array(int type, const char *name TSRMLS_DC) {
- zval **zvpp;
- if (PG(http_globals)[type]) {
- zval_dtor(PG(http_globals)[type]);
+ zval *zvp;
+ if (Z_TYPE(PG(http_globals)[type]) != IS_UNDEF) {
+ zval_dtor(&PG(http_globals)[type]);
}
- if (zend_hash_find(&EG(symbol_table), name, strlen(name) + 1, (void **) &zvpp) == SUCCESS) {
- Z_SET_REFCOUNT_PP(zvpp, 2);
- PG(http_globals)[type] = *zvpp;
+ if ((zvp = zend_hash_str_find(&EG(symbol_table).ht, name, strlen(name)))) {
+ Z_ADDREF_P(zvp);
+ PG(http_globals)[type] = *zvp;
}
}
static int phpdbg_dearm_autoglobals(zend_auto_global *auto_global TSRMLS_DC) {
- if (auto_global->name_len != sizeof("GLOBALS") - 1 || memcmp(auto_global->name, "GLOBALS", sizeof("GLOBALS") - 1)) {
+ if (auto_global->name->len != sizeof("GLOBALS") - 1 || memcmp(auto_global->name->val, "GLOBALS", sizeof("GLOBALS") - 1)) {
auto_global->armed = 0;
}
@@ -57,8 +57,8 @@ static int phpdbg_array_data_compare(const void *a, const void *b TSRMLS_DC) {
f = *((Bucket **) a);
s = *((Bucket **) b);
- first = *((zval **) f->pData);
- second = *((zval **) s->pData);
+ first = &f->val;
+ second = &s->val;
if (string_compare_function(&result, first, second TSRMLS_CC) == FAILURE) {
return 0;
@@ -85,16 +85,15 @@ static void phpdbg_array_intersect_init(phpdbg_intersect_ptr *info, HashTable *h
}
/* -1 => first array, 0 => both arrays equal, 1 => second array */
-static int phpdbg_array_intersect(phpdbg_intersect_ptr *info, zval ***ptr) {
+static int phpdbg_array_intersect(phpdbg_intersect_ptr *info, zval **ptr) {
int ret;
- zval **zvpp[2];
+ zval *zvp[2];
int invalid = !info->ht[0] + !info->ht[1];
if (invalid > 0) {
invalid = !info->ht[0];
- if (zend_hash_get_current_data_ex(info->ht[invalid], (void **) ptr, &info->pos[invalid]) == FAILURE) {
- *ptr = NULL;
+ if (!(*ptr = zend_hash_get_current_data_ex(info->ht[invalid], &info->pos[invalid]))) {
return 0;
}
@@ -103,23 +102,23 @@ static int phpdbg_array_intersect(phpdbg_intersect_ptr *info, zval ***ptr) {
return invalid ? 1 : -1;
}
- if (zend_hash_get_current_data_ex(info->ht[0], (void **) &zvpp[0], &info->pos[0]) == FAILURE) {
+ if (!(zvp[0] = zend_hash_get_current_data_ex(info->ht[0], &info->pos[0]))) {
info->ht[0] = NULL;
return phpdbg_array_intersect(info, ptr);
}
- if (zend_hash_get_current_data_ex(info->ht[1], (void **) &zvpp[1], &info->pos[1]) == FAILURE) {
+ if (!(zvp[1] = zend_hash_get_current_data_ex(info->ht[1], &info->pos[1]))) {
info->ht[1] = NULL;
return phpdbg_array_intersect(info, ptr);
}
- ret = zend_binary_zval_strcmp(*zvpp[0], *zvpp[1]);
+ ret = zend_binary_zval_strcmp(zvp[0], zvp[1]);
if (ret <= 0) {
- *ptr = zvpp[0];
+ *ptr = zvp[0];
zend_hash_move_forward_ex(info->ht[0], &info->pos[0]);
}
if (ret >= 0) {
- *ptr = zvpp[1];
+ *ptr = zvp[1];
zend_hash_move_forward_ex(info->ht[1], &info->pos[1]);
}
@@ -129,7 +128,7 @@ static int phpdbg_array_intersect(phpdbg_intersect_ptr *info, zval ***ptr) {
void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) {
#ifdef HAVE_JSON
zval *free_zv = NULL;
- zval zv, **zvpp;
+ zval zv, *zvp;
HashTable *ht;
php_json_decode(&zv, msg, len, 1, 1000 /* enough */ TSRMLS_CC);
@@ -141,14 +140,14 @@ void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) {
ht = Z_ARRVAL(zv);
/* Reapply symbol table */
- if (zend_hash_find(ht, "GLOBALS", sizeof("GLOBALS"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) {
+ if ((zvp = zend_hash_str_find(ht, ZEND_STRL("GLOBALS"))) && Z_TYPE_P(zvp) == IS_ARRAY) {
{
- zval **srv;
- if (zend_hash_find(Z_ARRVAL_PP(zvpp), "_SERVER", sizeof("_SERVER"), (void **) &srv) == SUCCESS && Z_TYPE_PP(srv) == IS_ARRAY) {
- zval **script;
- if (zend_hash_find(Z_ARRVAL_PP(srv), "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME"), (void **) &script) == SUCCESS && Z_TYPE_PP(script) == IS_STRING) {
+ zval *srv;
+ if ((srv = zend_hash_str_find(Z_ARRVAL_P(zvp), ZEND_STRL("_SERVER"))) && Z_TYPE_P(srv) == IS_ARRAY) {
+ zval *script;
+ if ((script = zend_hash_str_find(Z_ARRVAL_P(srv), ZEND_STRL("SCRIPT_FILENAME"))) && Z_TYPE_P(script) == IS_STRING) {
phpdbg_param_t param;
- param.str = Z_STRVAL_PP(script);
+ param.str = Z_STRVAL_P(script);
PHPDBG_COMMAND_HANDLER(exec)(&param TSRMLS_CC);
}
}
@@ -157,8 +156,8 @@ void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) {
PG(auto_globals_jit) = 0;
zend_hash_apply(CG(auto_globals), (apply_func_t) phpdbg_dearm_autoglobals TSRMLS_CC);
- zend_hash_clean(&EG(symbol_table));
- EG(symbol_table) = *Z_ARRVAL_PP(zvpp);
+ zend_hash_clean(&EG(symbol_table).ht);
+ EG(symbol_table) = *Z_ARR_P(zvp);
/* Rebuild cookies, env vars etc. from GLOBALS (PG(http_globals)) */
phpdbg_rebuild_http_globals_array(TRACK_VARS_POST, "_POST" TSRMLS_CC);
@@ -168,21 +167,21 @@ void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) {
phpdbg_rebuild_http_globals_array(TRACK_VARS_ENV, "_ENV" TSRMLS_CC);
phpdbg_rebuild_http_globals_array(TRACK_VARS_FILES, "_FILES" TSRMLS_CC);
- Z_ADDREF_PP(zvpp);
- free_zv = *zvpp;
+ Z_ADDREF_P(zvp);
+ free_zv = zvp;
}
- if (zend_hash_find(ht, "input", sizeof("input"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_STRING) {
+ if ((zvp = zend_hash_str_find(ht, ZEND_STRL("input"))) && Z_TYPE_P(zvp) == IS_STRING) {
if (SG(request_info).request_body) {
php_stream_close(SG(request_info).request_body);
}
SG(request_info).request_body = php_stream_temp_create_ex(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE, PG(upload_tmp_dir));
php_stream_truncate_set_size(SG(request_info).request_body, 0);
- php_stream_write(SG(request_info).request_body, Z_STRVAL_PP(zvpp), Z_STRLEN_PP(zvpp));
+ php_stream_write(SG(request_info).request_body, Z_STRVAL_P(zvp), Z_STRLEN_P(zvp));
}
- if (zend_hash_find(ht, "cwd", sizeof("cwd"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_STRING) {
- if (VCWD_CHDIR(Z_STRVAL_PP(zvpp)) == SUCCESS) {
+ if ((zvp = zend_hash_str_find(ht, ZEND_STRL("cwd"))) && Z_TYPE_P(zvp) == IS_STRING) {
+ if (VCWD_CHDIR(Z_STRVAL_P(zvp)) == SUCCESS) {
if (BG(CurrentStatFile) && !IS_ABSOLUTE_PATH(BG(CurrentStatFile), strlen(BG(CurrentStatFile)))) {
efree(BG(CurrentStatFile));
BG(CurrentStatFile) = NULL;
@@ -194,50 +193,46 @@ void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) {
}
}
- if (zend_hash_find(ht, "sapi_name", sizeof("sapi_name"), (void **) &zvpp) == SUCCESS && (Z_TYPE_PP(zvpp) == IS_STRING || Z_TYPE_PP(zvpp) == IS_NULL)) {
+ if ((zvp = zend_hash_str_find(ht, ZEND_STRL("sapi_name"))) && (Z_TYPE_P(zvp) == IS_STRING || Z_TYPE_P(zvp) == IS_NULL)) {
if (PHPDBG_G(sapi_name_ptr)) {
free(PHPDBG_G(sapi_name_ptr));
}
- if (Z_TYPE_PP(zvpp) == IS_STRING) {
- PHPDBG_G(sapi_name_ptr) = sapi_module.name = strdup(Z_STRVAL_PP(zvpp));
+ if (Z_TYPE_P(zvp) == IS_STRING) {
+ PHPDBG_G(sapi_name_ptr) = sapi_module.name = strdup(Z_STRVAL_P(zvp));
} else {
PHPDBG_G(sapi_name_ptr) = sapi_module.name = NULL;
}
}
- if (zend_hash_find(ht, "modules", sizeof("modules"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) {
- HashPosition position;
+ if ((zvp = zend_hash_str_find(ht, ZEND_STRL("modules"))) && Z_TYPE_P(zvp) == IS_ARRAY) {
phpdbg_intersect_ptr pos;
- zval **module;
+ zval *module;
zend_module_entry *mod;
HashTable zv_registry;
/* intersect modules, unregister modules loaded "too much", announce not yet registered modules (phpdbg_notice) */
zend_hash_init(&zv_registry, zend_hash_num_elements(&module_registry), 0, ZVAL_PTR_DTOR, 0);
- for (zend_hash_internal_pointer_reset_ex(&module_registry, &position);
- zend_hash_get_current_data_ex(&module_registry, (void **) &mod, &position) == SUCCESS;
- zend_hash_move_forward_ex(&module_registry, &position)) {
+ ZEND_HASH_FOREACH_PTR(&module_registry, mod) {
if (mod->name) {
- zval **value = emalloc(sizeof(zval *));
- MAKE_STD_ZVAL(*value);
- ZVAL_STRING(*value, mod->name, 1);
- zend_hash_next_index_insert(&zv_registry, value, sizeof(zval *), NULL);
+ zval value;
+ ZVAL_NEW_STR(&value, zend_string_init(mod->name, strlen(mod->name), 0));
+ zend_hash_next_index_insert(&zv_registry, &value);
}
- }
+ } ZEND_HASH_FOREACH_END();
- phpdbg_array_intersect_init(&pos, &zv_registry, Z_ARRVAL_PP(zvpp) TSRMLS_CC);
+ phpdbg_array_intersect_init(&pos, &zv_registry, Z_ARRVAL_P(zvp) TSRMLS_CC);
do {
int mode = phpdbg_array_intersect(&pos, &module);
if (mode < 0) {
// loaded module, but not needed
- if (strcmp(PHPDBG_NAME, Z_STRVAL_PP(module))) {
- zend_hash_del(&module_registry, Z_STRVAL_PP(module), Z_STRLEN_PP(module) + 1);
+ if (strcmp(PHPDBG_NAME, Z_STRVAL_P(module))) {
+ zend_hash_del(&module_registry, Z_STR_P(module));
}
} else if (mode > 0) {
// not loaded module
- if (!sapi_module.name || strcmp(sapi_module.name, Z_STRVAL_PP(module))) {
- phpdbg_notice("wait", "missingmodule=\"%.*s\"", "The module %.*s isn't present in " PHPDBG_NAME ", you still can load via dl /path/to/module/%.*s.so", Z_STRLEN_PP(module), Z_STRVAL_PP(module), Z_STRLEN_PP(module), Z_STRVAL_PP(module));
+ if (!sapi_module.name || strcmp(sapi_module.name, Z_STRVAL_P(module))) {
+ phpdbg_notice("wait", "missingmodule=\"%.*s\"", "The module %.*s isn't present in " PHPDBG_NAME ", you still can load via dl /path/to/module/%.*s.so", Z_STRLEN_P(module), Z_STRVAL_P(module), Z_STRLEN_P(module), Z_STRVAL_P(module));
}
}
} while (module);
@@ -245,26 +240,25 @@ void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) {
zend_hash_clean(&zv_registry);
}
- if (zend_hash_find(ht, "extensions", sizeof("extensions"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) {
+ if ((zvp = zend_hash_str_find(ht, ZEND_STRL("extensions"))) && Z_TYPE_P(zvp) == IS_ARRAY) {
zend_extension *extension;
zend_llist_position pos;
- HashPosition hpos;
- zval **name, key;
+ zval *name = NULL;
+ zend_string *strkey;
extension = (zend_extension *) zend_llist_get_first_ex(&zend_extensions, &pos);
while (extension) {
extension = (zend_extension *) zend_llist_get_next_ex(&zend_extensions, &pos);
- /* php_serach_array() body should be in some ZEND_API function */
- for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(zvpp), &hpos);
- zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void **) &name, &hpos) == SUCCESS;
- zend_hash_move_forward_ex(Z_ARRVAL_PP(zvpp), &hpos)) {
- if (Z_TYPE_PP(name) == IS_STRING && !zend_binary_strcmp(extension->name, strlen(extension->name), Z_STRVAL_PP(name), Z_STRLEN_PP(name))) {
+ /* php_serach_array() body should be in some ZEND_API function... */
+ ZEND_HASH_FOREACH_STR_KEY_PTR(Z_ARRVAL_P(zvp), strkey, name) {
+ if (Z_TYPE_P(name) == IS_STRING && !zend_binary_strcmp(extension->name, strlen(extension->name), Z_STRVAL_P(name), Z_STRLEN_P(name))) {
break;
}
- }
+ name = NULL;
+ } ZEND_HASH_FOREACH_END();
- if (zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void **) &zvpp, &hpos) == FAILURE) {
+ if (name) {
/* sigh, breaking the encapsulation, there aren't any functions manipulating the llist at the place of the zend_llist_position */
zend_llist_element *elm = pos;
if (elm->prev) {
@@ -288,66 +282,53 @@ void phpdbg_webdata_decompress(char *msg, int len TSRMLS_DC) {
pefree(elm, zend_extensions.persistent);
zend_extensions.count--;
} else {
- zend_hash_get_current_key_zval_ex(Z_ARRVAL_PP(zvpp), &key, &hpos);
+/* zend_hash_get_current_key_zval_ex(Z_ARRVAL_PP(zvpp), &key, &hpos);
if (Z_TYPE(key) == IS_LONG) {
zend_hash_index_del(Z_ARRVAL_PP(zvpp), Z_LVAL(key));
}
+*/
+ zend_hash_del(Z_ARRVAL_P(zvp), strkey);
}
+ }
- for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(zvpp), &hpos);
- zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void **) &name, &hpos) == SUCCESS;
- zend_hash_move_forward_ex(Z_ARRVAL_PP(zvpp), &hpos)) {
- phpdbg_notice("wait", "missingextension=\"%.*s\"", "The Zend extension %.*s isn't present in " PHPDBG_NAME ", you still can load via dl /path/to/extension.so", Z_STRLEN_PP(name), Z_STRVAL_PP(name));
+ ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(zvp), name) {
+ if (Z_TYPE_P(name) == IS_STRING) {
+ phpdbg_notice("wait", "missingextension=\"%.*s\"", "The Zend extension %.*s isn't present in " PHPDBG_NAME ", you still can load via dl /path/to/extension.so", Z_STRLEN_P(name), Z_STRVAL_P(name));
}
- }
+ } ZEND_HASH_FOREACH_END();
}
zend_ini_deactivate(TSRMLS_C);
- if (zend_hash_find(ht, "systemini", sizeof("systemini"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) {
- HashPosition position;
- zval **ini_entry;
+ if ((zvp = zend_hash_str_find(ht, ZEND_STRL("systemini"))) && Z_TYPE_P(zvp) == IS_ARRAY) {
+ zval *ini_entry;
zend_ini_entry *original_ini;
- zval key;
-
- for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(zvpp), &position);
- zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void**) &ini_entry, &position) == SUCCESS;
- zend_hash_move_forward_ex(Z_ARRVAL_PP(zvpp), &position)) {
- zend_hash_get_current_key_zval_ex(Z_ARRVAL_PP(zvpp), &key, &position);
- if (Z_TYPE(key) == IS_STRING) {
- if (Z_TYPE_PP(ini_entry) == IS_STRING) {
- if (zend_hash_find(EG(ini_directives), Z_STRVAL(key), Z_STRLEN(key) + 1, (void **) &original_ini) == SUCCESS) {
- if (!original_ini->on_modify || original_ini->on_modify(original_ini, Z_STRVAL_PP(ini_entry), Z_STRLEN_PP(ini_entry), original_ini->mh_arg1, original_ini->mh_arg2, original_ini->mh_arg3, ZEND_INI_STAGE_ACTIVATE TSRMLS_CC) == SUCCESS) {
- if (original_ini->modified && original_ini->orig_value != original_ini->value) {
- efree(original_ini->value);
- }
- original_ini->value = Z_STRVAL_PP(ini_entry);
- original_ini->value_length = Z_STRLEN_PP(ini_entry);
- Z_TYPE_PP(ini_entry) = IS_NULL; /* don't free the value */
+ zend_string *key;
+
+ ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(zvp), key, ini_entry) {
+ if (key && Z_TYPE_P(ini_entry) == IS_STRING) {
+ if ((original_ini = zend_hash_find_ptr(EG(ini_directives), key))) {
+ if (!original_ini->on_modify || original_ini->on_modify(original_ini, Z_STR_P(ini_entry), original_ini->mh_arg1, original_ini->mh_arg2, original_ini->mh_arg3, ZEND_INI_STAGE_ACTIVATE TSRMLS_CC) == SUCCESS) {
+ if (original_ini->modified && original_ini->orig_value != original_ini->value) {
+ efree(original_ini->value);
}
+ original_ini->value = Z_STR_P(ini_entry);
+ Z_ADDREF_P(ini_entry); /* don't free the string */
}
}
- efree(Z_STRVAL(key));
}
- }
+ } ZEND_HASH_FOREACH_END();
}
- if (zend_hash_find(ht, "userini", sizeof("userini"), (void **) &zvpp) == SUCCESS && Z_TYPE_PP(zvpp) == IS_ARRAY) {
- HashPosition position;
- zval **ini_entry;
- zval key;
-
- for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(zvpp), &position);
- zend_hash_get_current_data_ex(Z_ARRVAL_PP(zvpp), (void**) &ini_entry, &position) == SUCCESS;
- zend_hash_move_forward_ex(Z_ARRVAL_PP(zvpp), &position)) {
- zend_hash_get_current_key_zval_ex(Z_ARRVAL_PP(zvpp), &key, &position);
- if (Z_TYPE(key) == IS_STRING) {
- if (Z_TYPE_PP(ini_entry) == IS_STRING) {
- zend_alter_ini_entry_ex(Z_STRVAL(key), Z_STRLEN(key) + 1, Z_STRVAL_PP(ini_entry), Z_STRLEN_PP(ini_entry), ZEND_INI_PERDIR, ZEND_INI_STAGE_HTACCESS, 1 TSRMLS_CC);
- }
- efree(Z_STRVAL(key));
+ if ((zvp = zend_hash_str_find(ht, ZEND_STRL("userini"))) && Z_TYPE_P(zvp) == IS_ARRAY) {
+ zval *ini_entry;
+ zend_string *key;
+
+ ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(zvp), key, ini_entry) {
+ if (key && Z_TYPE_P(ini_entry) == IS_STRING) {
+ zend_alter_ini_entry_ex(key, Z_STR_P(ini_entry), ZEND_INI_PERDIR, ZEND_INI_STAGE_HTACCESS, 1 TSRMLS_CC);
}
- }
+ } ZEND_HASH_FOREACH_END();
}
zval_dtor(&zv);
diff --git a/sapi/phpdbg/phpdbg_watch.c b/sapi/phpdbg/phpdbg_watch.c
index de6cddf5b3..7a39d3ee1a 100644
--- a/sapi/phpdbg/phpdbg_watch.c
+++ b/sapi/phpdbg/phpdbg_watch.c
@@ -30,6 +30,16 @@
ZEND_EXTERN_MODULE_GLOBALS(phpdbg);
+const phpdbg_command_t phpdbg_watch_commands[] = {
+ PHPDBG_COMMAND_D_EX(array, "create watchpoint on an array", 'a', watch_array, NULL, "s", 0),
+ PHPDBG_COMMAND_D_EX(delete, "delete watchpoint", 'd', watch_delete, NULL, "s", 0),
+ PHPDBG_COMMAND_D_EX(recursive, "create recursive watchpoints", 'r', watch_recursive, NULL, "s", 0),
+ PHPDBG_END_COMMAND
+};
+
+//#define HT_FROM_WATCH(watch) (watch->type == WATCH_ON_OBJECT ? watch->addr.obj->handlers->get_properties(watch->parent_container.zv TSRMLS_CC) : watch->type == WATCH_ON_ARRAY ? &watch->addr.arr->ht : NULL)
+#define HT_FROM_ZVP(zvp) (Z_TYPE_P(zvp) == IS_OBJECT ? Z_OBJPROP_P(zvp) : Z_TYPE_P(zvp) == IS_ARRAY ? Z_ARRVAL_P(zvp) : NULL)
+
typedef struct {
void *page;
size_t size;
@@ -52,7 +62,7 @@ static phpdbg_watchpoint_t *phpdbg_check_for_watchpoint(void *addr TSRMLS_DC) {
watch = result->ptr;
/* check if that addr is in a mprotect()'ed memory area */
- if ((char *)phpdbg_get_page_boundary(watch->addr.ptr) > (char *)addr || (char *)phpdbg_get_page_boundary(watch->addr.ptr) + phpdbg_get_total_page_size(watch->addr.ptr, watch->size) < (char *)addr) {
+ if ((char *) phpdbg_get_page_boundary(watch->addr.ptr) > (char *) addr || (char *) phpdbg_get_page_boundary(watch->addr.ptr) + phpdbg_get_total_page_size(watch->addr.ptr, watch->size) < (char *) addr) {
/* failure */
return NULL;
}
@@ -61,10 +71,8 @@ static phpdbg_watchpoint_t *phpdbg_check_for_watchpoint(void *addr TSRMLS_DC) {
}
static void phpdbg_change_watchpoint_access(phpdbg_watchpoint_t *watch, int access TSRMLS_DC) {
- int m;
-
/* pagesize is assumed to be in the range of 2^x */
- m = mprotect(phpdbg_get_page_boundary(watch->addr.ptr), phpdbg_get_total_page_size(watch->addr.ptr, watch->size), access);
+ mprotect(phpdbg_get_page_boundary(watch->addr.ptr), phpdbg_get_total_page_size(watch->addr.ptr, watch->size), access);
}
static inline void phpdbg_activate_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) {
@@ -76,11 +84,11 @@ static inline void phpdbg_deactivate_watchpoint(phpdbg_watchpoint_t *watch TSRML
}
static inline void phpdbg_store_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) {
- phpdbg_btree_insert(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr, watch);
+ phpdbg_btree_insert(&PHPDBG_G(watchpoint_tree), (zend_ulong) watch->addr.ptr, watch);
}
static inline void phpdbg_remove_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) {
- phpdbg_btree_delete(&PHPDBG_G(watchpoint_tree), (zend_ulong)watch->addr.ptr);
+ phpdbg_btree_delete(&PHPDBG_G(watchpoint_tree), (zend_ulong) watch->addr.ptr);
}
void phpdbg_create_addr_watchpoint(void *addr, size_t size, phpdbg_watchpoint_t *watch) {
@@ -98,17 +106,95 @@ void phpdbg_create_ht_watchpoint(HashTable *ht, phpdbg_watchpoint_t *watch) {
watch->type = WATCH_ON_HASHTABLE;
}
-void phpdbg_watch_HashTable_dtor(zval **ptr);
+void phpdbg_watch_HashTable_dtor(zval *ptr);
+
+static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *tmp_watch TSRMLS_DC);
+static void phpdbg_delete_ht_watchpoints_recursive(phpdbg_watchpoint_t *watch TSRMLS_DC);
+static void phpdbg_delete_zval_watchpoints_recursive(phpdbg_watchpoint_t *watch TSRMLS_DC);
+static void phpdbg_delete_watchpoints_recursive(phpdbg_watchpoint_t *watch TSRMLS_DC);
+
+/* TODO: Store all the possible watches the refcounted may refer to (for displaying & deleting by identifier) */
+
+static phpdbg_watchpoint_t *phpdbg_create_refcounted_watchpoint(phpdbg_watchpoint_t *parent, zend_refcounted *ref) {
+ phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t));
+ watch->flags = parent->flags;
+ watch->parent = parent;
+ phpdbg_create_addr_watchpoint(&ref->refcount, sizeof(uint32_t), watch);
+ watch->type = WATCH_ON_REFCOUNTED;
+
+ return watch;
+}
+
+static void phpdbg_add_watch_collision(phpdbg_watchpoint_t *watch TSRMLS_DC) {
+ phpdbg_watch_collision *cur;
+ if ((cur = zend_hash_index_find_ptr(&PHPDBG_G(watch_collisions), (zend_ulong) watch->addr.ref))) {
+ cur->num++;
+ if (watch->flags == PHPDBG_WATCH_RECURSIVE) {
+ cur->refs++;
+ }
+ } else {
+ phpdbg_watch_collision coll;
+ coll.num = 1;
+ coll.refs = watch->flags == PHPDBG_WATCH_RECURSIVE;
+ coll.watch = *watch;
+ zend_hash_init(&coll.watches, 8, NULL, NULL, 0);
+ cur = zend_hash_index_add_mem(&PHPDBG_G(watch_collisions), (zend_ulong) watch->addr.ref, &coll, sizeof(phpdbg_watch_collision));
+ phpdbg_store_watchpoint(&cur->watch TSRMLS_CC);
+ phpdbg_activate_watchpoint(&cur->watch TSRMLS_CC);
+ }
+
+ zend_hash_str_add_ptr(&cur->watches, watch->parent->str, watch->parent->str_len, watch->parent);
+}
+
+static void phpdbg_remove_watch_collision(zend_refcounted *ref TSRMLS_DC) {
+ phpdbg_watch_collision *cur;
+ if ((cur = zend_hash_index_find_ptr(&PHPDBG_G(watch_collisions), (zend_ulong) ref))) {
+ phpdbg_watchpoint_t *watch = cur->watch.parent;
+
+ if (watch->flags == PHPDBG_WATCH_RECURSIVE && !--cur->refs) {
+ phpdbg_delete_watchpoints_recursive(watch TSRMLS_CC);
+ }
+
+ zend_hash_str_del(&cur->watches, watch->str, watch->str_len);
+
+ if (!--cur->num) {
+ phpdbg_deactivate_watchpoint(&cur->watch TSRMLS_CC);
+ phpdbg_remove_watchpoint(&cur->watch TSRMLS_CC);
+
+ phpdbg_delete_watchpoint(watch TSRMLS_CC);
+
+ zend_hash_index_del(&PHPDBG_G(watch_collisions), (zend_ulong) ref);
+ }
+ }
+}
static int phpdbg_create_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) {
watch->flags |= PHPDBG_WATCH_SIMPLE;
phpdbg_store_watchpoint(watch TSRMLS_CC);
- zend_hash_add(&PHPDBG_G(watchpoints), watch->str, watch->str_len, &watch, sizeof(phpdbg_watchpoint_t *), NULL);
+ zend_hash_str_add_ptr(&PHPDBG_G(watchpoints), watch->str, watch->str_len, watch);
+
+ if (watch->parent && watch->parent->type == WATCH_ON_ZVAL && Z_REFCOUNTED_P(watch->parent->addr.zv)) {
+ phpdbg_add_watch_collision(phpdbg_create_refcounted_watchpoint(watch, Z_COUNTED_P(watch->parent->addr.zv)) TSRMLS_CC);
+ }
if (watch->type == WATCH_ON_ZVAL) {
- phpdbg_btree_insert(&PHPDBG_G(watch_HashTables), (zend_ulong)watch->parent_container, watch->parent_container->pDestructor);
- watch->parent_container->pDestructor = (dtor_func_t)phpdbg_watch_HashTable_dtor;
+ if (watch->parent_container) {
+ phpdbg_btree_insert(&PHPDBG_G(watch_HashTables), (zend_ulong) watch->parent_container, watch->parent_container->pDestructor);
+ watch->parent_container->pDestructor = (dtor_func_t) phpdbg_watch_HashTable_dtor;
+ }
+
+ if (Z_ISREF_P(watch->addr.zv)) {
+ phpdbg_watchpoint_t *ref = emalloc(sizeof(phpdbg_watchpoint_t));
+ ref->flags = watch->flags;
+ ref->str = watch->str;
+ ref->str_len = watch->str_len;
+ ref->parent = watch;
+ ref->parent_container = NULL;
+ phpdbg_create_zval_watchpoint(Z_REFVAL_P(watch->addr.zv), ref);
+
+ phpdbg_create_watchpoint(ref TSRMLS_CC);
+ }
}
phpdbg_activate_watchpoint(watch TSRMLS_CC);
@@ -116,29 +202,35 @@ static int phpdbg_create_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) {
return SUCCESS;
}
-static int phpdbg_create_array_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) {
- HashTable *ht;
+static int phpdbg_create_array_watchpoint(phpdbg_watchpoint_t *zv_watch TSRMLS_DC) {
+ zval *zv = zv_watch->addr.zv;
+ phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t));
+ HashTable *ht = HT_FROM_ZVP(zv);
- switch (Z_TYPE_P(watch->addr.zv)) {
- case IS_ARRAY:
- ht = Z_ARRVAL_P(watch->addr.zv);
- break;
- case IS_OBJECT:
- ht = Z_OBJPROP_P(watch->addr.zv);
- break;
- default:
- return FAILURE;
+ watch->parent = zv_watch;
+
+ if (!ht) {
+ return FAILURE;
}
phpdbg_create_ht_watchpoint(ht, watch);
phpdbg_create_watchpoint(watch TSRMLS_CC);
+ if (Z_TYPE_P(zv) == IS_ARRAY) {
+ watch->flags |= PHPDBG_WATCH_ARRAY;
+ } else {
+ watch->flags |= PHPDBG_WATCH_OBJECT;
+ }
+
+ phpdbg_add_watch_collision(phpdbg_create_refcounted_watchpoint(watch, Z_COUNTED_P(zv)) TSRMLS_CC);
+
return SUCCESS;
}
static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_DC) {
HashTable *ht;
+ zval *zvp = watch->addr.zv;
if (watch->type != WATCH_ON_ZVAL) {
return FAILURE;
@@ -147,25 +239,18 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_
watch->flags |= PHPDBG_WATCH_RECURSIVE;
phpdbg_create_watchpoint(watch TSRMLS_CC);
- switch (Z_TYPE_P(watch->addr.zv)) {
- case IS_ARRAY:
- ht = Z_ARRVAL_P(watch->addr.zv);
- break;
- case IS_OBJECT:
- ht = Z_OBJPROP_P(watch->addr.zv);
- break;
- default:
- return SUCCESS;
+ ZVAL_DEREF(zvp);
+
+ if (!(ht = HT_FROM_ZVP(zvp))) {
+ return SUCCESS;
}
{
HashPosition position;
- zval **zv;
+ zval *zv;
zval key;
- for (zend_hash_internal_pointer_reset_ex(ht, &position);
- zend_hash_get_current_data_ex(ht, (void **)&zv, &position) == SUCCESS;
- zend_hash_move_forward_ex(ht, &position)) {
+ ZEND_HASH_FOREACH_VAL(ht, zv) {
phpdbg_watchpoint_t *new_watch = emalloc(sizeof(phpdbg_watchpoint_t));
new_watch->flags = PHPDBG_WATCH_RECURSIVE;
@@ -174,19 +259,21 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_
zend_hash_get_current_key_zval_ex(ht, &key, &position);
if (Z_TYPE(key) == IS_STRING) {
- new_watch->name_in_parent = zend_strndup(Z_STRVAL(key), Z_STRLEN(key));
+ new_watch->name_in_parent = estrndup(Z_STRVAL(key), Z_STRLEN(key));
new_watch->name_in_parent_len = Z_STRLEN(key);
} else {
- new_watch->name_in_parent = NULL;
- new_watch->name_in_parent_len = asprintf(&new_watch->name_in_parent, "%ld", Z_LVAL(key));
+ new_watch->name_in_parent_len = spprintf(&new_watch->name_in_parent, 0, "%lld", Z_LVAL(key));
}
- new_watch->str = NULL;
- new_watch->str_len = asprintf(&new_watch->str, "%.*s%s%s%s", (int) watch->str_len, watch->str, Z_TYPE_P(watch->addr.zv) == IS_ARRAY ? "[" : "->", phpdbg_get_property_key(new_watch->name_in_parent), Z_TYPE_P(watch->addr.zv) == IS_ARRAY ? "]" : "");
+ new_watch->str_len = spprintf(&new_watch->str, 0, "%.*s%s%s%s", (int) watch->str_len, watch->str, Z_TYPE_P(zvp) == IS_ARRAY ? "[" : "->", phpdbg_get_property_key(new_watch->name_in_parent), Z_TYPE_P(zvp) == IS_ARRAY ? "]" : "");
+
+ while (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
- phpdbg_create_zval_watchpoint(*zv, new_watch);
+ phpdbg_create_zval_watchpoint(zv, new_watch);
phpdbg_create_recursive_watchpoint(new_watch TSRMLS_CC);
- }
+ } ZEND_HASH_FOREACH_END();
}
{
@@ -194,12 +281,18 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_
new_watch->parent = watch;
new_watch->parent_container = watch->parent_container;
- new_watch->name_in_parent = zend_strndup(watch->name_in_parent, watch->name_in_parent_len);
+ new_watch->name_in_parent = estrndup(watch->name_in_parent, watch->name_in_parent_len);
new_watch->name_in_parent_len = watch->name_in_parent_len;
new_watch->str = NULL;
- new_watch->str_len = asprintf(&new_watch->str, "%.*s[]", (int)watch->str_len, watch->str);
+ new_watch->str_len = spprintf(&new_watch->str, 0, "%.*s[]", (int) watch->str_len, watch->str);
new_watch->flags = PHPDBG_WATCH_RECURSIVE;
+ if (Z_TYPE_P(zvp) == IS_ARRAY) {
+ new_watch->flags |= PHPDBG_WATCH_ARRAY;
+ } else {
+ new_watch->flags |= PHPDBG_WATCH_OBJECT;
+ }
+
phpdbg_create_ht_watchpoint(ht, new_watch);
phpdbg_create_watchpoint(new_watch TSRMLS_CC);
}
@@ -208,52 +301,58 @@ static int phpdbg_create_recursive_watchpoint(phpdbg_watchpoint_t *watch TSRMLS_
}
static int phpdbg_delete_watchpoint_recursive(phpdbg_watchpoint_t *watch, zend_bool user_request TSRMLS_DC) {
- if (watch->type == WATCH_ON_HASHTABLE || (watch->type == WATCH_ON_ZVAL && (Z_TYPE_P(watch->addr.zv) == IS_ARRAY || Z_TYPE_P(watch->addr.zv) == IS_OBJECT))) {
+ if (watch->type == WATCH_ON_HASHTABLE) {
HashTable *ht;
phpdbg_btree_result *result;
if (watch->type == WATCH_ON_HASHTABLE && user_request) {
- HashPosition position;
- zval **zv;
- zval key;
- char *str;
- int str_len;
- phpdbg_watchpoint_t **watchpoint;
-
- ht = watch->addr.ht;
-
- for (zend_hash_internal_pointer_reset_ex(ht, &position);
- zend_hash_get_current_data_ex(ht, (void **)&zv, &position) == SUCCESS;
- zend_hash_move_forward_ex(ht, &position)) {
- zend_hash_get_current_key_zval_ex(ht, &key, &position);
- str = NULL;
- if (Z_TYPE(key) == IS_STRING) {
- str_len = asprintf(&str, "%.*s%s%s%s", (int) watch->parent->str_len, watch->parent->str, Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY ? "[" : "->", phpdbg_get_property_key(Z_STRVAL(key)), Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY ? "]" : "");
- } else {
- str_len = asprintf(&str, "%.*s%s%li%s", (int) watch->parent->str_len, watch->parent->str, Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY ? "[" : "->", Z_LVAL(key), Z_TYPE_P(watch->parent->addr.zv) == IS_ARRAY ? "]" : "");
- }
-
- if (zend_hash_find(&PHPDBG_G(watchpoints), str, str_len, (void **) &watchpoint) == SUCCESS) {
- phpdbg_delete_watchpoint_recursive(*watchpoint, 1 TSRMLS_CC);
- }
- }
+ phpdbg_delete_ht_watchpoints_recursive(watch TSRMLS_CC);
} else {
- switch (Z_TYPE_P(watch->addr.zv)) {
- case IS_ARRAY:
- ht = Z_ARRVAL_P(watch->addr.zv);
- break;
- case IS_OBJECT:
- ht = Z_OBJPROP_P(watch->addr.zv);
- break;
- }
+ ht = HT_FROM_ZVP(watch->addr.zv);
if ((result = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong) ht))) {
phpdbg_delete_watchpoint_recursive((phpdbg_watchpoint_t *) result->ptr, user_request TSRMLS_CC);
}
}
+ } else if (watch->type == WATCH_ON_ZVAL) {
+ phpdbg_delete_zval_watchpoints_recursive(watch TSRMLS_CC);
}
- return zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
+ return zend_hash_str_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
+}
+
+static void phpdbg_delete_ht_watchpoints_recursive(phpdbg_watchpoint_t *watch TSRMLS_DC) {
+ zend_string *strkey;
+ zend_long numkey;
+ char *str;
+ int str_len;
+ phpdbg_watchpoint_t *watchpoint;
+
+ ZEND_HASH_FOREACH_KEY(watch->addr.ht, numkey, strkey) {
+ if (strkey) {
+ str_len = asprintf(&str, "%.*s%s%s%s", (int) watch->str_len, watch->str, (watch->flags & PHPDBG_WATCH_ARRAY) ? "[" : "->", phpdbg_get_property_key(strkey->val), (watch->flags & PHPDBG_WATCH_ARRAY) ? "]" : "");
+ } else {
+ str_len = asprintf(&str, "%.*s%s%lli%s", (int) watch->str_len, watch->str, (watch->flags & PHPDBG_WATCH_ARRAY) ? "[" : "->", numkey, (watch->flags & PHPDBG_WATCH_ARRAY) ? "]" : "");
+ }
+
+ if ((watchpoint = zend_hash_str_find_ptr(&PHPDBG_G(watchpoints), str, str_len))) {
+ phpdbg_delete_watchpoint_recursive(watchpoint, 1 TSRMLS_CC);
+ }
+ } ZEND_HASH_FOREACH_END();
+}
+
+static void phpdbg_delete_zval_watchpoints_recursive(phpdbg_watchpoint_t *watch TSRMLS_DC) {
+ if (Z_REFCOUNTED_P(watch->addr.zv)) {
+ phpdbg_remove_watch_collision(Z_COUNTED_P(watch->addr.zv) TSRMLS_CC);
+ }
+}
+
+static void phpdbg_delete_watchpoints_recursive(phpdbg_watchpoint_t *watch TSRMLS_DC) {
+ if (watch->type == WATCH_ON_ZVAL) {
+ phpdbg_delete_zval_watchpoints_recursive(watch TSRMLS_CC);
+ } else if (watch->type == WATCH_ON_HASHTABLE) {
+ phpdbg_delete_ht_watchpoints_recursive(watch TSRMLS_CC);
+ }
}
static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *tmp_watch TSRMLS_DC) {
@@ -261,7 +360,7 @@ static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *tmp_watch TSRMLS_DC) {
phpdbg_watchpoint_t *watch;
phpdbg_btree_result *result;
- if ((result = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong)tmp_watch->addr.ptr)) == NULL) {
+ if ((result = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong) tmp_watch->addr.ptr)) == NULL) {
return FAILURE;
}
@@ -270,7 +369,7 @@ static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *tmp_watch TSRMLS_DC) {
if (watch->flags & PHPDBG_WATCH_RECURSIVE) {
ret = phpdbg_delete_watchpoint_recursive(watch, 1 TSRMLS_CC);
} else {
- ret = zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
+ ret = zend_hash_str_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
}
efree(tmp_watch->str);
@@ -280,7 +379,7 @@ static int phpdbg_delete_watchpoint(phpdbg_watchpoint_t *tmp_watch TSRMLS_DC) {
return ret;
}
-static int phpdbg_watchpoint_parse_wrapper(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval **zv, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC) TSRMLS_DC) {
+static int phpdbg_watchpoint_parse_wrapper(char *name, size_t len, char *keyname, size_t keylen, HashTable *parent, zval *zv, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC) TSRMLS_DC) {
int ret;
phpdbg_watchpoint_t *watch = emalloc(sizeof(phpdbg_watchpoint_t));
watch->flags = 0;
@@ -289,7 +388,7 @@ static int phpdbg_watchpoint_parse_wrapper(char *name, size_t len, char *keyname
watch->name_in_parent = keyname;
watch->name_in_parent_len = keylen;
watch->parent_container = parent;
- phpdbg_create_zval_watchpoint(*zv, watch);
+ phpdbg_create_zval_watchpoint(zv, watch);
ret = callback(watch TSRMLS_CC);
@@ -307,15 +406,15 @@ PHPDBG_API int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable
}
static int phpdbg_watchpoint_parse_symtables(char *input, size_t len, int (*callback)(phpdbg_watchpoint_t * TSRMLS_DC) TSRMLS_DC) {
- if (EG(This) && len >= 5 && !memcmp("$this", input, 5)) {
- zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL);
+ if (EG(scope) && len >= 5 && !memcmp("$this", input, 5)) {
+ zend_hash_str_add(&EG(current_execute_data)->symbol_table->ht, ZEND_STRL("this"), &EG(current_execute_data)->This);
}
- if (zend_is_auto_global(input, len TSRMLS_CC) && phpdbg_watchpoint_parse_input(input, len, &EG(symbol_table), 0, callback, 1 TSRMLS_CC) != FAILURE) {
+ if (phpdbg_is_auto_global(input, len TSRMLS_CC) && phpdbg_watchpoint_parse_input(input, len, &EG(symbol_table).ht, 0, callback, 1 TSRMLS_CC) != FAILURE) {
return SUCCESS;
}
- return phpdbg_watchpoint_parse_input(input, len, EG(active_symbol_table), 0, callback, 0 TSRMLS_CC);
+ return phpdbg_watchpoint_parse_input(input, len, &EG(current_execute_data)->symbol_table->ht, 0, callback, 0 TSRMLS_CC);
}
PHPDBG_WATCH(delete) /* {{{ */
@@ -373,23 +472,23 @@ PHPDBG_WATCH(array) /* {{{ */
return SUCCESS;
} /* }}} */
-void phpdbg_watch_HashTable_dtor(zval **zv) {
+void phpdbg_watch_HashTable_dtor(zval *zv) {
phpdbg_btree_result *result;
TSRMLS_FETCH();
zval_ptr_dtor_wrapper(zv);
- if ((result = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong)*zv))) {
+ if ((result = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong) zv))) {
phpdbg_watchpoint_t *watch = result->ptr;
PHPDBG_G(watchpoint_hit) = 1;
- phpdbg_notice("watchdelete", "variable=\"%.*s\" recursive=\"%s\"", "%.*s was removed, removing watchpoint%s", (int)watch->str_len, watch->str, watch->flags & PHPDBG_WATCH_RECURSIVE ? " recursively" : "");
+ phpdbg_notice("watchdelete", "variable=\"%.*s\" recursive=\"%s\"", "%.*s was removed, removing watchpoint%s", (int) watch->str_len, watch->str, (watch->flags & PHPDBG_WATCH_RECURSIVE) ? " recursively" : "");
if (watch->flags & PHPDBG_WATCH_RECURSIVE) {
phpdbg_delete_watchpoint_recursive(watch, 0 TSRMLS_CC);
} else {
- zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
+ zend_hash_str_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
}
}
}
@@ -454,8 +553,8 @@ void phpdbg_watchpoints_clean(TSRMLS_D) {
zend_hash_clean(&PHPDBG_G(watchpoints));
}
-static void phpdbg_watch_dtor(void *pDest) {
- phpdbg_watchpoint_t *watch = *(phpdbg_watchpoint_t **)pDest;
+static void phpdbg_watch_dtor(zval *pDest) {
+ phpdbg_watchpoint_t *watch = (phpdbg_watchpoint_t *) Z_PTR_P(pDest);
TSRMLS_FETCH();
phpdbg_deactivate_watchpoint(watch TSRMLS_CC);
@@ -463,18 +562,17 @@ static void phpdbg_watch_dtor(void *pDest) {
efree(watch->str);
efree(watch->name_in_parent);
- efree(watch);
}
static void phpdbg_watch_mem_dtor(void *llist_data) {
- phpdbg_watch_memdump *dump = *(phpdbg_watch_memdump **)llist_data;
+ phpdbg_watch_memdump *dump = *(phpdbg_watch_memdump **) llist_data;
/* Disble writing again */
if (dump->reenable_writing) {
mprotect(dump->page, dump->size, PROT_READ);
}
- free(*(void **)llist_data);
+ free(*(void **) llist_data);
}
void phpdbg_setup_watchpoints(TSRMLS_D) {
@@ -491,60 +589,79 @@ void phpdbg_setup_watchpoints(TSRMLS_D) {
zend_llist_init(&PHPDBG_G(watchlist_mem), sizeof(void *), phpdbg_watch_mem_dtor, 1);
phpdbg_btree_init(&PHPDBG_G(watchpoint_tree), sizeof(void *) * 8);
phpdbg_btree_init(&PHPDBG_G(watch_HashTables), sizeof(void *) * 8);
- zend_hash_init(&PHPDBG_G(watchpoints), 8, NULL, phpdbg_watch_dtor, 0 ZEND_FILE_LINE_CC);
+ zend_hash_init(&PHPDBG_G(watchpoints), 8, NULL, phpdbg_watch_dtor, 0);
+ zend_hash_init(&PHPDBG_G(watch_collisions), 8, NULL, NULL, 0);
}
static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) {
/* fetch all changes between dump->page and dump->page + dump->size */
phpdbg_btree_position pos = phpdbg_btree_find_between(&PHPDBG_G(watchpoint_tree), (zend_ulong) dump->page, (zend_ulong) dump->page + dump->size);
- phpdbg_btree_result *result, *htresult;
+ phpdbg_btree_result *result;
int elementDiff;
void *curTest;
dump->reenable_writing = 0;
while ((result = phpdbg_btree_next(&pos))) {
- phpdbg_watchpoint_t *watch = result->ptr, *htwatch;
- void *oldPtr = (char *)&dump->data + ((size_t)watch->addr.ptr - (size_t)dump->page);
+ phpdbg_watchpoint_t *watch = result->ptr;
+ void *oldPtr = (char *) &dump->data + ((size_t) watch->addr.ptr - (size_t) dump->page);
char reenable = 1;
+ int removed = 0;
- if ((size_t)watch->addr.ptr < (size_t)dump->page || (size_t)watch->addr.ptr + watch->size > (size_t) dump->page + dump->size) {
+ if ((size_t) watch->addr.ptr < (size_t) dump->page || (size_t) watch->addr.ptr + watch->size > (size_t) dump->page + dump->size) {
continue;
}
/* Test if the zval was separated and if necessary move the watchpoint */
- if (zend_hash_find(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len + 1, &curTest) == SUCCESS) {
- if (watch->type == WATCH_ON_HASHTABLE) {
- switch (Z_TYPE_PP((zval **)curTest)) {
- case IS_ARRAY:
- curTest = (void *)Z_ARRVAL_PP((zval **)curTest);
- break;
- case IS_OBJECT:
- curTest = (void *)Z_OBJPROP_PP((zval **)curTest);
- break;
+ if ((watch->type == WATCH_ON_HASHTABLE || watch->type == WATCH_ON_ZVAL) && watch->parent_container) {
+ if ((curTest = zend_hash_str_find(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len))) {
+ while (Z_TYPE_P((zval *) curTest) == IS_INDIRECT) {
+ curTest = Z_INDIRECT_P((zval *) curTest);
}
- } else {
- curTest = *(void **)curTest;
- }
- if (curTest != watch->addr.ptr) {
- phpdbg_deactivate_watchpoint(watch TSRMLS_CC);
- phpdbg_remove_watchpoint(watch TSRMLS_CC);
- watch->addr.ptr = curTest;
- phpdbg_store_watchpoint(watch TSRMLS_CC);
- phpdbg_activate_watchpoint(watch TSRMLS_CC);
+ if (watch->type == WATCH_ON_HASHTABLE) {
+ switch (Z_TYPE_P((zval *) curTest)) {
+ case IS_ARRAY:
+ curTest = (void *) Z_ARRVAL_P((zval *) curTest);
+ break;
+ case IS_OBJECT:
+ curTest = (void *) Z_OBJPROP_P((zval *) curTest);
+ break;
+ }
+ }
- reenable = 0;
+ if (curTest != watch->addr.ptr) {
+ phpdbg_deactivate_watchpoint(watch TSRMLS_CC);
+ phpdbg_remove_watchpoint(watch TSRMLS_CC);
+ watch->addr.ptr = curTest;
+ phpdbg_store_watchpoint(watch TSRMLS_CC);
+ phpdbg_activate_watchpoint(watch TSRMLS_CC);
+
+ reenable = 0;
+ }
+ } else {
+ removed = 1;
}
}
/* Show to the user what changed and delete watchpoint upon removal */
if (memcmp(oldPtr, watch->addr.ptr, watch->size) != SUCCESS) {
- zend_bool do_break = PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS || (watch->type == WATCH_ON_ZVAL && memcmp(oldPtr, watch->addr.zv, sizeof(zvalue_value))) || (watch->type == WATCH_ON_HASHTABLE
-#if ZEND_DEBUG
- && !watch->addr.ht->inconsistent
-#endif
- && zend_hash_num_elements((HashTable *)oldPtr) != zend_hash_num_elements(watch->addr.ht));
+ zend_bool do_break = 0;
+
+ switch (watch->type) {
+ case WATCH_ON_ZVAL:
+ do_break = memcmp(oldPtr, watch->addr.zv, sizeof(zend_value) + sizeof(uint32_t) /* value + typeinfo */);
+ break;
+ case WATCH_ON_HASHTABLE:
+ do_break = zend_hash_num_elements((HashTable *) oldPtr) != zend_hash_num_elements(watch->addr.ht);
+ break;
+ case WATCH_ON_REFCOUNTED:
+ if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS) {
+ do_break = memcmp(oldPtr, watch->addr.ref, sizeof(uint32_t) /* no zend_refcounted metadata info */);
+ }
+ break;
+ }
+
if (do_break) {
PHPDBG_G(watchpoint_hit) = 1;
@@ -555,12 +672,10 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) {
switch (watch->type) {
case WATCH_ON_ZVAL: {
- int removed = ((zval *)oldPtr)->refcount__gc != watch->addr.zv->refcount__gc && !zend_symtable_exists(watch->parent_container, watch->name_in_parent, watch->name_in_parent_len + 1);
- int show_value = memcmp(oldPtr, watch->addr.zv, sizeof(zvalue_value));
- int show_ref = ((zval *)oldPtr)->refcount__gc != watch->addr.zv->refcount__gc || ((zval *)oldPtr)->is_ref__gc != watch->addr.zv->is_ref__gc;
+ int show_value = memcmp(oldPtr, watch->addr.zv, sizeof(zval) - sizeof(uint32_t) /* no metadata info */);
if (removed || show_value) {
- if ((Z_TYPE_P((zval *)oldPtr) == IS_ARRAY || Z_TYPE_P((zval *)oldPtr) == IS_OBJECT) && removed) {
+ if (removed && (Z_TYPE_P((zval *) oldPtr) == IS_ARRAY || Z_TYPE_P((zval *) oldPtr) == IS_OBJECT)) {
phpdbg_writeln("watchvalue", "type=\"old\" inaccessible=\"inaccessible\"", "Old value inaccessible, array or object (HashTable) already destroyed");
} else {
phpdbg_out("Old value: ");
@@ -570,21 +685,17 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) {
phpdbg_out("\n");
}
}
- if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS && (removed || show_ref)) {
- phpdbg_write("watchrefcount", "type=\"old\" refcount=\"%d\" isref=\"%d\"", "Old refcount: %d; Old is_ref: %d", ((zval *) oldPtr)->refcount__gc, ((zval *) oldPtr)->is_ref__gc);
- }
/* check if zval was removed */
if (removed) {
phpdbg_notice("watchdelete", "variable=\"%.*s\"", "Watchpoint %.*s was unset, removing watchpoint", (int) watch->str_len, watch->str);
- zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
+ zend_hash_str_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
reenable = 0;
- if (Z_TYPE_P((zval *) oldPtr) == IS_ARRAY || Z_TYPE_P((zval *) oldPtr) == IS_OBJECT) {
- goto remove_ht_watch;
+ if (Z_REFCOUNTED_P((zval *) oldPtr)) {
+ phpdbg_remove_watch_collision(Z_COUNTED_P((zval *) oldPtr) TSRMLS_CC);
}
-
break;
}
@@ -595,33 +706,27 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) {
phpdbg_xml("</watchvalue>");
phpdbg_out("\n");
}
- if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS && show_ref) {
- phpdbg_writeln("watchrefcount", "type=\"new\" refcount=\"%d\" isref=\"%d\"", "New refcount: %d; New is_ref: %d", watch->addr.zv->refcount__gc, watch->addr.zv->is_ref__gc);
- }
- if ((Z_TYPE_P(watch->addr.zv) == IS_ARRAY && Z_ARRVAL_P(watch->addr.zv) != Z_ARRVAL_P((zval *) oldPtr)) || (Z_TYPE_P(watch->addr.zv) != IS_OBJECT && Z_OBJ_HANDLE_P(watch->addr.zv) == Z_OBJ_HANDLE_P((zval *) oldPtr))) {
- /* add new watchpoints if necessary */
- if (watch->flags & PHPDBG_WATCH_RECURSIVE) {
- phpdbg_create_recursive_watchpoint(watch TSRMLS_CC);
+ /* add new watchpoints if necessary */
+ if (Z_PTR_P(watch->addr.zv) != Z_PTR_P((zval *) oldPtr)) {
+ if (Z_REFCOUNTED_P((zval *) oldPtr)) {
+ phpdbg_remove_watch_collision(Z_COUNTED_P((zval *) oldPtr) TSRMLS_CC);
+ }
+ if (Z_REFCOUNTED_P(watch->addr.zv)) {
+ if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS) {
+ phpdbg_writeln("watchrefcount", "type=\"new\" refcount=\"%d\"", "New refcount: %d", Z_COUNTED_P(watch->addr.zv)->refcount);
+ }
+ if (watch->flags & PHPDBG_WATCH_RECURSIVE) {
+ phpdbg_create_recursive_watchpoint(watch TSRMLS_CC);
+ }
}
- }
-
- if ((Z_TYPE_P((zval *) oldPtr) != IS_ARRAY || Z_ARRVAL_P(watch->addr.zv) == Z_ARRVAL_P((zval *) oldPtr)) && (Z_TYPE_P((zval *)oldPtr) != IS_OBJECT || Z_OBJ_HANDLE_P(watch->addr.zv) == Z_OBJ_HANDLE_P((zval *) oldPtr))) {
- break;
- }
-
-remove_ht_watch:
- if ((htresult = phpdbg_btree_find(&PHPDBG_G(watchpoint_tree), (zend_ulong)Z_ARRVAL_P((zval *)oldPtr)))) {
- htwatch = htresult->ptr;
- zend_hash_del(&PHPDBG_G(watchpoints), htwatch->str, htwatch->str_len);
}
break;
}
case WATCH_ON_HASHTABLE:
-
-#if ZEND_DEBUG
- if (watch->addr.ht->inconsistent) {
+#if 0 && ZEND_DEBUG
+ if (watch->addr.arr->ht->inconsistent) {
phpdbg_notice("watchdelete", "variable=\"%.*s\"", "Watchpoint %.*s was unset, removing watchpoint", (int) watch->str_len, watch->str);
zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
@@ -630,7 +735,6 @@ remove_ht_watch:
break;
}
#endif
-
elementDiff = zend_hash_num_elements((HashTable *) oldPtr) - zend_hash_num_elements(watch->addr.ht);
if (elementDiff) {
if (elementDiff > 0) {
@@ -644,10 +748,21 @@ remove_ht_watch:
}
}
}
- if (((HashTable *) oldPtr)->pInternalPointer != watch->addr.ht->pInternalPointer) {
+ if (watch->addr.ht->nInternalPointer != ((HashTable *) oldPtr)->nInternalPointer) {
phpdbg_writeln("watcharrayptr", "", "Internal pointer of array was changed");
}
break;
+ case WATCH_ON_REFCOUNTED: {
+ if (PHPDBG_G(flags) & PHPDBG_SHOW_REFCOUNTS) {
+ phpdbg_writeln("watchrefcount", "type=\"old\" refcount=\"%d\"", "Old refcount: %d", ((zend_refcounted *) oldPtr)->refcount);
+
+ if (!removed) {
+ phpdbg_writeln("watchrefcount", "type=\"old\" refcount=\"%d\"", "Old refcount: %d", ((zend_refcounted *) oldPtr)->refcount);
+ }
+ }
+
+ break;
+ }
}
if (do_break) {
@@ -683,16 +798,13 @@ int phpdbg_print_changed_zvals(TSRMLS_D) {
}
void phpdbg_list_watchpoints(TSRMLS_D) {
- HashPosition position;
- phpdbg_watchpoint_t **watch;
+ phpdbg_watchpoint_t *watch;
phpdbg_xml("<watchlist %r>");
- for (zend_hash_internal_pointer_reset_ex(&PHPDBG_G(watchpoints), &position);
- zend_hash_get_current_data_ex(&PHPDBG_G(watchpoints), (void**) &watch, &position) == SUCCESS;
- zend_hash_move_forward_ex(&PHPDBG_G(watchpoints), &position)) {
- phpdbg_writeln("watchvariable", "variable=\"%.*s\" on=\"%s\" type=\"%s\"", "%.*s (%s, %s)", (int) (*watch)->str_len, (*watch)->str, (*watch)->type == WATCH_ON_HASHTABLE ? "array" : "variable", (*watch)->flags == PHPDBG_WATCH_RECURSIVE ? "recursive" : "simple");
- }
+ ZEND_HASH_FOREACH_PTR(&PHPDBG_G(watchpoints), watch) {
+ phpdbg_writeln("watchvariable", "variable=\"%.*s\" on=\"%s\" type=\"%s\"", "%.*s (%s, %s)", (int) watch->str_len, watch->str, watch->type == WATCH_ON_HASHTABLE ? "array" : watch->type == WATCH_ON_REFCOUNTED ? "refcount" : "variable", watch->flags == PHPDBG_WATCH_RECURSIVE ? "recursive" : "simple");
+ } ZEND_HASH_FOREACH_END();
phpdbg_xml("</watchlist>");
}
@@ -706,8 +818,11 @@ void phpdbg_watch_efree(void *ptr) {
if (result) {
phpdbg_watchpoint_t *watch = result->ptr;
- if ((size_t)watch->addr.ptr + watch->size > (size_t) ptr) {
- zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
+ if ((size_t) watch->addr.ptr + watch->size > (size_t) ptr) {
+ if (watch->type == WATCH_ON_ZVAL) {
+ phpdbg_remove_watch_collision(Z_COUNTED_P(watch->addr.zv) TSRMLS_CC);
+ }
+ zend_hash_str_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
}
}
diff --git a/sapi/phpdbg/phpdbg_watch.h b/sapi/phpdbg/phpdbg_watch.h
index 5c0079057c..35cab10dc1 100644
--- a/sapi/phpdbg/phpdbg_watch.h
+++ b/sapi/phpdbg/phpdbg_watch.h
@@ -25,7 +25,7 @@
#include "phpdbg_cmd.h"
#ifdef _WIN32
-# include "phpdbg_win.h"
+# include "phpdbg_win.h"
#endif
#define PHPDBG_WATCH(name) PHPDBG_COMMAND(watch_##name)
@@ -37,47 +37,49 @@ PHPDBG_WATCH(array);
PHPDBG_WATCH(delete);
PHPDBG_WATCH(recursive);
-/**
- * Commands
- */
-
-static const phpdbg_command_t phpdbg_watch_commands[] = {
- PHPDBG_COMMAND_D_EX(array, "create watchpoint on an array", 'a', watch_array, NULL, "s", 0),
- PHPDBG_COMMAND_D_EX(delete, "delete watchpoint", 'd', watch_delete, NULL, "s", 0),
- PHPDBG_COMMAND_D_EX(recursive, "create recursive watchpoints", 'r', watch_recursive, NULL, "s", 0),
- PHPDBG_END_COMMAND
-};
+extern const phpdbg_command_t phpdbg_watch_commands[];
/* Watchpoint functions/typedefs */
typedef enum {
WATCH_ON_ZVAL,
WATCH_ON_HASHTABLE,
+ WATCH_ON_REFCOUNTED,
} phpdbg_watchtype;
-#define PHPDBG_WATCH_SIMPLE 0x0
-#define PHPDBG_WATCH_RECURSIVE 0x1
+#define PHPDBG_WATCH_SIMPLE 0x0
+#define PHPDBG_WATCH_RECURSIVE 0x1
+#define PHPDBG_WATCH_ARRAY 0x2
+#define PHPDBG_WATCH_OBJECT 0x4
typedef struct _phpdbg_watchpoint_t phpdbg_watchpoint_t;
struct _phpdbg_watchpoint_t {
- phpdbg_watchpoint_t *parent;
- HashTable *parent_container;
- char *name_in_parent;
- size_t name_in_parent_len;
- char *str;
- size_t str_len;
union {
zval *zv;
HashTable *ht;
+ zend_refcounted *ref;
void *ptr;
} addr;
size_t size;
phpdbg_watchtype type;
char flags;
+ phpdbg_watchpoint_t *parent;
+ HashTable *parent_container;
+ char *name_in_parent;
+ size_t name_in_parent_len;
+ char *str;
+ size_t str_len;
};
+typedef struct {
+ phpdbg_watchpoint_t watch;
+ unsigned int num;
+ unsigned int refs;
+ HashTable watches;
+} phpdbg_watch_collision;
+
void phpdbg_setup_watchpoints(TSRMLS_D);
#ifndef _WIN32
@@ -102,11 +104,11 @@ void phpdbg_watch_efree(void *ptr);
static long phpdbg_pagesize;
static zend_always_inline void *phpdbg_get_page_boundary(void *addr) {
- return (void *)((size_t)addr & ~(phpdbg_pagesize - 1));
+ return (void *) ((size_t) addr & ~(phpdbg_pagesize - 1));
}
static zend_always_inline size_t phpdbg_get_total_page_size(void *addr, size_t size) {
- return (size_t)phpdbg_get_page_boundary((void *)((size_t)addr + size - 1)) - (size_t)phpdbg_get_page_boundary(addr) + phpdbg_pagesize;
+ return (size_t) phpdbg_get_page_boundary((void *) ((size_t) addr + size - 1)) - (size_t) phpdbg_get_page_boundary(addr) + phpdbg_pagesize;
}
#endif
diff --git a/sapi/phpdbg/phpdbg_webdata_transfer.c b/sapi/phpdbg/phpdbg_webdata_transfer.c
index e7438ea01a..2f18b9d082 100644
--- a/sapi/phpdbg/phpdbg_webdata_transfer.c
+++ b/sapi/phpdbg/phpdbg_webdata_transfer.c
@@ -1,6 +1,6 @@
/*
+----------------------------------------------------------------------+
- | PHP Version 5 |
+ | PHP Version 7 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2014 The PHP Group |
+----------------------------------------------------------------------+
@@ -19,93 +19,87 @@
#include "phpdbg_webdata_transfer.h"
#include "ext/json/php_json.h"
+static int phpdbg_is_auto_global(char *name, int len TSRMLS_DC) {
+ int ret;
+ zend_string *str = zend_string_init(name, len, 0);
+ ret = zend_is_auto_global(str TSRMLS_CC);
+ efree(str);
+ return ret;
+}
+
PHPDBG_API void phpdbg_webdata_compress(char **msg, int *len TSRMLS_DC) {
#ifdef HAVE_JSON
smart_str buf = {0};
zval array;
HashTable *ht;
- /* I really need to change that to an array of zvals... */
- zval zv1 = {{0}}, *zvp1 = &zv1;
- zval zv2 = {{0}}, *zvp2 = &zv2;
- zval zv3 = {{0}}, *zvp3 = &zv3;
- zval zv4 = {{0}}, *zvp4 = &zv4;
- zval zv5 = {{0}}, *zvp5 = &zv5;
- zval zv6 = {{0}}, *zvp6 = &zv6;
- zval zv7 = {{0}}, *zvp7 = &zv7;
- zval zv8 = {{0}}, *zvp8 = &zv8;
+ zval zv[9] = {{{0}}};
array_init(&array);
ht = Z_ARRVAL(array);
/* fetch superglobals */
{
- zend_is_auto_global(ZEND_STRL("GLOBALS") TSRMLS_CC);
+ phpdbg_is_auto_global(ZEND_STRL("GLOBALS") TSRMLS_CC);
/* might be JIT */
- zend_is_auto_global(ZEND_STRL("_ENV") TSRMLS_CC);
- zend_is_auto_global(ZEND_STRL("_SERVER") TSRMLS_CC);
- zend_is_auto_global(ZEND_STRL("_REQUEST") TSRMLS_CC);
- array_init(&zv1);
- zend_hash_copy(Z_ARRVAL(zv1), &EG(symbol_table), NULL, (void *) NULL, sizeof(zval *));
- Z_ARRVAL(zv1)->pDestructor = NULL; /* we're operating on a copy! Don't double free zvals */
- zend_hash_del(Z_ARRVAL(zv1), "GLOBALS", sizeof("GLOBALS")); /* do not use the reference to itself in json */
- zend_hash_add(ht, "GLOBALS", sizeof("GLOBALS"), &zvp1, sizeof(zval *), NULL);
+ phpdbg_is_auto_global(ZEND_STRL("_ENV") TSRMLS_CC);
+ phpdbg_is_auto_global(ZEND_STRL("_SERVER") TSRMLS_CC);
+ phpdbg_is_auto_global(ZEND_STRL("_REQUEST") TSRMLS_CC);
+ array_init(&zv[1]);
+ zend_hash_copy(Z_ARRVAL(zv[1]), &EG(symbol_table).ht, NULL);
+ Z_ARRVAL(zv[1])->pDestructor = NULL; /* we're operating on a copy! Don't double free zvals */
+ zend_hash_str_del(Z_ARRVAL(zv[1]), ZEND_STRL("GLOBALS")); /* do not use the reference to itself in json */
+ zend_hash_str_add(ht, ZEND_STRL("GLOBALS"), &zv[1]);
}
/* save php://input */
{
php_stream *stream;
- int len;
- char *contents;
+ zend_string *str;
stream = php_stream_temp_create_ex(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE, PG(upload_tmp_dir));
- if ((len = php_stream_copy_to_mem(stream, &contents, PHP_STREAM_COPY_ALL, 0)) > 0) {
- ZVAL_STRINGL(&zv2, contents, len, 0);
+ if ((str = php_stream_copy_to_mem(stream, PHP_STREAM_COPY_ALL, 0))) {
+ ZVAL_STR(&zv[2], str);
} else {
- ZVAL_EMPTY_STRING(&zv2);
+ ZVAL_EMPTY_STRING(&zv[2]);
}
- Z_SET_REFCOUNT(zv2, 2);
- zend_hash_add(ht, "input", sizeof("input"), &zvp2, sizeof(zval *), NULL);
+ Z_SET_REFCOUNT(zv[2], 1);
+ zend_hash_str_add(ht, ZEND_STRL("input"), &zv[2]);
}
/* change sapi name */
{
if (sapi_module.name) {
- ZVAL_STRING(&zv6, sapi_module.name, 0);
+ ZVAL_STRING(&zv[6], sapi_module.name);
} else {
- Z_TYPE(zv6) = IS_NULL;
+ Z_TYPE_INFO(zv[6]) = IS_NULL;
}
- Z_SET_REFCOUNT(zv6, 2);
- zend_hash_add(ht, "sapi_name", sizeof("sapi_name"), &zvp6, sizeof(zval *), NULL);
+ zend_hash_str_add(ht, ZEND_STRL("sapi_name"), &zv[6]);
+ Z_SET_REFCOUNT(zv[6], 1);
}
/* handle modules / extensions */
{
- HashPosition position;
zend_module_entry *module;
zend_extension *extension;
zend_llist_position pos;
- array_init(&zv7);
- for (zend_hash_internal_pointer_reset_ex(&module_registry, &position);
- zend_hash_get_current_data_ex(&module_registry, (void**) &module, &position) == SUCCESS;
- zend_hash_move_forward_ex(&module_registry, &position)) {
- zval **value = emalloc(sizeof(zval *));
- ALLOC_ZVAL(*value);
- ZVAL_STRING(*value, module->name, 1);
- zend_hash_next_index_insert(Z_ARRVAL(zv7), value, sizeof(zval *), NULL);
- }
- zend_hash_add(ht, "modules", sizeof("modules"), &zvp7, sizeof(zval *), NULL);
+ array_init(&zv[7]);
+ ZEND_HASH_FOREACH_PTR(&module_registry, module) {
+ zval *value = ecalloc(sizeof(zval), 1);
+ ZVAL_STRING(value, module->name);
+ zend_hash_next_index_insert(Z_ARRVAL(zv[7]), value);
+ } ZEND_HASH_FOREACH_END();
+ zend_hash_str_add(ht, ZEND_STRL("modules"), &zv[7]);
- array_init(&zv8);
+ array_init(&zv[8]);
extension = (zend_extension *) zend_llist_get_first_ex(&zend_extensions, &pos);
while (extension) {
- zval **value = emalloc(sizeof(zval *));
- ALLOC_ZVAL(*value);
- ZVAL_STRING(*value, extension->name, 1);
- zend_hash_next_index_insert(Z_ARRVAL(zv8), value, sizeof(zval *), NULL);
+ zval *value = ecalloc(sizeof(zval), 1);
+ ZVAL_STRING(value, extension->name);
+ zend_hash_next_index_insert(Z_ARRVAL(zv[8]), value);
extension = (zend_extension *) zend_llist_get_next_ex(&zend_extensions, &pos);
}
- zend_hash_add(ht, "extensions", sizeof("extensions"), &zvp8, sizeof(zval *), NULL);
+ zend_hash_str_add(ht, ZEND_STRL("extensions"), &zv[8]);
}
/* switch cwd */
@@ -119,67 +113,58 @@ PHPDBG_API void phpdbg_webdata_compress(char **msg, int *len TSRMLS_DC) {
ret = VCWD_GETWD(path);
#endif
if (ret) {
- ZVAL_STRING(&zv5, path, 1);
- Z_SET_REFCOUNT(zv5, 1);
- zend_hash_add(ht, "cwd", sizeof("cwd"), &zvp5, sizeof(zval *), NULL);
+ ZVAL_STRING(&zv[5], path);
+ Z_SET_REFCOUNT(zv[5], 1);
+ zend_hash_str_add(ht, ZEND_STRL("cwd"), &zv[5]);
}
}
/* get system ini entries */
{
- HashPosition position;
zend_ini_entry *ini_entry;
- array_init(&zv3);
- for (zend_hash_internal_pointer_reset_ex(EG(ini_directives), &position);
- zend_hash_get_current_data_ex(EG(ini_directives), (void**) &ini_entry, &position) == SUCCESS;
- zend_hash_move_forward_ex(EG(ini_directives), &position)) {
- zval **value = emalloc(sizeof(zval *));
+ array_init(&zv[3]);
+ ZEND_HASH_FOREACH_PTR(EG(ini_directives), ini_entry) {
+ zval *value = ecalloc(sizeof(zval), 1);
if (ini_entry->modified) {
if (!ini_entry->orig_value) {
efree(value);
continue;
}
- ALLOC_ZVAL(*value);
- ZVAL_STRINGL(*value, ini_entry->orig_value, ini_entry->orig_value_length, 1);
+ ZVAL_STR(value, ini_entry->orig_value);
} else {
if (!ini_entry->value) {
efree(value);
continue;
}
- ALLOC_ZVAL(*value);
- ZVAL_STRINGL(*value, ini_entry->value, ini_entry->value_length, 1);
+ ZVAL_STR(value, ini_entry->value);
}
- zend_hash_add(Z_ARRVAL(zv3), ini_entry->name, ini_entry->name_length, value, sizeof(zval *), NULL);
- }
- zend_hash_add(ht, "systemini", sizeof("systemini"), &zvp3, sizeof(zval *), NULL);
+ zend_hash_add(Z_ARRVAL(zv[3]), ini_entry->name, value);
+ } ZEND_HASH_FOREACH_END();
+ zend_hash_str_add(ht, ZEND_STRL("systemini"), &zv[3]);
}
/* get perdir ini entries */
if (EG(modified_ini_directives)) {
- HashPosition position;
zend_ini_entry *ini_entry;
- array_init(&zv4);
- for (zend_hash_internal_pointer_reset_ex(EG(modified_ini_directives), &position);
- zend_hash_get_current_data_ex(EG(modified_ini_directives), (void**) &ini_entry, &position) == SUCCESS;
- zend_hash_move_forward_ex(EG(modified_ini_directives), &position)) {
- zval **value = emalloc(sizeof(zval *));
+ array_init(&zv[4]);
+ ZEND_HASH_FOREACH_PTR(EG(ini_directives), ini_entry) {
+ zval *value = ecalloc(sizeof(zval), 1);
if (!ini_entry->value) {
efree(value);
continue;
}
- ALLOC_ZVAL(*value);
- ZVAL_STRINGL(*value, ini_entry->value, ini_entry->value_length, 1);
- zend_hash_add(Z_ARRVAL(zv4), ini_entry->name, ini_entry->name_length, value, sizeof(zval *), NULL);
- }
- zend_hash_add(ht, "userini", sizeof("userini"), &zvp4, sizeof(zval *), NULL);
+ ZVAL_STR(value, ini_entry->value);
+ zend_hash_add(Z_ARRVAL(zv[4]), ini_entry->name, value);
+ } ZEND_HASH_FOREACH_END();
+ zend_hash_str_add(ht, ZEND_STRL("userini"), &zv[4]);
}
/* encode data */
php_json_encode(&buf, &array, 0 TSRMLS_CC);
- *msg = buf.c;
- *len = buf.len;
+ *msg = buf.s->val;
+ *len = buf.s->len;
zval_dtor(&array);
#endif
}
diff --git a/sapi/phpdbg/tests/run-tests.php b/sapi/phpdbg/tests/run-tests.php
index 1cc31d815e..4afb64561c 100644
--- a/sapi/phpdbg/tests/run-tests.php
+++ b/sapi/phpdbg/tests/run-tests.php
@@ -389,7 +389,7 @@ namespace phpdbg\testing {
} break;
default: {
- $this->$chunks[0] = $chunks[1];
+ $this->{$chunks[0]} = $chunks[1];
}
}
} else switch(substr($trim, 1, 1)) {
diff --git a/sapi/phpdbg/xml.md b/sapi/phpdbg/xml.md
index 0556fb2415..7871b31376 100644
--- a/sapi/phpdbg/xml.md
+++ b/sapi/phpdbg/xml.md
@@ -60,7 +60,6 @@ type
- general attribute for most errors, describes the genre of the error
-
General tags
============
@@ -78,11 +77,6 @@ intro
- help: command name for help
- report: URL for bug reporting
-prompt
-------
-
-- msg tag contains the text prompt
-- indicates that a new command may be accepted
phpdbg
------
@@ -257,23 +251,6 @@ info (subcommands)
- &lt;lasterror error="" (file="" line="") />
- error attribute contains the last error as a string, is empty if there's no last error
-### constants ###
-
-- &lt;constantinfo num="" /> with num having an integer value, indicating the number of (local or superglobal) variables
-- if info vars was used it'll have also one of these attributes:
- - method
- - function
- - file
- - opline
-- for each variable there is a &lt;constant> element
-- &lt;constant address="" refcount="" type="" name="" />
- - address: pointer to zval (hexadecimal)
- - refcount: refcount of zval
- - type: the variable type (long, string, ...). If the value is "unknown", the other attributes are meaningless
- - name: the name of the variable
- - value: the value of primitive types (scalars) => string/int/bool/double
- - length: if string, then the length of that string
-
### vars / globals ###
- &lt;variableinfo num="" /> with num having an integer value, indicating the number of (local or superglobal) variables
@@ -282,7 +259,7 @@ info (subcommands)
- function
- file
- opline
-- for each variable there is a &lt;variable> element
+- for each variable there is a &lt;variable> followed by a &lt;variabledetails> element
- &lt;variable address="" refcount="" type="" name="" />
- address: pointer to zval (hexadecimal)
- refcount: refcount of zval
@@ -291,8 +268,6 @@ info (subcommands)
- refstatus: empty if the zval is not a reference
- class: the class the object in the zval is an instance of
- resource: the type of the resource in the zval
- - value: the value of primitive types (scalars) => string/int/bool/double
- - length: if string, then the length of that string
### literal ###
@@ -461,8 +436,6 @@ ev
- eval()uates some code
- output wrapped in &lt;eval> tags
-- output is here first a dump of xml tags (see "Variable Dump" section), then a dump wrapped in <stream> tags
-- if there's an error, the tag will be <eval>, instead of the usual <php> tag
sh
--
@@ -636,7 +609,6 @@ dl
- errors may have the module or extension attribute when their name is already known at the point of failure
-
Other tags
==========
@@ -677,83 +649,3 @@ Other tags
- generally emitted when data couldn't be fetched (e.g. by accessing inconsistent data); only used in hard interrupt mode
- it might mean that data couldn't be fetched at all, or that only incomplete data was fetched (e.g. when a fixed number of following attributes are fetched, this tag will mark a stop of fetching if none or not all tags were printed)
-
-
-Variable Dump
-=============
-
-- all except property and element tags have a refstatus attribute, is set to non-empty if it's a reference
-
-object properties
------------------
-
-- wrapped in a property tag &lt;property name="" protection="">
- - name: name of key
- - protection: one of these three values: public / protected / private
- - class: only present if protection attribute is set to "private", contains the name of the class to which the property belongs
-- if the property tag contains any serverity="error" attribute, there was some crucial error to read it, just skip it
-
-array elements
---------------
-- wrapped in an element tag &lt;property name="" protection="">
- - name: name of key
-- if the element tag contains any serverity="error" attribute, there was some crucial error to read it, jsut skip it
-
-int
----
-
-- &lt;int refstatus="" value="" />
- - value is the integer
-
-float
------
-
-- &lt;float refstatus="" value="" />
- - value is the float
-
-bool
-----
-
-- &lt;bool refstatus="" value="" />
- -value: true or false
-
-string
-------
-
-- &lt;string refstatus="" length="" value="" />
- - length: length or string
- - value: the string
-
-null
-----
-
-- &lt;null refstatus="" />
-
-array
------
-
-- &lt;array refstatus="" num="">
- - num: number of elements
- - contains &lt;element> tags
-
-object
-------
-
-- &lt;object refstatus="" class="" id="" num="">
- - class: name of the class the object is an instance of (may be empty if unknown)
- - id: id of the object
- - num: number of properties
- - contains &lt;property> tags
-
-resource
---------
-
-- &lt;resource refstatus="" id="" type="" />
- - id: resource id
- - type: type of resource
-
-recursion
----------
-
-- &lt;recursion />
-- if that tag appears, there's a recursive reference inside the value to be printed