mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 23:27:04 +02:00
DEBUG: pools: report the data around the offending area in case of mismatch
When the integrity check fails, it's useful to get a dump of the area around the first faulty byte. That's what this patch does. For example it now shows this before reporting info about the tag itself: Contents around first corrupted address relative to pool item:. Contents around address 0xe4febc0792c0+40=0xe4febc0792e8: 0xe4febc0792c8 [80 75 56 d8 fe e4 00 00] [.uV.....] 0xe4febc0792d0 [a0 f7 23 a4 fe e4 00 00] [..#.....] 0xe4febc0792d8 [90 75 56 d8 fe e4 00 00] [.uV.....] 0xe4febc0792e0 [d9 93 fb ff fd ff ff ff] [........] 0xe4febc0792e8 [d9 93 fb ff ff ff ff ff] [........] 0xe4febc0792f0 [d9 93 fb ff ff ff ff ff] [........] 0xe4febc0792f8 [d9 93 fb ff ff ff ff ff] [........] 0xe4febc079300 [d9 93 fb ff ff ff ff ff] [........] This may be backported to 2.9 and maybe even 2.8 as it does help spot the cause of the memory corruption.
This commit is contained in:
parent
16e3655fbd
commit
c0ee2d78d7
@ -77,7 +77,7 @@
|
|||||||
if (likely(!(pool_debugging & POOL_DBG_TAG))) \
|
if (likely(!(pool_debugging & POOL_DBG_TAG))) \
|
||||||
break; \
|
break; \
|
||||||
if (*(typeof(pool)*)(((char *)__i) + __p->size) != __p) { \
|
if (*(typeof(pool)*)(((char *)__i) + __p->size) != __p) { \
|
||||||
pool_inspect_item("tag mismatch on free()", pool, item, caller); \
|
pool_inspect_item("tag mismatch on free()", __p, __i, caller, -1); \
|
||||||
ABORT_NOW(); \
|
ABORT_NOW(); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
@ -126,7 +126,7 @@ void *pool_destroy(struct pool_head *pool);
|
|||||||
void pool_destroy_all(void);
|
void pool_destroy_all(void);
|
||||||
void *__pool_alloc(struct pool_head *pool, unsigned int flags);
|
void *__pool_alloc(struct pool_head *pool, unsigned int flags);
|
||||||
void __pool_free(struct pool_head *pool, void *ptr);
|
void __pool_free(struct pool_head *pool, void *ptr);
|
||||||
void pool_inspect_item(const char *msg, struct pool_head *pool, const void *item, const void *caller);
|
void pool_inspect_item(const char *msg, struct pool_head *pool, const void *item, const void *caller, ssize_t ofs);
|
||||||
|
|
||||||
|
|
||||||
/****************** Thread-local cache management ******************/
|
/****************** Thread-local cache management ******************/
|
||||||
|
15
src/pool.c
15
src/pool.c
@ -496,7 +496,7 @@ void pool_check_pattern(struct pool_cache_head *pch, struct pool_head *pool, str
|
|||||||
u = ptr[ofs++];
|
u = ptr[ofs++];
|
||||||
while (ofs < size / sizeof(*ptr)) {
|
while (ofs < size / sizeof(*ptr)) {
|
||||||
if (unlikely(ptr[ofs] != u)) {
|
if (unlikely(ptr[ofs] != u)) {
|
||||||
pool_inspect_item("cache corruption detected", pool, item, caller);
|
pool_inspect_item("cache corruption detected", pool, item, caller, ofs * sizeof(*ptr));
|
||||||
ABORT_NOW();
|
ABORT_NOW();
|
||||||
}
|
}
|
||||||
ofs++;
|
ofs++;
|
||||||
@ -961,8 +961,12 @@ void pool_destroy_all()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* carefully inspects an item upon fatal error and emit diagnostics */
|
/* carefully inspects an item upon fatal error and emit diagnostics.
|
||||||
void pool_inspect_item(const char *msg, struct pool_head *pool, const void *item, const void *caller)
|
* If ofs < 0, no hint is provided regarding the content location. However if
|
||||||
|
* ofs >= 0, then we also try to inspect around that place where corruption
|
||||||
|
* was detected.
|
||||||
|
*/
|
||||||
|
void pool_inspect_item(const char *msg, struct pool_head *pool, const void *item, const void *caller, ssize_t ofs)
|
||||||
{
|
{
|
||||||
const struct pool_head *the_pool = NULL;
|
const struct pool_head *the_pool = NULL;
|
||||||
|
|
||||||
@ -979,6 +983,11 @@ void pool_inspect_item(const char *msg, struct pool_head *pool, const void *item
|
|||||||
" pool: %p ('%s', size %u, real %u, users %u)\n",
|
" pool: %p ('%s', size %u, real %u, users %u)\n",
|
||||||
item, pool, pool->name, pool->size, pool->alloc_sz, pool->users);
|
item, pool, pool->name, pool->size, pool->alloc_sz, pool->users);
|
||||||
|
|
||||||
|
if (ofs >= 0) {
|
||||||
|
chunk_printf(&trash, "Contents around first corrupted address relative to pool item:.\n");
|
||||||
|
dump_area_with_syms(&trash, item, item + ofs, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (pool_debugging & POOL_DBG_TAG) {
|
if (pool_debugging & POOL_DBG_TAG) {
|
||||||
const void **pool_mark;
|
const void **pool_mark;
|
||||||
struct pool_head *ph;
|
struct pool_head *ph;
|
||||||
|
Loading…
Reference in New Issue
Block a user