[mpich2-commits] r5509 - mpich2/trunk/src/util/mem
goodell at mcs.anl.gov
goodell at mcs.anl.gov
Tue Oct 20 15:35:45 CDT 2009
Author: goodell
Date: 2009-10-20 15:35:45 -0500 (Tue, 20 Oct 2009)
New Revision: 5509
Modified:
mpich2/trunk/src/util/mem/handlemem.c
Log:
Better valgrind integration: object labeling and mempools.
Valgrind errors reported inside of handle objects now also contain
information about which handle (pointer, handle val, and type) the
memory belongs to. This should help when tracking down valgrind
errors/warnings in the future.
The memory pool integration should help catch various additional memory
errors such as frees of unallocated memory. It might also help with
some of the non-memcheck tools, such as DRD and Helgrind.
No reviewer.
Modified: mpich2/trunk/src/util/mem/handlemem.c
===================================================================
--- mpich2/trunk/src/util/mem/handlemem.c 2009-10-20 20:35:44 UTC (rev 5508)
+++ mpich2/trunk/src/util/mem/handlemem.c 2009-10-20 20:35:45 UTC (rev 5509)
@@ -129,6 +129,25 @@
return 0;
}
+#if defined(MPIU_VG_AVAILABLE)
+#define MPIU_HANDLE_VG_LABEL(objptr_, objsize_, handle_type_, is_direct_) \
+ do { \
+ if (MPIU_VG_RUNNING_ON_VALGRIND()) { \
+ char desc_str[256]; \
+ MPIU_Snprintf(desc_str, sizeof(desc_str)-1, \
+ "[MPICH2 handle: objptr=%p handle=0x%x %s/%s]", \
+ (objptr_), (objptr_)->handle, \
+ ((is_direct_) ? "DIRECT" : "INDIRECT"), \
+ MPIU_Handle_get_kind_str(handle_type_)); \
+ /* we don't keep track of the block descriptor because the handle */ \
+ /* values never change once allocated */ \
+ MPIU_VG_CREATE_BLOCK((objptr_), (objsize_), desc_str); \
+ } \
+ } while (0)
+#else
+#define MPIU_HANDLE_VG_LABEL(objptr_, objsize_, handle_type_, is_direct_) do{}while(0)
+#endif
+
void *MPIU_Handle_direct_init(void *direct,
int direct_size,
int obj_size,
@@ -137,7 +156,7 @@
int i;
MPIU_Handle_common *hptr=0;
char *ptr = (char *)direct;
-
+
for (i=0; i<direct_size; i++) {
/* printf( "Adding %p in %d\n", ptr, handle_type ); */
hptr = (MPIU_Handle_common *)ptr;
@@ -145,6 +164,8 @@
hptr->next = ptr;
hptr->handle = ((unsigned)HANDLE_KIND_DIRECT << HANDLE_KIND_SHIFT) |
(handle_type << HANDLE_MPI_KIND_SHIFT) | i;
+
+ MPIU_HANDLE_VG_LABEL(hptr, obj_size, handle_type, 1);
}
if (hptr)
@@ -194,6 +215,8 @@
hptr->handle = ((unsigned)HANDLE_KIND_INDIRECT << HANDLE_KIND_SHIFT) |
(handle_type << HANDLE_MPI_KIND_SHIFT) |
(*indirect_size << HANDLE_INDIRECT_SHIFT) | i;
+
+ MPIU_HANDLE_VG_LABEL(hptr, obj_size, handle_type, 0);
}
hptr->next = 0;
/* We're here because avail is null, so there is no need to set
@@ -218,6 +241,10 @@
(void)MPIU_Handle_free( objmem->indirect, objmem->indirect_size );
/* This does *not* remove any Info objects that the user created
and then did not destroy */
+
+ /* at this point we are done with the memory pool, inform valgrind */
+ MPIU_VG_DESTROY_MEMPOOL(objmem_ptr);
+
return 0;
}
@@ -308,6 +335,8 @@
if (!objmem->initialized) {
performed_initialize = 1;
+ MPIU_VG_CREATE_MEMPOOL(objmem, 0/*rzB*/, 0/*is_zeroed*/);
+
/* Setup the first block. This is done here so that short MPI
jobs do not need to include any of the Info code if no
Info-using routines are used */
@@ -346,21 +375,26 @@
MPIU_Handle_obj_alloc_complete(objmem, performed_initialize);
}
- MPIU_DBG_MSG_FMT(HANDLE,TYPICAL,(MPIU_DBG_FDEST,
- "Allocating object ptr %p (handle val 0x%08x)",
- ptr, ptr->handle));
-
if (ptr) {
#ifdef USE_MEMORY_TRACING
/* We set the object to an invalid pattern. This is similar to
what is done by MPIU_trmalloc by default (except that trmalloc uses
0xda as the byte in the memset)
*/
- MPIU_VG_MAKE_MEM_DEFINED(&ptr->ref_count, objmem->size - sizeof(int));
- memset( (void*)&ptr->ref_count, 0xef, objmem->size-sizeof(int));
+ /* if the object was previously freed then MEMPOOL_FREE marked it as
+ * NOACCESS, so we need to make it addressable again before memsetting
+ * it */
+ MPIU_VG_MAKE_MEM_DEFINED(&ptr->ref_count, objmem->size - sizeof(ptr->handle));
+ memset( (void*)&ptr->ref_count, 0xef, objmem->size-sizeof(ptr->handle));
#endif /* USE_MEMORY_TRACING */
/* mark the mem as addressable yet undefined if valgrind is available */
- MPIU_VG_MAKE_MEM_UNDEFINED(&ptr->ref_count, objmem->size - sizeof(int));
+ MPIU_VG_MEMPOOL_ALLOC(objmem, ptr, objmem->size);
+ /* the handle value is always valid at return from this function */
+ MPIU_VG_MAKE_MEM_DEFINED(&ptr->handle, sizeof(ptr->handle));
+
+ MPIU_DBG_MSG_FMT(HANDLE,TYPICAL,(MPIU_DBG_FDEST,
+ "Allocating object ptr %p (handle val 0x%08x)",
+ ptr, ptr->handle));
}
return ptr;
@@ -383,9 +417,6 @@
MPIU_THREAD_CS_ENTER(HANDLEALLOC,);
- MPIU_VG_MAKE_MEM_NOACCESS(&obj->ref_count, objmem->size - sizeof(int));
- MPIU_VG_MAKE_MEM_UNDEFINED(&obj->next, sizeof(obj->next));
-
MPIU_DBG_MSG_FMT(HANDLE,TYPICAL,(MPIU_DBG_FDEST,
"Freeing object ptr %p (0x%08x kind=%s) refcount=%d",
(obj),
@@ -393,6 +424,13 @@
MPIU_Handle_get_kind_str(HANDLE_GET_MPI_KIND((obj)->handle)),
MPIU_Object_get_ref(obj)));
+ MPIU_VG_MEMPOOL_FREE(objmem, obj);
+ /* MEMPOOL_FREE marks the object NOACCESS, so we have to make the
+ * MPIU_Handle_common area that is used for internal book keeping
+ * addressable again. */
+ MPIU_VG_MAKE_MEM_DEFINED(&obj->handle, sizeof(obj->handle));
+ MPIU_VG_MAKE_MEM_UNDEFINED(&obj->next, sizeof(obj->next));
+
obj->next = objmem->avail;
objmem->avail = obj;
MPIU_THREAD_CS_EXIT(HANDLEALLOC,);
More information about the mpich2-commits
mailing list