Browse Source

removed some weird crash when freeing to early

pull/661/head
Bob Weinand 13 years ago
parent
commit
f887960f9b
  1. 19
      phpdbg.c
  2. 6
      phpdbg.h
  3. 27
      phpdbg_watch.c
  4. 15
      phpdbg_win.c
  5. 2
      test.php

19
phpdbg.c

@ -1151,15 +1151,17 @@ phpdbg_main:
__try {
#endif
zend_mm_heap *mm_heap = zend_mm_set_heap(NULL TSRMLS_CC);
#if ZEND_DEBUG
if (!mm_heap->use_zend_alloc) {
free(mm_heap);
mm_heap = zend_mm_startup();
mm_heap->_malloc = malloc;
mm_heap->_realloc = realloc;
mm_heap->_free = free;
#endif
PHPDBG_G(original_free_function) = mm_heap->_free;
mm_heap->_free = phpdbg_watch_efree;
mm_heap->use_zend_alloc = 0;
#if ZEND_DEBUG
}
PHPDBG_G(original_free_function) = mm_heap->_free;
#ifdef _WIN32
phpdbg_win_set_mm_heap(mm_heap);
#else
mm_heap->_free = phpdbg_watch_efree;
#endif
zend_mm_set_heap(mm_heap TSRMLS_CC);
@ -1328,8 +1330,8 @@ phpdbg_interact:
/* this is just helpful */
PG(report_memleaks) = 0;
phpdbg_out:
#ifndef _WIN32
phpdbg_out:
if ((PHPDBG_G(flags) & PHPDBG_IS_DISCONNECTED)) {
PHPDBG_G(flags) &= ~PHPDBG_IS_DISCONNECTED;
goto phpdbg_interact;
@ -1340,6 +1342,7 @@ phpdbg_out:
} __except(phpdbg_exception_handler_win32(xp = GetExceptionInformation())) {
phpdbg_error("Access violation (Segementation fault) encountered\ntrying to abort cleanly...");
}
phpdbg_out:
#endif
#ifndef ZTS
/* force cleanup of auto and core globals */

6
phpdbg.h

@ -207,6 +207,12 @@ struct _zend_mm_heap {
void *(*_malloc)(size_t);
void (*_free)(void *);
void *(*_realloc)(void *, size_t);
size_t free_bitmap;
size_t large_free_bitmap;
size_t block_size;
size_t compact_size;
zend_mm_segment *segments_list;
zend_mm_storage *storage;
};
#endif /* PHPDBG_H */

27
phpdbg_watch.c

@ -503,7 +503,6 @@ static void phpdbg_watch_dtor(void *pDest) {
free(watch->str);
free(watch->name_in_parent);
efree(watch);
}
@ -571,14 +570,19 @@ static void phpdbg_print_changed_zval(phpdbg_watch_memdump *dump TSRMLS_DC) {
phpdbg_notice("Breaking on watchpoint %s", watch->str);
switch (watch->type) {
case WATCH_ON_ZVAL:
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);
phpdbg_write("Old value: ");
zend_print_flat_zval_r((zval *)oldPtr TSRMLS_CC);
if ((Z_TYPE_P((zval *)oldPtr) == IS_ARRAY || Z_TYPE_P((zval *)oldPtr) == IS_OBJECT) && removed) {
phpdbg_write("Value inaccessible, HashTable already destroyed");
} else {
zend_print_flat_zval_r((zval *)oldPtr TSRMLS_CC);
}
phpdbg_writeln("\nOld refcount: %d; Old is_ref: %d", ((zval *)oldPtr)->refcount__gc, ((zval *)oldPtr)->is_ref__gc);
/* check if zval was removed */
if (((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)) {
if (removed) {
phpdbg_notice("Watchpoint %s was unset, removing watchpoint", watch->str);
zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
@ -606,9 +610,20 @@ remove_ht_watch:
}
break;
}
case WATCH_ON_HASHTABLE:
#ifdef ZEND_DEBUG
if (watch->addr.ht->inconsistent) {
phpdbg_notice("Watchpoint %s was unset, removing watchpoint", watch->str);
zend_hash_del(&PHPDBG_G(watchpoints), watch->str, watch->str_len);
reenable = 0;
break;
}
#endif
elementDiff = zend_hash_num_elements((HashTable *)oldPtr) - zend_hash_num_elements(watch->addr.ht);
if (elementDiff) {
if (elementDiff > 0) {
@ -668,7 +683,7 @@ void phpdbg_list_watchpoints(TSRMLS_D) {
void phpdbg_watch_efree(void *ptr) {
TSRMLS_FETCH();
phpdbg_btree_result *result = phpdbg_btree_find_closest(&PHPDBG_G(watchpoint_tree), (zend_ulong)ptr);
if (result) {
phpdbg_watchpoint_t *watch = result->ptr;

15
phpdbg_win.c

@ -25,7 +25,7 @@ phpdbg_btree phpdbg_memory_tree;
int mprotect(void *addr, size_t size, int protection) {
int var;
//printf("Set protection of %p to %s\n", addr, protection == (PROT_READ | PROT_WRITE) ? "rw": "r-");
printf("Set protection of %p to %s\n", addr, protection == (PROT_READ | PROT_WRITE) ? "rw": "r-");
return (int)VirtualProtect(addr, size, protection == (PROT_READ | PROT_WRITE) ? PAGE_READWRITE : PAGE_READONLY, &var);
}
@ -33,7 +33,7 @@ size_t virtual_size(void *ptr) {
return (size_t)phpdbg_btree_find(&phpdbg_memory_tree, (zend_ulong)ptr)->ptr;
}
void *virtual_malloc(size_t size) {
/*void *virtual_malloc(size_t size) {
size_t real_size = phpdbg_get_total_page_size(NULL, size);
void *addr = VirtualAlloc(NULL, real_size, MEM_COMMIT, PAGE_READWRITE);
phpdbg_btree_insert(&phpdbg_memory_tree, (zend_ulong)addr, (void *)real_size);
@ -58,15 +58,22 @@ void *virtual_realloc(void *ptr, size_t size) {
memcpy(ret, ptr, original_size);
virtual_free(ptr);
return ret;
}
}*/
void phpdbg_win_set_mm_heap(zend_mm_heap *heap) {
/*void phpdbg_win_set_mm_heap(zend_mm_heap *heap) {
phpdbg_btree_init(&phpdbg_memory_tree, sizeof(void *) * 8);
heap->_free = virtual_free;
heap->_realloc = virtual_realloc;
heap->_malloc = virtual_malloc;
}
void phpdbg_win_set_mm_storage(zend_mm_storage *storage) {
phpdbg_btree_init(&phpdbg_memory_tree, sizeof(void *) * 8);
storage->_free = virtual_free;
storage->_realloc = virtual_realloc;
storage->_malloc = virtual_malloc;
}*/
int phpdbg_exception_handler_win32(EXCEPTION_POINTERS *xp) {
EXCEPTION_RECORD *xr = xp->ExceptionRecord;
CONTEXT *xc = xp->ContextRecord;

2
test.php

@ -72,3 +72,5 @@ $test = $obj->a;
$obj->a += 2;
$test -= 2;
unset($obj);
Loading…
Cancel
Save