]> granicus.if.org Git - php/commitdiff
Reimplemented ability to get debug info (C source file and line number) in phpdbg...
authorDmitry Stogov <dmitry@zend.com>
Tue, 11 Aug 2015 13:33:47 +0000 (16:33 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 11 Aug 2015 13:33:47 +0000 (16:33 +0300)
Zend/zend_alloc.c
Zend/zend_alloc.h
Zend/zend_portability.h
sapi/phpdbg/phpdbg.c
sapi/phpdbg/phpdbg_watch.c

index 32ee381c12147d241fba06fa2bcc16c8dfc6e504..52b1ac5868e6eab42494579b5f152cab7106eb2b 100644 (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
index 519a59d2549b910eae93b76bcc01cd778f724906..ae7e75345e3203a67ee927ef624495ba0c4fbbd3 100644 (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);
index 99069e57e1228aec3de9afd63ee0f8bbc1a1d23a..55523501c749711a0907491c69aaf65f619286b2 100644 (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
index 3d7f847d23297bca591473413c5f22f3e341d1a9..831d4fc4721967243c9d22e00c19ff6442367fda 100644 (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();
 
index 15ae97da3a91747f0623d75354955ab640dbb579..c3fcb769a47388db0d901724a40c7778ea4473e0 100644 (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);
+       }
 }