Skip to content

Commit 162bf9e

Browse files
committed
Reimplemented ability to get debug info (C source file and line number) in phpdbg without hacks and ABI breaks.
1 parent 7eb6bd1 commit 162bf9e

File tree

5 files changed

+109
-81
lines changed

5 files changed

+109
-81
lines changed

Zend/zend_alloc.c

Lines changed: 76 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,18 @@ struct _zend_mm_heap {
266266
int cached_chunks_count; /* number of cached chunks */
267267
double avg_chunks_count; /* average number of chunks allocated per request */
268268
#if ZEND_MM_CUSTOM
269-
void *(*_malloc)(size_t);
270-
void (*_free)(void*);
271-
void *(*_realloc)(void*, size_t);
269+
union {
270+
struct {
271+
void *(*_malloc)(size_t);
272+
void (*_free)(void*);
273+
void *(*_realloc)(void*, size_t);
274+
} std;
275+
struct {
276+
void *(*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
277+
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
278+
void *(*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
279+
} debug;
280+
} custom_heap;
272281
#endif
273282
};
274283

@@ -1810,7 +1819,7 @@ static zend_mm_heap *zend_mm_init(void)
18101819
heap->overflow = 0;
18111820
#endif
18121821
#if ZEND_MM_CUSTOM
1813-
heap->use_custom_heap = 0;
1822+
heap->use_custom_heap = ZEND_MM_CUSTOM_HEAP_NONE;
18141823
#endif
18151824
#if ZEND_MM_STORAGE
18161825
heap->storage = NULL;
@@ -2111,7 +2120,11 @@ void zend_mm_shutdown(zend_mm_heap *heap, int full, int silent)
21112120
#if ZEND_MM_CUSTOM
21122121
if (heap->use_custom_heap) {
21132122
if (full) {
2114-
heap->_free(heap);
2123+
if (ZEND_DEBUG && heap->use_custom_heap == ZEND_MM_CUSTOM_HEAP_DEBUG) {
2124+
heap->custom_heap.debug._free(heap ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC);
2125+
} else {
2126+
heap->custom_heap.std._free(heap);
2127+
}
21152128
}
21162129
return;
21172130
}
@@ -2258,12 +2271,20 @@ ZEND_API int is_zend_mm(void)
22582271
#if ZEND_MM_CUSTOM
22592272
# define ZEND_MM_CUSTOM_ALLOCATOR(size) do { \
22602273
if (UNEXPECTED(AG(mm_heap)->use_custom_heap)) { \
2261-
return AG(mm_heap)->_malloc(size); \
2274+
if (ZEND_DEBUG && AG(mm_heap)->use_custom_heap == ZEND_MM_CUSTOM_HEAP_DEBUG) { \
2275+
return AG(mm_heap)->custom_heap.debug._malloc(size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); \
2276+
} else { \
2277+
return AG(mm_heap)->custom_heap.std._malloc(size); \
2278+
} \
22622279
} \
22632280
} while (0)
22642281
# define ZEND_MM_CUSTOM_DEALLOCATOR(ptr) do { \
22652282
if (UNEXPECTED(AG(mm_heap)->use_custom_heap)) { \
2266-
AG(mm_heap)->_free(ptr); \
2283+
if (ZEND_DEBUG && AG(mm_heap)->use_custom_heap == ZEND_MM_CUSTOM_HEAP_DEBUG) { \
2284+
AG(mm_heap)->custom_heap.debug._free(ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC); \
2285+
} else { \
2286+
AG(mm_heap)->custom_heap.std._free(ptr); \
2287+
} \
22672288
return; \
22682289
} \
22692290
} while (0)
@@ -2353,7 +2374,11 @@ ZEND_API void* ZEND_FASTCALL _emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LI
23532374

