diff options
author | Dmitry Stogov <dmitry@zend.com> | 2015-08-11 16:33:47 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2015-08-11 16:33:47 +0300 |
commit | 162bf9e802b3d5aec43b6cdcb6ea87169923076a (patch) | |
tree | 4a0a35e35a3047423cb332f0b6c86f4e26b0ef8e | |
parent | 7eb6bd1311a815ec23eb7cf06f6214f4a2d5895a (diff) | |
download | php-git-162bf9e802b3d5aec43b6cdcb6ea87169923076a.tar.gz |
Reimplemented ability to get debug info (C source file and line number) in phpdbg without hacks and ABI breaks.
-rw-r--r-- | Zend/zend_alloc.c | 98 | ||||
-rw-r--r-- | Zend/zend_alloc.h | 11 | ||||
-rw-r--r-- | Zend/zend_portability.h | 16 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg.c | 61 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_watch.c | 4 |
5 files changed, 109 insertions, 81 deletions
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 32ee381c12..52b1ac5868 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -266,9 +266,18 @@ struct _zend_mm_heap { int cached_chunks_count; /* number of cached chunks */ double avg_chunks_count; /* average number of chunks allocated per request */ #if ZEND_MM_CUSTOM - void *(*_malloc)(size_t); - void (*_free)(void*); - void *(*_realloc)(void*, size_t); + union { + struct { + void *(*_malloc)(size_t); + void (*_free)(void*); + void *(*_realloc)(void*, size_t); + } std; + struct { + void *(*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC); + void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC); + void *(*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC); + } debug; + } custom_heap; #endif }; @@ -1810,7 +1819,7 @@ static zend_mm_heap *zend_mm_init(void) heap->overflow = 0; #endif #if ZEND_MM_CUSTOM - heap->use_custom_heap = 0; + heap->use_custom_heap = ZEND_MM_CUSTOM_HEAP_NONE; #endif #if ZEND_MM_STORAGE heap->storage = NULL; @@ -2111,7 +2120,11 @@ void zend_mm_shutdown(zend_mm_heap *heap, int full, int silent) #if ZEND_MM_CUSTOM if (heap->use_custom_heap) { if (full) { - heap->_free(heap); + if (ZEND_DEBUG && heap->use_custom_heap == ZEND_MM_CUSTOM_HEAP_DEBUG) { + heap->custom_heap.debug._free(heap ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC); + } else { + heap->custom_heap.std._free(heap); + } } return; } @@ -2258,12 +2271,20 @@ ZEND_API int is_zend_mm(void) #if ZEND_MM_CUSTOM # define ZEND_MM_CUSTOM_ALLOCATOR(size) do { \ if (UNEXPECTED(AG(mm_heap)->use_custom_heap)) { \ - return AG(mm_heap)->_malloc(size); \ + if (ZEND_DEBUG && AG(mm_heap)->use_custom_heap == ZEND_MM_CUSTOM_HEAP_DEBUG) { \ + return AG(mm_heap)->custom_heap.debug._malloc(size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); \ + } else { \ + return AG(mm_heap)->custom_heap.std._malloc(size); \ + } \ } \ } while (0) # define ZEND_MM_CUSTOM_DEALLOCATOR(ptr) do { \ if (UNEXPECTED(AG(mm_heap)->use_custom_heap)) { \ - AG(mm_heap)->_free(ptr); \ + if (ZEND_DEBUG && AG(mm_heap)->use_custom_heap == ZEND_MM_CUSTOM_HEAP_DEBUG) { \ + AG(mm_heap)->custom_heap.debug._free(ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); \ + } else { \ + AG(mm_heap)->custom_heap.std._free(ptr); \ + } \ return; \ } \ } while (0) @@ -2353,7 +2374,11 @@ ZEND_API void* ZEND_FASTCALL _emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LI #if ZEND_MM_CUSTOM if (UNEXPECTED(AG(mm_heap)->use_custom_heap)) { - return AG(mm_heap)->_malloc(size); + if (ZEND_DEBUG && AG(mm_heap)->use_custom_heap == ZEND_MM_CUSTOM_HEAP_DEBUG) { + return AG(mm_heap)->custom_heap.debug._malloc(size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + } else { + return AG(mm_heap)->custom_heap.std._malloc(size); + } } #endif return zend_mm_alloc_heap(AG(mm_heap), size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); @@ -2364,7 +2389,11 @@ ZEND_API void ZEND_FASTCALL _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_OR #if ZEND_MM_CUSTOM if (UNEXPECTED(AG(mm_heap)->use_custom_heap)) { - AG(mm_heap)->_free(ptr); + if (ZEND_DEBUG && AG(mm_heap)->use_custom_heap == ZEND_MM_CUSTOM_HEAP_DEBUG) { + AG(mm_heap)->custom_heap.debug._free(ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + } else { + AG(mm_heap)->custom_heap.std._free(ptr); + } return; } #endif @@ -2375,7 +2404,11 @@ ZEND_API void* ZEND_FASTCALL _erealloc(void *ptr, size_t size ZEND_FILE_LINE_DC { if (UNEXPECTED(AG(mm_heap)->use_custom_heap)) { - return AG(mm_heap)->_realloc(ptr, size); + if (ZEND_DEBUG && AG(mm_heap)->use_custom_heap == ZEND_MM_CUSTOM_HEAP_DEBUG) { + return AG(mm_heap)->custom_heap.debug._realloc(ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + } else { + return AG(mm_heap)->custom_heap.std._realloc(ptr, size); + } } return zend_mm_realloc_heap(AG(mm_heap), ptr, size, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); } @@ -2384,7 +2417,11 @@ ZEND_API void* ZEND_FASTCALL _erealloc2(void *ptr, size_t size, size_t copy_size { if (UNEXPECTED(AG(mm_heap)->use_custom_heap)) { - return AG(mm_heap)->_realloc(ptr, size); + if (ZEND_DEBUG && AG(mm_heap)->use_custom_heap == ZEND_MM_CUSTOM_HEAP_DEBUG) { + return AG(mm_heap)->custom_heap.debug._realloc(ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); + } else { + return AG(mm_heap)->custom_heap.std._realloc(ptr, size); + } } return zend_mm_realloc_heap(AG(mm_heap), ptr, size, copy_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); } @@ -2549,10 +2586,10 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals) if (tmp && !zend_atoi(tmp, 0)) { alloc_globals->mm_heap = malloc(sizeof(zend_mm_heap)); memset(alloc_globals->mm_heap, 0, sizeof(zend_mm_heap)); - alloc_globals->mm_heap->use_custom_heap = 1; - alloc_globals->mm_heap->_malloc = malloc; - alloc_globals->mm_heap->_free = free; - alloc_globals->mm_heap->_realloc = realloc; + alloc_globals->mm_heap->use_custom_heap = ZEND_MM_CUSTOM_HEAP_STD; + alloc_globals->mm_heap->custom_heap.std._malloc = malloc; + alloc_globals->mm_heap->custom_heap.std._free = free; + alloc_globals->mm_heap->custom_heap.std._realloc = realloc; return; } #endif @@ -2614,10 +2651,10 @@ ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap, #if ZEND_MM_CUSTOM zend_mm_heap *_heap = (zend_mm_heap*)heap; - _heap->use_custom_heap = 1; - _heap->_malloc = _malloc; - _heap->_free = _free; - _heap->_realloc = _realloc; + _heap->use_custom_heap = ZEND_MM_CUSTOM_HEAP_STD; + _heap->custom_heap.std._malloc = _malloc; + _heap->custom_heap.std._free = _free; + _heap->custom_heap.std._realloc = _realloc; #endif } @@ -2630,9 +2667,9 @@ ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap, zend_mm_heap *_heap = (zend_mm_heap*)heap; if (heap->use_custom_heap) { - *_malloc = _heap->_malloc; - *_free = _heap->_free; - *_realloc = _heap->_realloc; + *_malloc = _heap->custom_heap.std._malloc; + *_free = _heap->custom_heap.std._free; + *_realloc = _heap->custom_heap.std._realloc; } else { *_malloc = NULL; *_free = NULL; @@ -2645,6 +2682,23 @@ ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap, #endif } +#if ZEND_DEBUG +ZEND_API void zend_mm_set_custom_debug_handlers(zend_mm_heap *heap, + void* (*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC), + void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC), + void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)) +{ +#if ZEND_MM_CUSTOM + zend_mm_heap *_heap = (zend_mm_heap*)heap; + + _heap->use_custom_heap = ZEND_MM_CUSTOM_HEAP_DEBUG; + _heap->custom_heap.debug._malloc = _malloc; + _heap->custom_heap.debug._free = _free; + _heap->custom_heap.debug._realloc = _realloc; +#endif +} +#endif + ZEND_API zend_mm_storage *zend_mm_get_storage(zend_mm_heap *heap) { #if ZEND_MM_STORAGE diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h index 519a59d254..ae7e75345e 100644 --- a/Zend/zend_alloc.h +++ b/Zend/zend_alloc.h @@ -284,6 +284,10 @@ ZEND_API zend_mm_heap *zend_mm_get_heap(void); ZEND_API size_t zend_mm_gc(zend_mm_heap *heap); +#define ZEND_MM_CUSTOM_HEAP_NONE 0 +#define ZEND_MM_CUSTOM_HEAP_STD 1 +#define ZEND_MM_CUSTOM_HEAP_DEBUG 2 + ZEND_API int zend_mm_is_custom_heap(zend_mm_heap *new_heap); ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap, void* (*_malloc)(size_t), @@ -294,6 +298,13 @@ ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap, void (**_free)(void*), void* (**_realloc)(void*, size_t)); +#if ZEND_DEBUG +ZEND_API void zend_mm_set_custom_debug_handlers(zend_mm_heap *heap, + void* (*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC), + void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC), + void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)); +#endif + typedef struct _zend_mm_storage zend_mm_storage; typedef void* (*zend_mm_chunk_alloc_t)(zend_mm_storage *storage, size_t size, size_t alignment); diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index 99069e57e1..55523501c7 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -221,16 +221,12 @@ char *alloca(); # define ZEND_ATTRIBUTE_UNUSED_LABEL #endif -#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 +#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 diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c index 3d7f847d23..831d4fc472 100644 --- a/sapi/phpdbg/phpdbg.c +++ b/sapi/phpdbg/phpdbg.c @@ -1225,48 +1225,12 @@ void phpdbg_signal_handler(int sig, siginfo_t *info, void *context) /* {{{ */ } /* }}} */ #endif - -/* A bit dark magic in order to have meaningful allocator adresses [ppc(64) may return bogus addresses here] */ -#if ZEND_DEBUG && (__has_builtin(__builtin_frame_address) || ZEND_GCC_VERSION >= 3004) && !defined(__ppc__) && !defined(__ppc64__) -/* with gcc %rbp/%ebp for __builtin_frame_address() and clang returns the frame return address being at %ebp/%rbp + sizeof(void*) */ -# ifdef __clang__ -# define FETCH_PARENT_START() \ - parent -= ZEND_MM_ALIGNED_SIZE(sizeof(void *)); -# else -# define FETCH_PARENT_START() -# endif -# define FETCH_PARENT_FILELINE(argsize) \ - char *__zend_filename, *__zend_orig_filename; \ - uint __zend_lineno, __zend_orig_lineno; \ - void *parent = __builtin_frame_address(1U); \ - FETCH_PARENT_START() \ - 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(argsize) \ - char *__zend_filename = __FILE__, *__zend_orig_filename = NULL; \ - uint __zend_lineno = __LINE__, __zend_orig_lineno = 0; -#else -# define FETCH_PARENT_FILELINE(argsize) -#endif - -void *phpdbg_malloc_wrapper(size_t size) /* {{{ */ +void *phpdbg_malloc_wrapper(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) /* {{{ */ { - 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) /* {{{ */ +void phpdbg_free_wrapper(void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) /* {{{ */ { zend_mm_heap *heap = zend_mm_get_heap(); if (UNEXPECTED(heap == p)) { @@ -1274,14 +1238,13 @@ void phpdbg_free_wrapper(void *p) /* {{{ */ * let's prevent it from segfault for now */ } else { - FETCH_PARENT_FILELINE(ZEND_MM_ALIGNED_SIZE(sizeof(p))); + phpdbg_watch_efree(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) /* {{{ */ +void *phpdbg_realloc_wrapper(void *ptr, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) /* {{{ */ { - 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); } /* }}} */ @@ -1633,18 +1596,20 @@ phpdbg_main: use_mm_wrappers = !_malloc && !_realloc && !_free; - if (use_mm_wrappers) { - _malloc = phpdbg_malloc_wrapper; - _realloc = phpdbg_realloc_wrapper; - _free = phpdbg_free_wrapper; - } - phpdbg_init_list(); PHPDBG_G(original_free_function) = _free; _free = phpdbg_watch_efree; - zend_mm_set_custom_handlers(mm_heap, _malloc, _free, _realloc); + if (use_mm_wrappers) { +#if ZEND_DEBUG + zend_mm_set_custom_debug_handlers(mm_heap, phpdbg_malloc_wrapper, phpdbg_free_wrapper, phpdbg_realloc_wrapper); +#else + zend_mm_set_custom_handlers(mm_heap, phpdbg_malloc_wrapper, phpdbg_free_wrapper, phpdbg_realloc_wrapper); +#endif + } else { + zend_mm_set_custom_handlers(mm_heap, _malloc, _free, _realloc); + } phpdbg_setup_watchpoints(); diff --git a/sapi/phpdbg/phpdbg_watch.c b/sapi/phpdbg/phpdbg_watch.c index 15ae97da3a..c3fcb769a4 100644 --- a/sapi/phpdbg/phpdbg_watch.c +++ b/sapi/phpdbg/phpdbg_watch.c @@ -1133,5 +1133,7 @@ void phpdbg_watch_efree(void *ptr) { } } - PHPDBG_G(original_free_function)(ptr); + if (PHPDBG_G(original_free_function)) { + PHPDBG_G(original_free_function)(ptr); + } } |