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:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user