pg->ops = NULL;
pg->vmret = 0;
pg->bp_count = 0;
- pg->last = NULL;
+ pg->lcmd = NULL;
pg->lparam = NULL;
pg->flags = PHPDBG_DEFAULT_FLAGS;
pg->oplog = NULL;
}
} /* }}} */
-static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */
+static void php_phpdbg_destroy_param(void *data) /* {{{ */
{
+ phpdbg_param_t *param = (phpdbg_param_t*) data;
+
+ if (param) {
+ TSRMLS_FETCH();
+
+ phpdbg_clear_param(param TSRMLS_CC);
+ efree(param);
+ }
+} /* }}} */
+
+static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */
+{
zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE], 8, NULL, php_phpdbg_destroy_bp_file, 0);
zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM], 8, NULL, php_phpdbg_destroy_bp_symbol, 0);
zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE], 8, NULL, NULL, 0);
zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD], 8, NULL, php_phpdbg_destroy_bp_methods, 0);
zend_hash_init(&PHPDBG_G(bp)[PHPDBG_BREAK_COND], 8, NULL, php_phpdbg_destroy_bp_condition, 0);
+
zend_hash_init(&PHPDBG_G(seek), 8, NULL, NULL, 0);
+ zend_hash_init(&PHPDBG_G(params), 8, NULL, php_phpdbg_destroy_param, 0);
+
return SUCCESS;
} /* }}} */
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_OPLINE]);
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD]);
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_COND]);
+
zend_hash_destroy(&PHPDBG_G(seek));
+ zend_hash_destroy(&PHPDBG_G(params));
if (PHPDBG_G(exec)) {
efree(PHPDBG_G(exec));
zval *retval; /* return value */
int bp_count; /* breakpoint count */
int vmret; /* return from last opcode handler execution */
- phpdbg_command_t *last; /* last command */
+ phpdbg_command_t *lcmd; /* last command */
phpdbg_param_t *lparam; /* last param */
- zend_ulong flags; /* phpdbg flags */
FILE *oplog; /* opline log */
HashTable seek; /* seek oplines */
+ HashTable params; /* parameters */
+ zend_ulong flags; /* phpdbg flags */
ZEND_END_MODULE_GLOBALS(phpdbg)
/* }}} */
}
} /* }}} */
-int phpdbg_do_cmd( const phpdbg_command_t *command,
- phpdbg_command_t **selected,
- char *cmd_line, size_t cmd_len TSRMLS_DC) /* {{{ */
+int phpdbg_do_cmd( const phpdbg_command_t *command, char *cmd_line, size_t cmd_len TSRMLS_DC) /* {{{ */
{
int rc = FAILURE;
if ((command->name_len == expr_len && memcmp(cmd, command->name, expr_len) == 0)
|| (expr_len == 1 && command->alias && command->alias == cmd_line[0])) {
- param = emalloc(sizeof(phpdbg_param_t));
-
- PHPDBG_G(last) = (phpdbg_command_t*) command;
-
- /* urm ... */
- if (PHPDBG_G(lparam)) {
- //phpdbg_clear_param(
- // PHPDBG_G(lparam) TSRMLS_CC);
- //efree(PHPDBG_G(lparam));
- }
+ param = (phpdbg_param_t*) emalloc(sizeof(phpdbg_param_t));
phpdbg_parse_param(
expr,
(cmd_len - expr_len) ? (((cmd_len - expr_len) - sizeof(" "))+1) : 0,
param TSRMLS_CC);
- PHPDBG_G(lparam) = param;
+ PHPDBG_G(lparam) = param;
+ PHPDBG_G(lcmd) = (phpdbg_command_t*) command;
+
+ /* avoid leaks */
+ zend_hash_next_index_insert(
+ &PHPDBG_G(params), (void**)¶m, sizeof(phpdbg_param_t*), NULL);
if (command->subs && param->type == STR_PARAM) {
- if (phpdbg_do_cmd(command->subs, selected, param->str, param->len TSRMLS_CC) == SUCCESS) {
+ if (phpdbg_do_cmd(command->subs, param->str, param->len TSRMLS_CC) == SUCCESS) {
rc = SUCCESS;
- /* because we can */
- phpdbg_clear_param(param TSRMLS_CC);
- efree(param);
goto done;
}
}
- *selected = (phpdbg_command_t*) command;
-
if (command->arg_type == REQUIRED_ARG && param->type == EMPTY_PARAM) {
phpdbg_error("This command requires argument!");
rc = FAILURE;
}
done:
- if (selected && param) {
- phpdbg_debug(
- "phpdbg_do_cmd(%s, \"%s\"): %d",
- command->name, phpdbg_get_param_type(param TSRMLS_CC), (rc==SUCCESS));
- }
-
return rc;
} /* }}} */
/**
* Command Executor
*/
-int phpdbg_do_cmd(const phpdbg_command_t*, phpdbg_command_t**, char *, size_t TSRMLS_DC);
+int phpdbg_do_cmd(const phpdbg_command_t*, char *, size_t TSRMLS_DC);
phpdbg_param_type phpdbg_parse_param(const char*, size_t, phpdbg_param_t* TSRMLS_DC);
void phpdbg_clear_param(phpdbg_param_t * TSRMLS_DC);
const char* phpdbg_get_param_type(const phpdbg_param_t *param TSRMLS_DC);
zend_bool in_code = 0;
while (fgets(cmd, PHPDBG_MAX_CMD, fp) != NULL) {
- phpdbg_command_t *selected = NULL;
-
cmd_len = strlen(cmd)-1;
while (*cmd && isspace(cmd[cmd_len-1]))
goto next_line;
}
- switch (phpdbg_do_cmd(phpdbg_prompt_commands, &selected, cmd, cmd_len TSRMLS_CC)) {
+ switch (phpdbg_do_cmd(phpdbg_prompt_commands, cmd, cmd_len TSRMLS_CC)) {
case FAILURE:
phpdbg_error(
"Unrecognized command in %s:%d: %s!", init_file, line, cmd);
cmd[cmd_len] = '\0';
if (*cmd && cmd_len > 0L) {
- /* keep a cursor to selected command */
- phpdbg_command_t *selected = NULL;
-
#ifdef HAVE_LIBREADLINE
add_history(cmd);
#endif
- switch (ret = phpdbg_do_cmd(phpdbg_prompt_commands, &selected, cmd, cmd_len TSRMLS_CC)) {
+ switch (ret = phpdbg_do_cmd(phpdbg_prompt_commands, cmd, cmd_len TSRMLS_CC)) {
case FAILURE:
if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING)) {
phpdbg_error("Failed to execute %s!", cmd);
cmd = NULL;
}
#endif
- } else if (PHPDBG_G(last)) {
- ret = PHPDBG_G(last)->handler(PHPDBG_G(lparam) TSRMLS_CC);
- goto out;
+ } else {
+ if (PHPDBG_G(lcmd)) {
+ ret = PHPDBG_G(lcmd)->handler(
+ PHPDBG_G(lparam) TSRMLS_CC);
+ goto out;
+ }
}
}