1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Reimplemented ability to get debug info (C source file and line number) in phpdbg without hacks and ABI breaks.

This commit is contained in:
Dmitry Stogov
2015-08-11 16:33:47 +03:00
parent 7eb6bd1311
commit 162bf9e802
5 changed files with 109 additions and 81 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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

View File

@@ -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();

View File

@@ -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);
}
}