summaryrefslogtreecommitdiff
path: root/source/fitz/memento.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2016-03-26 09:28:34 +0000
committerRobin Watts <robin.watts@artifex.com>2016-03-26 09:31:34 +0000
commitc896e6dfbc4240a4d042dd43a8f66c5127f94707 (patch)
tree8304c7669c8cf9912ab016743fa70d0ce8390df4 /source/fitz/memento.c
parenta1ca4f85637a5b35ad7a7da751077e447cba3ab2 (diff)
downloadmupdf-c896e6dfbc4240a4d042dd43a8f66c5127f94707.tar.xz
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.
Diffstat (limited to 'source/fitz/memento.c')
-rw-r--r--source/fitz/memento.c44
1 files changed, 39 insertions, 5 deletions
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;
}