Cleanup shutdown, enable proper memory leak displaying

phpdbg should not memory leak...
This commit is contained in:
Bob Weinand 2015-07-24 17:17:09 +02:00
parent bf1ecbfe16
commit 13525328ed
13 changed files with 177 additions and 177 deletions

View File

@ -343,13 +343,14 @@ ZEND_API zend_bool destroy_op_array(zend_op_array *op_array)
if (op_array->static_variables &&
!(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) {
if (--GC_REFCOUNT(op_array->static_variables) == 0) {
if (--GC_REFCOUNT(op_array->static_variables) == 0) {
zend_array_destroy(op_array->static_variables);
}
}
if (op_array->run_time_cache && !op_array->function_name) {
efree(op_array->run_time_cache);
op_array->run_time_cache = NULL;
}
if (!op_array->refcount) {

View File

@ -175,7 +175,7 @@ char *alloca();
# endif
#endif
#if ZEND_GCC_VERSION >= 2096
#if ZEND_GCC_VERSION >= 2096 || __has_attribute(__malloc__)
# define ZEND_ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
#else
# define ZEND_ATTRIBUTE_MALLOC
@ -221,12 +221,16 @@ char *alloca();
# define ZEND_ATTRIBUTE_UNUSED_LABEL
#endif
#if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004 && defined(__i386__)
# define ZEND_FASTCALL __attribute__((fastcall))
#elif defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER == 1700
# define ZEND_FASTCALL __fastcall
#elif defined(_MSC_VER) && _MSC_VER >= 1800 && !defined(__clang__)
# define ZEND_FASTCALL __vectorcall
#if !ZEND_DEBUG
# if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004 && defined(__i386__)
# define ZEND_FASTCALL __attribute__((fastcall))
# elif defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER == 1700
# define ZEND_FASTCALL __fastcall
# elif defined(_MSC_VER) && _MSC_VER >= 1800 && !defined(__clang__)
# define ZEND_FASTCALL __vectorcall
# else
# define ZEND_FASTCALL
# endif
#else
# define ZEND_FASTCALL
#endif

View File

@ -524,7 +524,7 @@ zend_bool php_std_auto_global_callback(char *name, uint name_len)
/* {{{ php_build_argv
*/
static void php_build_argv(char *s, zval *track_vars_array)
PHPAPI void php_build_argv(char *s, zval *track_vars_array)
{
zval arr, argc, tmp;
int count = 0;

View File

@ -41,6 +41,7 @@ PHPAPI void php_register_variable(char *var, char *val, zval *track_vars_array);
PHPAPI void php_register_variable_safe(char *var, char *val, size_t val_len, zval *track_vars_array);
PHPAPI void php_register_variable_ex(char *var, zval *val, zval *track_vars_array);
PHPAPI void php_build_argv(char *s, zval *track_vars_array);
PHPAPI int php_hash_environment(void);
END_EXTERN_C()

View File

@ -72,12 +72,6 @@ PHP_INI_END()
static zend_bool phpdbg_booted = 0;
static zend_bool phpdbg_fully_started = 0;
#if PHP_VERSION_ID >= 50500
void (*zend_execute_old)(zend_execute_data *execute_data);
#else
void (*zend_execute_old)(zend_op_array *op_array);
#endif
static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */
{
pg->prompt[0] = NULL;
@ -102,6 +96,7 @@ static inline void php_phpdbg_globals_ctor(zend_phpdbg_globals *pg) /* {{{ */
pg->sapi_name_ptr = NULL;
pg->socket_fd = -1;
pg->socket_server_fd = -1;
pg->unclean_eval = 0;
pg->req_id = 0;
pg->err_buf.active = 0;
@ -126,13 +121,7 @@ static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */
ZEND_INIT_MODULE_GLOBALS(phpdbg, php_phpdbg_globals_ctor, NULL);
REGISTER_INI_ENTRIES();
#if PHP_VERSION_ID >= 50500
zend_execute_old = zend_execute_ex;
zend_execute_ex = phpdbg_execute_ex;
#else
zend_execute_old = zend_execute;
zend_execute = phpdbg_execute_ex;
#endif
REGISTER_STRINGL_CONSTANT("PHPDBG_VERSION", PHPDBG_VERSION, sizeof(PHPDBG_VERSION)-1, CONST_CS|CONST_PERSISTENT);
@ -151,43 +140,42 @@ static PHP_MINIT_FUNCTION(phpdbg) /* {{{ */
static void php_phpdbg_destroy_bp_file(zval *brake) /* {{{ */
{
zend_hash_destroy(Z_ARRVAL_P(brake));
efree(Z_ARRVAL_P(brake));
} /* }}} */
static void php_phpdbg_destroy_bp_symbol(zval *brake) /* {{{ */
{
efree((char *) ((phpdbg_breaksymbol_t *) Z_PTR_P(brake))->symbol);
efree(Z_PTR_P(brake));
} /* }}} */
static void php_phpdbg_destroy_bp_opcode(zval *brake) /* {{{ */
{
efree((char *) ((phpdbg_breakop_t *) Z_PTR_P(brake))->name);
efree(Z_PTR_P(brake));
} /* }}} */
static void php_phpdbg_destroy_bp_methods(zval *brake) /* {{{ */
{
zend_hash_destroy(Z_ARRVAL_P(brake));
efree(Z_ARRVAL_P(brake));
} /* }}} */
static void php_phpdbg_destroy_bp_condition(zval *data) /* {{{ */
{
phpdbg_breakcond_t *brake = (phpdbg_breakcond_t *) Z_PTR_P(data);
if (brake) {
if (brake->ops) {
destroy_op_array(brake->ops);
efree(brake->ops);
}
efree((char*) brake->code);
if (brake->ops) {
destroy_op_array(brake->ops);
efree(brake->ops);
}
efree((char*) brake->code);
efree(brake);
} /* }}} */
static void php_phpdbg_destroy_registered(zval *data) /* {{{ */
{
zend_function *function = (zend_function *) Z_PTR_P(data);
destroy_zend_function(function);
} /* }}} */
@ -215,6 +203,7 @@ static PHP_RINIT_FUNCTION(phpdbg) /* {{{ */
static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
{
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE]);
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_FILE_PENDING]);
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_SYM]);
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_FUNCTION_OPLINE]);
zend_hash_destroy(&PHPDBG_G(bp)[PHPDBG_BREAK_METHOD_OPLINE]);
@ -240,16 +229,6 @@ static PHP_RSHUTDOWN_FUNCTION(phpdbg) /* {{{ */
PHPDBG_G(exec) = NULL;
}
if (PHPDBG_G(prompt)[0]) {
free(PHPDBG_G(prompt)[0]);
}
if (PHPDBG_G(prompt)[1]) {
free(PHPDBG_G(prompt)[1]);
}
PHPDBG_G(prompt)[0] = NULL;
PHPDBG_G(prompt)[1] = NULL;
if (PHPDBG_G(oplog)) {
fclose(PHPDBG_G(oplog));
PHPDBG_G(oplog) = NULL;
@ -847,25 +826,8 @@ static void php_sapi_phpdbg_log_message(char *message) /* {{{ */
static int php_sapi_phpdbg_deactivate(void) /* {{{ */
{
if ((PHPDBG_G(flags) & PHPDBG_IS_STOPPING) == PHPDBG_IS_CLEANING) {
zend_phpdbg_globals *pg = PHPDBG_G(backup) = calloc(1, sizeof(zend_phpdbg_globals));
php_phpdbg_globals_ctor(pg);
pg->exec = zend_strndup(PHPDBG_G(exec), PHPDBG_G(exec_len));
pg->exec_len = PHPDBG_G(exec_len);
pg->oplog = PHPDBG_G(oplog);
pg->prompt[0] = PHPDBG_G(prompt)[0];
pg->prompt[1] = PHPDBG_G(prompt)[1];
memcpy(pg->colors, PHPDBG_G(colors), sizeof(pg->colors));
pg->eol = PHPDBG_G(eol);
pg->input_buflen = PHPDBG_G(input_buflen);
memcpy(pg->input_buffer, PHPDBG_G(input_buffer), pg->input_buflen);
pg->flags = PHPDBG_G(flags) & PHPDBG_PRESERVE_FLAGS_MASK;
}
fflush(stdout);
if(SG(request_info).argv0) {
if (SG(request_info).argv0) {
free(SG(request_info).argv0);
SG(request_info).argv0 = NULL;
}
@ -946,14 +908,8 @@ static size_t phpdbg_stdiop_write(php_stream *stream, const char *buf, size_t co
return PHPDBG_G(php_stdiop_write)(stream, buf, count);
}
#if PHP_VERSION_ID >= 50700
static inline void php_sapi_phpdbg_flush(void *context) /* {{{ */
{
#else
static inline void php_sapi_phpdbg_flush(void *context) /* {{{ */
{
#endif
if (!phpdbg_active_sigsafe_mem()) {
fflush(PHPDBG_G(io)[PHPDBG_STDOUT].ptr);
}
@ -1083,7 +1039,6 @@ 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); \
zend_hash_str_update(configuration_hash, name, sizeof(name) - 1, &tmp);
void phpdbg_ini_defaults(HashTable *configuration_hash) /* {{{ */
@ -1269,37 +1224,55 @@ void phpdbg_signal_handler(int sig, siginfo_t *info, void *context) /* {{{ */
} /* }}} */
#endif
static inline zend_mm_heap *phpdbg_mm_get_heap() /* {{{ */
{
zend_mm_heap *mm_heap;
mm_heap = zend_mm_set_heap(NULL);
zend_mm_set_heap(mm_heap);
return mm_heap;
} /* }}} */
/* A bit dark magic in order to have meaningful allocator adresses */
#if ZEND_DEBUG && __has_builtin(__builtin_frame_address)
#define FETCH_PARENT_FILELINE(argsize) \
char *__zend_filename, *__zend_orig_filename; \
uint __zend_lineno, __zend_orig_lineno; \
void *parent = __builtin_frame_address(1U); \
parent -= ZEND_MM_ALIGNED_SIZE(sizeof(void *)); /* remove frame pointer adress */ \
parent -= (argsize); /* size of first arguments */ \
parent -= sizeof(char *); /* filename */ \
__zend_filename = *(char **) parent; \
parent = (void *) ((intptr_t) parent & ZEND_MM_ALIGNMENT_MASK); /* realign */ \
parent -= sizeof(uint); /* lineno */ \
__zend_lineno = *(uint *) parent; \
parent = (void *) ((intptr_t) parent & ZEND_MM_ALIGNMENT_MASK); /* realign */ \
parent -= sizeof(char *); /* orig_filename */ \
__zend_orig_filename = *(char **) parent; \
parent = (void *) ((intptr_t) parent & ZEND_MM_ALIGNMENT_MASK); /* realign */ \
parent -= sizeof(uint); /* orig_lineno */ \
__zend_orig_lineno = *(uint *) parent;
#elif ZEND_DEBUG
#define FETCH_PARENT_FILELINE() \
char *__zend_filename = __FILE__, *__zend_orig_filename = NULL; \
uint __zend_lineno = __LINE__, __zend_orig_lineno = 0;
#endif
void *phpdbg_malloc_wrapper(size_t size) /* {{{ */
{
return zend_mm_alloc(phpdbg_mm_get_heap(), size);
FETCH_PARENT_FILELINE(ZEND_MM_ALIGNED_SIZE(sizeof(size)));
return _zend_mm_alloc(zend_mm_get_heap(), size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
} /* }}} */
void phpdbg_free_wrapper(void *p) /* {{{ */
{
zend_mm_heap *heap = phpdbg_mm_get_heap();
zend_mm_heap *heap = zend_mm_get_heap();
if (UNEXPECTED(heap == p)) {
/* TODO: heap maybe allocated by mmap(zend_mm_init) or malloc(USE_ZEND_ALLOC=0)
* let's prevent it from segfault for now
*/
} else {
zend_mm_free(heap, p);
FETCH_PARENT_FILELINE(ZEND_MM_ALIGNED_SIZE(sizeof(p)));
return _zend_mm_free(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
}
} /* }}} */
void *phpdbg_realloc_wrapper(void *ptr, size_t size) /* {{{ */
{
return zend_mm_realloc(phpdbg_mm_get_heap(), ptr, size);
FETCH_PARENT_FILELINE(ZEND_MM_ALIGNED_SIZE(sizeof(ptr)) + ZEND_MM_ALIGNED_SIZE(sizeof(size)));
return _zend_mm_realloc(zend_mm_get_heap(), ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
} /* }}} */
int main(int argc, char **argv) /* {{{ */
@ -1333,6 +1306,7 @@ int main(int argc, char **argv) /* {{{ */
FILE* stream = NULL;
char *print_opline_func;
zend_bool ext_stmt = 0;
zend_bool use_mm_wrappers = 0;
#ifdef ZTS
void ***tsrm_ls;
@ -1624,6 +1598,7 @@ phpdbg_main:
#else
phpdbg_globals = *settings;
#endif
free(settings);
}
/* setup remote server if necessary */
@ -1641,21 +1616,17 @@ phpdbg_main:
remote = 1;
}
mm_heap = phpdbg_mm_get_heap();
mm_heap = zend_mm_get_heap();
zend_mm_get_custom_handlers(mm_heap, &_malloc, &_free, &_realloc);
if (!_malloc) {
use_mm_wrappers = !_malloc && !_realloc && !_free;
if (use_mm_wrappers) {
_malloc = phpdbg_malloc_wrapper;
}
if (!_realloc) {
_realloc = phpdbg_realloc_wrapper;
}
if (!_free) {
_free = phpdbg_free_wrapper;
}
zend_activate();
phpdbg_init_list();
PHPDBG_G(original_free_function) = _free;
@ -1692,9 +1663,14 @@ phpdbg_main:
php_output_activate();
php_output_deactivate();
if (SG(sapi_headers).mimetype) {
efree(SG(sapi_headers).mimetype);
SG(sapi_headers).mimetype = NULL;
}
php_output_activate();
if (php_request_startup() == SUCCESS) {
{
int i;
SG(request_info).argc = argc - php_optind + 1;
@ -1703,8 +1679,11 @@ phpdbg_main:
SG(request_info).argv[i] = estrdup(argv[php_optind - 1 + i]);
}
SG(request_info).argv[0] = PHPDBG_G(exec) ? estrdup(PHPDBG_G(exec)) : estrdup("");
}
php_hash_environment();
if (php_request_startup() == FAILURE) {
PUTS("Could not startup");
return 1;
}
/* do not install sigint handlers for remote consoles */
@ -1721,7 +1700,7 @@ phpdbg_main:
}
#endif
PG(modules_activated) = 0;
// PG(modules_activated) = 0;
#ifndef _WIN32
/* setup io here */
@ -1842,7 +1821,6 @@ phpdbg_main:
#ifndef _WIN32
phpdbg_interact:
#endif
/* phpdbg main() */
do {
zend_try {
@ -1857,6 +1835,7 @@ phpdbg_interact:
}
}
CG(unclean_shutdown) = 0;
phpdbg_interactive(1);
} zend_catch {
if ((PHPDBG_G(flags) & PHPDBG_IS_CLEANING)) {
@ -1900,16 +1879,6 @@ phpdbg_interact:
} while (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING));
if (PHPDBG_G(exec) && (PHPDBG_G(flags) & PHPDBG_IS_CLEANING)) {
exec = strdup(PHPDBG_G(exec)); /* preserve exec, don't reparse that from cmd */
}
/* this must be forced */
CG(unclean_shutdown) = 0;
/* this is just helpful */
PG(report_memleaks) = 0;
#ifndef _WIN32
phpdbg_out:
if ((PHPDBG_G(flags) & PHPDBG_IS_DISCONNECTED)) {
@ -1939,16 +1908,6 @@ phpdbg_out:
efree(SG(request_info).argv);
}
#ifndef _WIN32
/* reset it... else we risk a stack overflow upon next run (when clean'ing) */
php_stream_stdio_ops.write = PHPDBG_G(php_stdiop_write);
#endif
#ifndef ZTS
/* force cleanup of auto and core globals */
zend_hash_clean(CG(auto_globals));
memset( &core_globals, 0, sizeof(php_core_globals));
#endif
if (ini_entries) {
free(ini_entries);
}
@ -1957,42 +1916,70 @@ phpdbg_out:
free(ini_override);
}
/* this must be forced */
CG(unclean_shutdown) = 0;
/* this is just helpful */
PG(report_memleaks) = 0;
/* In case we aborted during script execution, we may not reset CG(unclean_shutdown) */
if (!(PHPDBG_G(flags) & PHPDBG_IS_RUNNING)) {
CG(unclean_shutdown) = PHPDBG_G(unclean_eval);
}
if ((PHPDBG_G(flags) & (PHPDBG_IS_CLEANING | PHPDBG_IS_RUNNING)) == PHPDBG_IS_CLEANING) {
php_free_shutdown_functions();
zend_objects_store_mark_destructed(&EG(objects_store));
}
/* sapi_module.deactivate is where to backup things, last chance before mm_shutdown... */
/* backup globals when cleaning */
if ((cleaning > 0 || remote) && !quit_immediately) {
settings = calloc(1, sizeof(zend_phpdbg_globals));
php_phpdbg_globals_ctor(settings);
if (PHPDBG_G(exec)) {
settings->exec = zend_strndup(PHPDBG_G(exec), PHPDBG_G(exec_len));
settings->exec_len = PHPDBG_G(exec_len);
}
settings->oplog = PHPDBG_G(oplog);
settings->prompt[0] = PHPDBG_G(prompt)[0];
settings->prompt[1] = PHPDBG_G(prompt)[1];
memcpy(settings->colors, PHPDBG_G(colors), sizeof(settings->colors));
settings->eol = PHPDBG_G(eol);
settings->input_buflen = PHPDBG_G(input_buflen);
memcpy(settings->input_buffer, PHPDBG_G(input_buffer), settings->input_buflen);
settings->flags = PHPDBG_G(flags) & PHPDBG_PRESERVE_FLAGS_MASK;
} else {
if (PHPDBG_G(prompt)[0]) {
free(PHPDBG_G(prompt)[0]);
}
if (PHPDBG_G(prompt)[1]) {
free(PHPDBG_G(prompt)[1]);
}
}
/* hack to restore mm_heap->use_custom_heap in order to receive memory leak info */
if (use_mm_wrappers) {
/* ASSUMING that mm_heap->use_custom_heap is the first element of the struct ... */
*(int *) mm_heap = 0;
}
zend_try {
php_request_shutdown(NULL);
} zend_end_try();
if ((PHPDBG_G(flags) & (PHPDBG_IS_QUITTING | PHPDBG_IS_RUNNING)) == PHPDBG_IS_RUNNING) {
if (!(PHPDBG_G(flags) & PHPDBG_IS_QUITTING) && PHPDBG_G(in_execution)) {
if (!quit_immediately && !phpdbg_startup_run) {
phpdbg_notice("stop", "type=\"normal\"", "Script ended normally");
cleaning++;
}
cleaning++;
}
if ((PHPDBG_G(flags) & PHPDBG_IS_STOPPING) == PHPDBG_IS_CLEANING) {
settings = PHPDBG_G(backup);
}
php_output_deactivate();
zend_try {
php_module_shutdown();
} zend_end_try();
sapi_shutdown();
#ifndef _WIN32
/* reset it... else we risk a stack overflow upon next run (when clean'ing) */
php_stream_stdio_ops.write = PHPDBG_G(php_stdiop_write);
#endif
sapi_shutdown();
}
if ((cleaning > 0 || remote) && !quit_immediately) {

View File

@ -259,6 +259,7 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
int bp_count; /* breakpoint count */
int vmret; /* return from last opcode handler execution */
zend_bool in_execution; /* in execution? */
zend_bool unclean_eval; /* do not check for memory leaks when we needed to bail out during eval */
zend_op_array *(*compile_file)(zend_file_handle *file_handle, int type);
HashTable file_sources;
@ -308,8 +309,6 @@ ZEND_BEGIN_MODULE_GLOBALS(phpdbg)
HANDLE sigio_watcher_thread; /* sigio watcher thread handle */
struct win32_sigio_watcher_data swd;
#endif
struct _zend_phpdbg_globals *backup; /* backup of data to store */
ZEND_END_MODULE_GLOBALS(phpdbg) /* }}} */
#endif

View File

@ -63,6 +63,7 @@ static void phpdbg_file_breaks_dtor(zval *data) /* {{{ */
phpdbg_breakfile_t *bp = (phpdbg_breakfile_t*) Z_PTR_P(data);
efree((char*)bp->filename);
efree(bp);
} /* }}} */
static void phpdbg_class_breaks_dtor(zval *data) /* {{{ */
@ -71,11 +72,13 @@ static void phpdbg_class_breaks_dtor(zval *data) /* {{{ */
efree((char*)bp->class_name);
efree((char*)bp->func_name);
efree(bp);
} /* }}} */
static void phpdbg_opline_class_breaks_dtor(zval *data) /* {{{ */
{
zend_hash_destroy((HashTable *) Z_PTR_P(data));
zend_hash_destroy(Z_ARRVAL_P(data));
efree(Z_ARRVAL_P(data));
} /* }}} */
static void phpdbg_opline_breaks_dtor(zval *data) /* {{{ */
@ -88,6 +91,7 @@ static void phpdbg_opline_breaks_dtor(zval *data) /* {{{ */
if (bp->func_name) {
efree((char*)bp->func_name);
}
efree(bp);
} /* }}} */
PHPDBG_API void phpdbg_reset_breakpoints(void) /* {{{ */
@ -230,8 +234,9 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num) /* {
char realpath[MAXPATHLEN];
const char *original_path = path;
zend_bool pending = 0;
zend_string *path_str;
HashTable *broken, *file_breaks = &PHPDBG_G(bp)[PHPDBG_BREAK_FILE];
HashTable *broken, *file_breaks = &PHPDBG_G(bp)[PHPDBG_BREAK_FILE];
phpdbg_breakfile_t new_break;
size_t path_len = 0L;
@ -261,11 +266,13 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num) /* {
}
}
if (!(broken = zend_hash_str_find_ptr(file_breaks, path, path_len))) {
path_str = zend_string_init(path, path_len, 0);
if (!(broken = zend_hash_find_ptr(file_breaks, path_str))) {
HashTable breaks;
zend_hash_init(&breaks, 8, NULL, phpdbg_file_breaks_dtor, 0);
broken = zend_hash_str_add_mem(file_breaks, path, path_len, &breaks, sizeof(HashTable));
broken = zend_hash_add_mem(file_breaks, path_str, &breaks, sizeof(HashTable));
}
if (!zend_hash_index_exists(broken, line_num)) {
@ -278,7 +285,7 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num) /* {
PHPDBG_BREAK_MAPPING(new_break.id, broken);
if (pending) {
zend_string *file, *path_str = zend_string_init(path, path_len, 0);
zend_string *file;
ZEND_HASH_FOREACH_STR_KEY(&PHPDBG_G(file_sources), file) {
HashTable *fileht;
@ -289,7 +296,6 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num) /* {
break;
}
} ZEND_HASH_FOREACH_END();
zend_string_release(path_str);
}
if (pending) {
@ -304,6 +310,8 @@ PHPDBG_API void phpdbg_set_breakpoint_file(const char *path, long line_num) /* {
} else {
phpdbg_error("breakpoint", "type=\"exists\" add=\"fail\" file=\"%s\" line=\"%ld\"", "Breakpoint at %s:%ld exists", path, line_num);
}
zend_string_release(path_str);
} /* }}} */
PHPDBG_API HashTable *phpdbg_resolve_pending_file_break_ex(const char *file, uint filelen, zend_string *cur, HashTable *fileht) /* {{{ */
@ -1066,11 +1074,7 @@ static inline phpdbg_breakbase_t *phpdbg_find_conditional_breakpoint(zend_execut
zend_try {
PHPDBG_G(flags) |= PHPDBG_IN_COND_BP;
zend_execute(bp->ops, &retval);
#if PHP_VERSION_ID >= 50700
if (zend_is_true(&retval)) {
#else
if (zend_is_true(&retval)) {
#endif
breakpoint = SUCCESS;
}
} zend_end_try();

View File

@ -765,6 +765,9 @@ PHPDBG_API char *phpdbg_read_input(char *buffered) /* {{{ */
PHPDBG_G(buffer) = estrdup(buffer);
} else {
if (PHPDBG_G(buffer)) {
if (buffer) {
efree(buffer);
}
buffer = estrdup(PHPDBG_G(buffer));
}
}

View File

@ -253,8 +253,8 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) {
}
#if HAVE_MMAP
if (file->handle.stream.mmap.map) {
data.map = file->handle.stream.mmap.map;
if (file->type == ZEND_HANDLE_MAPPED) {
data.map = file->handle.stream.handle;
}
#endif
@ -289,11 +289,13 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) {
zend_file_handle_dtor(&fake);
dataptr->op_array = ret;
if (dataptr->op_array->refcount) {
++*dataptr->op_array->refcount;
} else {
dataptr->op_array->refcount = emalloc(sizeof(uint32_t));
*dataptr->op_array->refcount = 2;
if (data->op_array) {
if (dataptr->op_array->refcount) {
++*dataptr->op_array->refcount;
} else {
dataptr->op_array->refcount = emalloc(sizeof(uint32_t));
*dataptr->op_array->refcount = 2;
}
}
return ret;
@ -304,7 +306,7 @@ void phpdbg_free_file_source(zval *zv) {
#if HAVE_MMAP
if (data->map) {
munmap(data->map, data->len + ZEND_MMAP_AHEAD);
php_stream_mmap_unmap(data->map);
} else
#endif
if (data->buf) {

View File

@ -1281,6 +1281,7 @@ PHPDBG_API int phpdbg_out_internal(int fd, const char *fmt, ...) {
len = phpdbg_mixed_write(fd, buffer, buflen);
}
efree(buffer);
return len;
}

View File

@ -418,12 +418,13 @@ PHPDBG_COMMAND(exec) /* {{{ */
VCWD_CHDIR_FILE(res);
*SG(request_info).argv = PHPDBG_G(exec);
php_hash_environment();
php_build_argv(NULL, &PG(http_globals)[TRACK_VARS_SERVER]);
phpdbg_notice("exec", "type=\"set\" context=\"%s\"", "Set execution context: %s", PHPDBG_G(exec));
if (PHPDBG_G(in_execution)) {
phpdbg_clean(1);
return SUCCESS;
}
phpdbg_compile();
@ -678,7 +679,7 @@ PHPDBG_COMMAND(run) /* {{{ */
SG(request_info).argv = erealloc(argv, ++argc * sizeof(char *));
SG(request_info).argc = argc;
php_hash_environment();
php_build_argv(NULL, &PG(http_globals)[TRACK_VARS_SERVER]);
}
zend_try {
@ -689,13 +690,11 @@ PHPDBG_COMMAND(run) /* {{{ */
} zend_catch {
PHPDBG_G(in_execution) = 0;
if (PHPDBG_G(flags) & PHPDBG_IS_QUITTING) {
zend_bailout();
}
if (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)) {
phpdbg_error("stop", "type=\"bailout\"", "Caught exit/error from VM");
restore = 0;
} else {
zend_bailout();
}
} zend_end_try();
@ -708,8 +707,9 @@ PHPDBG_COMMAND(run) /* {{{ */
if (EG(exception)) {
phpdbg_handle_exception();
}
}
PHPDBG_G(in_execution) = 1;
}
phpdbg_clean(1);
PHPDBG_G(flags) &= ~PHPDBG_IS_RUNNING;
@ -744,6 +744,7 @@ PHPDBG_COMMAND(ev) /* {{{ */
zend_execute_data *original_execute_data = EG(current_execute_data);
zend_class_entry *original_scope = EG(scope);
zend_vm_stack original_stack = EG(vm_stack);
zend_object *ex = NULL;
PHPDBG_OUTPUT_BACKUP();
@ -769,6 +770,7 @@ PHPDBG_COMMAND(ev) /* {{{ */
zend_try {
if (zend_eval_stringl(param->str, param->len, &retval, "eval()'d code") == SUCCESS) {
if (EG(exception)) {
ex = EG(exception);
zend_exception_error(EG(exception), E_ERROR);
} else {
phpdbg_xml("<eval %r>");
@ -783,6 +785,10 @@ PHPDBG_COMMAND(ev) /* {{{ */
}
}
} zend_catch {
PHPDBG_G(unclean_eval) = 1;
if (ex) {
OBJ_RELEASE(ex);
}
EG(current_execute_data) = original_execute_data;
EG(scope) = original_scope;
EG(vm_stack_top) = original_stack->top;
@ -1185,14 +1191,10 @@ PHPDBG_COMMAND(register) /* {{{ */
PHPDBG_COMMAND(quit) /* {{{ */
{
/* don't allow this to loop, ever ... */
if (!(PHPDBG_G(flags) & PHPDBG_IS_STOPPING)) {
PHPDBG_G(flags) |= PHPDBG_IS_QUITTING;
PHPDBG_G(flags) &= ~(PHPDBG_IS_RUNNING | PHPDBG_IS_CLEANING);
zend_bailout();
}
PHPDBG_G(flags) |= PHPDBG_IS_QUITTING;
PHPDBG_G(flags) &= ~PHPDBG_IS_CLEANING;
return PHPDBG_NEXT;
return SUCCESS;
} /* }}} */
PHPDBG_COMMAND(clean) /* {{{ */
@ -1211,8 +1213,6 @@ PHPDBG_COMMAND(clean) /* {{{ */
phpdbg_writeln("clean", "constants=\"%d\"", "Constants %d", zend_hash_num_elements(EG(zend_constants)));
phpdbg_writeln("clean", "includes=\"%d\"", "Includes %d", zend_hash_num_elements(&EG(included_files)));
PHPDBG_G(flags) &= ~PHPDBG_IS_RUNNING;
phpdbg_clean(1);
phpdbg_xml("</cleaninfo>");
@ -1291,7 +1291,7 @@ int phpdbg_interactive(zend_bool allow_async_unsafe) /* {{{ */
PHPDBG_G(flags) |= PHPDBG_IS_INTERACTIVE;
while (ret == SUCCESS || ret == FAILURE) {
if ((PHPDBG_G(flags) & (PHPDBG_IS_STOPPING | PHPDBG_IS_RUNNING)) == PHPDBG_IS_STOPPING) {
if (PHPDBG_G(flags) & PHPDBG_IS_STOPPING) {
zend_bailout();
}
@ -1370,15 +1370,14 @@ void phpdbg_clean(zend_bool full) /* {{{ */
{
/* this is implicitly required */
if (PHPDBG_G(ops)) {
destroy_op_array(PHPDBG_G(ops));
efree(PHPDBG_G(ops));
if (destroy_op_array(PHPDBG_G(ops))) {
efree(PHPDBG_G(ops));
}
PHPDBG_G(ops) = NULL;
}
if (full) {
PHPDBG_G(flags) |= PHPDBG_IS_CLEANING;
zend_bailout();
}
} /* }}} */

View File

@ -64,11 +64,6 @@ PHPDBG_COMMAND(wait); /* }}} */
/* {{{ prompt commands */
extern const phpdbg_command_t phpdbg_prompt_commands[]; /* }}} */
/* {{{ */
#if PHP_VERSION_ID >= 50500
void phpdbg_execute_ex(zend_execute_data *execute_data);
#else
void phpdbg_execute_ex(zend_op_array *op_array);
#endif /* }}} */
#endif /* PHPDBG_PROMPT_H */

View File

@ -166,16 +166,20 @@ PHPDBG_API const char *phpdbg_current_file(void) /* {{{ */
PHPDBG_API const zend_function *phpdbg_get_function(const char *fname, const char *cname) /* {{{ */
{
zend_function *func = NULL;
zend_string *lfname = zend_string_alloc(strlen(fname), 0);
memcpy(ZSTR_VAL(lfname), zend_str_tolower_dup(fname, ZSTR_LEN(lfname)), ZSTR_LEN(lfname) + 1);
zend_string *lfname = zend_string_init(fname, strlen(fname), 0);
zend_string *tmp = zend_string_tolower(lfname);
zend_string_release(lfname);
lfname = tmp;
if (cname) {
zend_class_entry *ce;
zend_string *lcname = zend_string_alloc(strlen(cname), 0);
memcpy(ZSTR_VAL(lcname), zend_str_tolower_dup(cname, ZSTR_LEN(lcname)), ZSTR_LEN(lcname) + 1);
zend_string *lcname = zend_string_init(cname, strlen(cname), 0);
tmp = zend_string_tolower(lcname);
zend_string_release(lcname);
lcname = tmp;
ce = zend_lookup_class(lcname);
efree(lcname);
zend_string_release(lcname);
if (ce) {
func = zend_hash_find_ptr(&ce->function_table, lfname);
@ -184,7 +188,7 @@ PHPDBG_API const zend_function *phpdbg_get_function(const char *fname, const cha
func = zend_hash_find_ptr(EG(function_table), lfname);
}
efree(lfname);
zend_string_release(lfname);
return func;
} /* }}} */