util: add debug_memory_check_block(), debug_memory_tag()
authorBrian Paul <brianp@vmware.com>
Wed, 3 Apr 2013 19:36:50 +0000 (13:36 -0600)
committerBrian Paul <brianp@vmware.com>
Thu, 4 Apr 2013 14:50:15 +0000 (08:50 -0600)
The former just checks that the given block is valid by checking
the header and footer.

The later sets the memory block's tag.  With extra debug code, we
can use that for monitoring/checking particular allocations.

Reviewed-by: José Fonseca <jfonseca@vmware.com>
src/gallium/auxiliary/os/os_memory_debug.h
src/gallium/auxiliary/util/u_debug_memory.c

index 36b8fc63a6e1c95e1c875412c3b3ca131191841a..9a487dec05c8e181f2d826f5527f66b259bb98da 100644 (file)
@@ -60,6 +60,12 @@ void *
 debug_realloc(const char *file, unsigned line, const char *function,
               void *old_ptr, size_t old_size, size_t new_size );
 
+void
+debug_memory_tag(void *ptr, unsigned tag);
+
+void
+debug_memory_check_block(void *ptr);
+
 void 
 debug_memory_check(void);
 
index 4bf26a5241499d1de5242199883015c38bf24984..4723547819ed825609b96205a4f084a939431573 100644 (file)
@@ -76,6 +76,7 @@ struct debug_memory_header
 #endif
 
    unsigned magic;
+   unsigned tag;
 };
 
 struct debug_memory_footer
@@ -140,6 +141,7 @@ debug_malloc(const char *file, unsigned line, const char *function,
    hdr->function = function;
    hdr->size = size;
    hdr->magic = DEBUG_MEMORY_MAGIC;
+   hdr->tag = 0;
 #if DEBUG_FREED_MEMORY
    hdr->freed = FALSE;
 #endif
@@ -263,6 +265,7 @@ debug_realloc(const char *file, unsigned line, const char *function,
    new_hdr->function = old_hdr->function;
    new_hdr->size = new_size;
    new_hdr->magic = DEBUG_MEMORY_MAGIC;
+   new_hdr->tag = 0;
 #if DEBUG_FREED_MEMORY
    new_hdr->freed = FALSE;
 #endif
@@ -347,6 +350,58 @@ debug_memory_end(unsigned long start_no)
 }
 
 
+/**
+ * Put a tag (arbitrary integer) on a memory block.
+ * Can be useful for debugging.
+ */
+void
+debug_memory_tag(void *ptr, unsigned tag)
+{
+   struct debug_memory_header *hdr;
+   
+   if (!ptr)
+      return;
+   
+   hdr = header_from_data(ptr);
+   if (hdr->magic != DEBUG_MEMORY_MAGIC) {
+      debug_printf("%s corrupted memory at %p\n", __FUNCTION__, ptr);
+      debug_assert(0);
+   }
+
+   hdr->tag = tag;
+}
+
+
+/**
+ * Check the given block of memory for validity/corruption.
+ */
+void
+debug_memory_check_block(void *ptr)
+{
+   struct debug_memory_header *hdr;
+   struct debug_memory_footer *ftr;
+   
+   if (!ptr)
+      return;
+   
+   hdr = header_from_data(ptr);
+   ftr = footer_from_header(hdr);
+
+   if (hdr->magic != DEBUG_MEMORY_MAGIC) {
+      debug_printf("%s:%u:%s: bad or corrupted memory %p\n",
+                   hdr->file, hdr->line, hdr->function, ptr);
+      debug_assert(0);
+   }
+
+   if (ftr->magic != DEBUG_MEMORY_MAGIC) {
+      debug_printf("%s:%u:%s: buffer overflow %p\n",
+                   hdr->file, hdr->line, hdr->function, ptr);
+      debug_assert(0);
+   }
+}
+
+
+
 /**
  * We can periodically call this from elsewhere to do a basic sanity
  * check of the heap memory we've allocated.