23542375
#if ZEND_MM_CUSTOM
23552376
if (UNEXPECTED(AG(mm_heap)->use_custom_heap)) {
2356-
return AG(mm_heap)->_malloc(size);
2377+
if (ZEND_DEBUG && AG(mm_heap)->use_custom_heap == ZEND_MM_CUSTOM_HEAP_DEBUG) {
2378+
return AG(mm_heap)->custom_heap.debug._malloc(size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2379+
} else {
2380+
return AG(mm_heap)->custom_heap.std._malloc(size);
2381+
}
23572382
}
23582383
#endif
23592384
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
23642389

23652390
#if ZEND_MM_CUSTOM
23662391
if (UNEXPECTED(AG(mm_heap)->use_custom_heap)) {
2367-
AG(mm_heap)->_free(ptr);
2392+
if (ZEND_DEBUG && AG(mm_heap)->use_custom_heap == ZEND_MM_CUSTOM_HEAP_DEBUG) {
2393+
AG(mm_heap)->custom_heap.debug._free(ptr ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2394+
} else {
2395+
AG(mm_heap)->custom_heap.std._free(ptr);
2396+
}
23682397
return;
23692398
}
23702399
#endif
@@ -2375,7 +2404,11 @@ ZEND_API void* ZEND_FASTCALL _erealloc(void *ptr, size_t size ZEND_FILE_LINE_DC
23752404
{
23762405

23772406
if (UNEXPECTED(AG(mm_heap)->use_custom_heap)) {
2378-
return AG(mm_heap)->_realloc(ptr, size);
2407+
if (ZEND_DEBUG && AG(mm_heap)->use_custom_heap == ZEND_MM_CUSTOM_HEAP_DEBUG) {
2408+
return AG(mm_heap)->custom_heap.debug._realloc(ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2409+
} else {
2410+
return AG(mm_heap)->custom_heap.std._realloc(ptr, size);
2411+
}
23792412
}
23802413
return zend_mm_realloc_heap(AG(mm_heap), ptr, size, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
23812414
}
@@ -2384,7 +2417,11 @@ ZEND_API void* ZEND_FASTCALL _erealloc2(void *ptr, size_t size, size_t copy_size
23842417
{
23852418

23862419
if (UNEXPECTED(AG(mm_heap)->use_custom_heap)) {
2387-
return AG(mm_heap)->_realloc(ptr, size);
2420+
if (ZEND_DEBUG && AG(mm_heap)->use_custom_heap == ZEND_MM_CUSTOM_HEAP_DEBUG) {
2421+
return AG(mm_heap)->custom_heap.debug._realloc(ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
2422+
} else {
2423+
return AG(mm_heap)->custom_heap.std._realloc(ptr, size);
2424+
}
23882425
}
23892426
return zend_mm_realloc_heap(AG(mm_heap), ptr, size, copy_size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
23902427
}
@@ -2549,10 +2586,10 @@ static void alloc_globals_ctor(zend_alloc_globals *alloc_globals)
25492586
if (tmp && !zend_atoi(tmp, 0)) {
25502587
alloc_globals->mm_heap = malloc(sizeof(zend_mm_heap));
25512588
memset(alloc_globals->mm_heap, 0, sizeof(zend_mm_heap));
2552-
alloc_globals->mm_heap->use_custom_heap = 1;
2553-
alloc_globals->mm_heap->_malloc = malloc;
2554-
alloc_globals->mm_heap->_free = free;
2555-
alloc_globals->mm_heap->_realloc = realloc;
2589+
alloc_globals->mm_heap->use_custom_heap = ZEND_MM_CUSTOM_HEAP_STD;
2590+
alloc_globals->mm_heap->custom_heap.std._malloc = malloc;
2591+
alloc_globals->mm_heap->custom_heap.std._free = free;
2592+
alloc_globals->mm_heap->custom_heap.std._realloc = realloc;
25562593
return;
25572594
}
25582595
#endif
@@ -2614,10 +2651,10 @@ ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
26142651
#if ZEND_MM_CUSTOM
26152652
zend_mm_heap *_heap = (zend_mm_heap*)heap;
26162653

2617-
_heap->use_custom_heap = 1;
2618-
_heap->_malloc = _malloc;
2619-
_heap->_free = _free;
2620-
_heap->_realloc = _realloc;
2654+
_heap->use_custom_heap = ZEND_MM_CUSTOM_HEAP_STD;
2655+
_heap->custom_heap.std._malloc = _malloc;
2656+
_heap->custom_heap.std._free = _free;
2657+
_heap->custom_heap.std._realloc = _realloc;
26212658
#endif
26222659
}
26232660

@@ -2630,9 +2667,9 @@ ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
26302667
zend_mm_heap *_heap = (zend_mm_heap*)heap;
26312668

26322669
if (heap->use_custom_heap) {
2633-
*_malloc = _heap->_malloc;
2634-
*_free = _heap->_free;
2635-
*_realloc = _heap->_realloc;
2670+
*_malloc = _heap->custom_heap.std._malloc;
2671+
*_free = _heap->custom_heap.std._free;
2672+
*_realloc = _heap->custom_heap.std._realloc;
26362673
} else {
26372674
*_malloc = NULL;
26382675
*_free = NULL;
@@ -2645,6 +2682,23 @@ ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
26452682
#endif
26462683
}
26472684

2685+
#if ZEND_DEBUG
2686+
ZEND_API void zend_mm_set_custom_debug_handlers(zend_mm_heap *heap,
2687+
void* (*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
2688+
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
2689+
void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC))
2690+
{
2691+
#if ZEND_MM_CUSTOM
2692+
zend_mm_heap *_heap = (zend_mm_heap*)heap;
2693+
2694+
_heap->use_custom_heap = ZEND_MM_CUSTOM_HEAP_DEBUG;
2695+
_heap->custom_heap.debug._malloc = _malloc;
2696+
_heap->custom_heap.debug._free = _free;
2697+
_heap->custom_heap.debug._realloc = _realloc;
2698+
#endif
2699+
}
2700+
#endif
2701+
26482702
ZEND_API zend_mm_storage *zend_mm_get_storage(zend_mm_heap *heap)
26492703
{
26502704
#if ZEND_MM_STORAGE

Zend/zend_alloc.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,10 @@ ZEND_API zend_mm_heap *zend_mm_get_heap(void);
284284

285285
ZEND_API size_t zend_mm_gc(zend_mm_heap *heap);
286286

287+
#define ZEND_MM_CUSTOM_HEAP_NONE 0
288+
#define ZEND_MM_CUSTOM_HEAP_STD 1
289+
#define ZEND_MM_CUSTOM_HEAP_DEBUG 2
290+
287291
ZEND_API int zend_mm_is_custom_heap(zend_mm_heap *new_heap);
288292
ZEND_API void zend_mm_set_custom_handlers(zend_mm_heap *heap,
289293
void* (*_malloc)(size_t),
@@ -294,6 +298,13 @@ ZEND_API void zend_mm_get_custom_handlers(zend_mm_heap *heap,
294298
void (**_free)(void*),
295299
void* (**_realloc)(void*, size_t));
296300

301+
#if ZEND_DEBUG
302+
ZEND_API void zend_mm_set_custom_debug_handlers(zend_mm_heap *heap,
303+
void* (*_malloc)(size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
304+
void (*_free)(void* ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC),
305+
void* (*_realloc)(void*, size_t ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC));
306+
#endif
307+
297308
typedef struct _zend_mm_storage zend_mm_storage;
298309

299310
typedef void* (*zend_mm_chunk_alloc_t)(zend_mm_storage *storage, size_t size, size_t alignment);

Zend/zend_portability.h

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -221,16 +221,12 @@ char *alloca();
221221
# define ZEND_ATTRIBUTE_UNUSED_LABEL
222222
#endif
223223

224-
#if !ZEND_DEBUG
225-
# if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004 && defined(__i386__)
226-
# define ZEND_FASTCALL __attribute__((fastcall))
227-
# elif defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER == 1700
228-
# define ZEND_FASTCALL __fastcall
229-
# elif defined(_MSC_VER) && _MSC_VER >= 1800 && !defined(__clang__)
230-
# define ZEND_FASTCALL __vectorcall
231-
# else
232-
# define ZEND_FASTCALL
233-
# endif
224+
#if defined(__GNUC__) && ZEND_GCC_VERSION >= 3004 && defined(__i386__)
225+
# define ZEND_FASTCALL __attribute__((fastcall))
226+
#elif defined(_MSC_VER) && defined(_M_IX86) && _MSC_VER == 1700
227+
# define ZEND_FASTCALL __fastcall
228+
#elif defined(_MSC_VER) && _MSC_VER >= 1800 && !defined(__clang__)
229+
# define ZEND_FASTCALL __vectorcall
234230
#else
235231
# define ZEND_FASTCALL
236232
#endif

sapi/phpdbg/phpdbg.c

Lines changed: 13 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,63 +1225,26 @@ void phpdbg_signal_handler(int sig, siginfo_t *info, void *context) /* {{{ */
12251225
} /* }}} */
12261226
#endif
12271227

1228-
1229-
/* A bit dark magic in order to have meaningful allocator adresses [ppc(64) may return bogus addresses here] */
1230-
#if ZEND_DEBUG && (__has_builtin(__builtin_frame_address) || ZEND_GCC_VERSION >= 3004) && !defined(__ppc__) && !defined(__ppc64__)
1231-
/* with gcc %rbp/%ebp for __builtin_frame_address() and clang returns the frame return address being at %ebp/%rbp + sizeof(void*) */
1232-
# ifdef __clang__
1233-
# define FETCH_PARENT_START() \
1234-
parent -= ZEND_MM_ALIGNED_SIZE(sizeof(void *));
1235-
# else
1236-
# define FETCH_PARENT_START()
1237-
# endif
1238-
# define FETCH_PARENT_FILELINE(argsize) \
1239-
char *__zend_filename, *__zend_orig_filename; \
1240-
uint __zend_lineno, __zend_orig_lineno; \
1241-
void *parent = __builtin_frame_address(1U); \
1242-
FETCH_PARENT_START() \
1243-
parent -= (argsize); /* size of first arguments */ \
1244-
parent -= sizeof(char *); /* filename */ \
1245-
__zend_filename = *(char **) parent; \
1246-
parent = (void *) ((intptr_t) parent & ZEND_MM_ALIGNMENT_MASK); /* realign */ \
1247-
parent -= sizeof(uint); /* lineno */ \
1248-
__zend_lineno = *(uint *) parent; \
1249-
parent = (void *) ((intptr_t) parent & ZEND_MM_ALIGNMENT_MASK); /* realign */ \
1250-
parent -= sizeof(char *); /* orig_filename */ \
1251-
__zend_orig_filename = *(char **) parent; \
1252-
parent = (void *) ((intptr_t) parent & ZEND_MM_ALIGNMENT_MASK); /* realign */ \
1253-
parent -= sizeof(uint); /* orig_lineno */ \
1254-
__zend_orig_lineno = *(uint *) parent;
1255-
#elif ZEND_DEBUG
1256-
# define FETCH_PARENT_FILELINE(argsize) \
1257-
char *__zend_filename = __FILE__, *__zend_orig_filename = NULL; \
1258-
uint __zend_lineno = __LINE__, __zend_orig_lineno = 0;
1259-
#else
1260-
# define FETCH_PARENT_FILELINE(argsize)
1261-
#endif
1262-
1263-
void *phpdbg_malloc_wrapper(size_t size) /* {{{ */
1228+
void *phpdbg_malloc_wrapper(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) /* {{{ */
12641229
{
1265-
FETCH_PARENT_FILELINE(ZEND_MM_ALIGNED_SIZE(sizeof(size)));
12661230
return _zend_mm_alloc(zend_mm_get_heap(), size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
12671231
} /* }}} */
12681232

1269-
void phpdbg_free_wrapper(void *p) /* {{{ */
1233+
void phpdbg_free_wrapper(void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) /* {{{ */
12701234
{
12711235
zend_mm_heap *heap = zend_mm_get_heap();
12721236
if (UNEXPECTED(heap == p)) {
12731237
/* TODO: heap maybe allocated by mmap(zend_mm_init) or malloc(USE_ZEND_ALLOC=0)
12741238
* let's prevent it from segfault for now
12751239
*/
12761240
} else {
1277-
FETCH_PARENT_FILELINE(ZEND_MM_ALIGNED_SIZE(sizeof(p)));
1241+
phpdbg_watch_efree(p);
12781242
return _zend_mm_free(heap, p ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
12791243
}
12801244
} /* }}} */
12811245

1282-
void *phpdbg_realloc_wrapper(void *ptr, size_t size) /* {{{ */
1246+
void *phpdbg_realloc_wrapper(void *ptr, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) /* {{{ */
12831247
{
1284-
FETCH_PARENT_FILELINE(ZEND_MM_ALIGNED_SIZE(sizeof(ptr)) + ZEND_MM_ALIGNED_SIZE(sizeof(size)));
12851248
return _zend_mm_realloc(zend_mm_get_heap(), ptr, size ZEND_FILE_LINE_RELAY_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
12861249
} /* }}} */
12871250

@@ -1633,18 +1596,20 @@ int main(int argc, char **argv) /* {{{ */
16331596

16341597
use_mm_wrappers = !_malloc && !_realloc && !_free;
16351598

1636-
if (use_mm_wrappers) {
1637-
_malloc = phpdbg_malloc_wrapper;
1638-
_realloc = phpdbg_realloc_wrapper;
1639-
_free = phpdbg_free_wrapper;
1640-
}
1641-
16421599
phpdbg_init_list();
16431600

16441601
PHPDBG_G(original_free_function) = _free;
16451602
_free = phpdbg_watch_efree;
16461603

1647-
zend_mm_set_custom_handlers(mm_heap, _malloc, _free, _realloc);
1604+
if (use_mm_wrappers) {
1605+
#if ZEND_DEBUG
1606+
zend_mm_set_custom_debug_handlers(mm_heap, phpdbg_malloc_wrapper, phpdbg_free_wrapper, phpdbg_realloc_wrapper);
1607+
#else
1608+
zend_mm_set_custom_handlers(mm_heap, phpdbg_malloc_wrapper, phpdbg_free_wrapper, phpdbg_realloc_wrapper);
1609+
#endif
1610+
} else {
1611+
zend_mm_set_custom_handlers(mm_heap, _malloc, _free, _realloc);
1612+
}
16481613

16491614
phpdbg_setup_watchpoints();
16501615

sapi/phpdbg/phpdbg_watch.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1133,5 +1133,7 @@ void phpdbg_watch_efree(void *ptr) {
11331133
}
11341134
}
11351135

1136-
PHPDBG_G(original_free_function)(ptr);
1136+
if (PHPDBG_G(original_free_function)) {
1137+
PHPDBG_G(original_free_function)(ptr);
1138+
}
11371139
}

0 commit comments

Comments
 (0)