From c896e6dfbc4240a4d042dd43a8f66c5127f94707 Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Sat, 26 Mar 2016 09:28:34 +0000 Subject: Memento: Cope with wrapped blocks. If another routine 'wraps' memento blocks (such as a chunk allocator or the 'trace' allocator in mudraw), then the address passed to Memento_label, Memento_takeRef etc, can be inside the block rather than at the start of the block. Update Memento to cope with this. --- source/fitz/memento.c | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) (limited to 'source/fitz/memento.c') diff --git a/source/fitz/memento.c b/source/fitz/memento.c index b29e07a1..36693366 100644 --- a/source/fitz/memento.c +++ b/source/fitz/memento.c @@ -676,6 +676,9 @@ static void Memento_storeDetails(Memento_BlkHeader *head, int type) int count; int skip; + if (head == NULL) + return; + #ifdef MEMENTO_STACKTRACE_METHOD count = Memento_getStacktrace(stack, &skip); #else @@ -1560,16 +1563,47 @@ int Memento_breakAt(int event) return event; } +static void *safe_find_block(void *ptr) +{ + Memento_BlkHeader *block; + int valid; + + block = MEMBLK_FROMBLK(ptr); + /* Sometimes wrapping allocators can mean Memento_label + * is called with a value within the block, rather than + * at the start of the block. If we detect this, find it + * the slow way. */ + VALGRIND_MAKE_MEM_DEFINED(&block->child, sizeof(block->child)); + VALGRIND_MAKE_MEM_DEFINED(&block->sibling, sizeof(block->sibling)); + valid = (block->child == MEMENTO_CHILD_MAGIC && + block->sibling == MEMENTO_SIBLING_MAGIC); + VALGRIND_MAKE_MEM_NOACCESS(&block->child, sizeof(block->child)); + VALGRIND_MAKE_MEM_NOACCESS(&block->sibling, sizeof(block->sibling)); + if (!valid); + { + findBlkData data; + + data.addr = ptr; + data.blk = NULL; + data.flags = 0; + Memento_appBlocks(&memento.used, Memento_containsAddr, &data); + if (data.blk == NULL) + return ptr; + block = data.blk; + } + return block; +} + void *Memento_label(void *ptr, const char *label) { Memento_BlkHeader *block; if (ptr == NULL) return NULL; - block = MEMBLK_FROMBLK(ptr); + block = safe_find_block(ptr); VALGRIND_MAKE_MEM_DEFINED(&block->label, sizeof(block->label)); block->label = label; - VALGRIND_MAKE_MEM_UNDEFINED(&block->label, sizeof(block->label)); + VALGRIND_MAKE_MEM_NOACCESS(&block->label, sizeof(block->label)); return ptr; } @@ -1675,21 +1709,21 @@ static void do_reference(Memento_BlkHeader *blk, int event) void *Memento_takeRef(void *blk) { if (blk) - do_reference(MEMBLK_FROMBLK(blk), Memento_EventType_takeRef); + do_reference(safe_find_block(blk), Memento_EventType_takeRef); return blk; } void *Memento_dropRef(void *blk) { if (blk) - do_reference(MEMBLK_FROMBLK(blk), Memento_EventType_dropRef); + do_reference(safe_find_block(blk), Memento_EventType_dropRef); return blk; } void *Memento_reference(void *blk) { if (blk) - do_reference(MEMBLK_FROMBLK(blk), Memento_EventType_reference); + do_reference(safe_find_block(blk), Memento_EventType_reference); return blk; } -- cgit v1.2.3