summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2015-08-11 16:33:47 +0300
committerDmitry Stogov <dmitry@zend.com>2015-08-11 16:33:47 +0300
commit162bf9e802b3d5aec43b6cdcb6ea87169923076a (patch)
tree4a0a35e35a3047423cb332f0b6c86f4e26b0ef8e
parent7eb6bd1311a815ec23eb7cf06f6214f4a2d5895a (diff)
downloadphp-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.c98
-rw-r--r--Zend/zend_alloc.h11
-rw-r--r--Zend/zend_portability.h16
-rw-r--r--sapi/phpdbg/phpdbg.c61
-rw-r--r--sapi/phpdbg/phpdbg_watch.c4
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);
+ }
}