summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorN Balachandran <nbalacha@redhat.com>2017-12-08 08:46:04 +0530
committerShyamsundar Ranganathan <srangana@redhat.com>2017-12-11 04:58:02 +0000
commit0679490c0414646d781f96020f8e85b7a8c3c828 (patch)
tree3fe6d06356e3e92b4757a3e05cf6d313dda575ac
parentdd8b4832588bcfcb73a74673bef196b87a7c16d3 (diff)
core/memacct: save allocs in mem_acct_rec list
With configure --enable-debug, add all object allocations to a list in the corresponding mem_acct_rec. This allows us to see all objects of a particular type and allows for additional debugging in case of memory leaks. This is not compiled in by default and must be explicitly enabled. It is intended to be used by developers. > Change-Id: I7cf2dbeadecf994423d7e7591e85f18d2575cce8 > BUG: 1522662 > Signed-off-by: N Balachandran <nbalacha@redhat.com> (cherry picked from commit 47d01546a1826dc14a8331ea8700015f1cfdc4db) Change-Id: I7cf2dbeadecf994423d7e7591e85f18d2575cce8 BUG: 1523456 Signed-off-by: N Balachandran <nbalacha@redhat.com>
-rw-r--r--doc/debugging/mem-alloc-list.md19
-rw-r--r--libglusterfs/src/mem-pool.c34
-rw-r--r--libglusterfs/src/mem-pool.h6
-rw-r--r--libglusterfs/src/xlator.c3
4 files changed, 61 insertions, 1 deletions
diff --git a/doc/debugging/mem-alloc-list.md b/doc/debugging/mem-alloc-list.md
new file mode 100644
index 0000000..1c68e65
--- /dev/null
+++ b/doc/debugging/mem-alloc-list.md
@@ -0,0 +1,19 @@
+## Viewing Memory Allocations
+
+While statedumps provide stats of the number of allocations, size etc for a
+particular mem type, there is no easy way to examine all the allocated objects of that type
+in memory.Being able to view this information could help with determining how an object is used,
+and if there are any memory leaks.
+
+The mem_acct_rec structures have been updated to include lists to which the allocated object is
+added. These can be examined in gdb using simple scripts.
+
+`gdb> plist xl->mem_acct.rec[$type]->obj_list`
+
+will print out the pointers of all allocations of $type.
+
+These changes are primarily targeted at developers and need to enabled
+at compile-time using `configure --enable-debug`.
+
+
+
diff --git a/libglusterfs/src/mem-pool.c b/libglusterfs/src/mem-pool.c
index a972f67..252bae5 100644
--- a/libglusterfs/src/mem-pool.c
+++ b/libglusterfs/src/mem-pool.c
@@ -78,8 +78,16 @@ gf_mem_set_acct_info (xlator_t *xl, char **alloc_ptr, size_t size,
header->mem_acct = xl->mem_acct;
header->magic = GF_MEM_HEADER_MAGIC;
+#ifdef DEBUG
+ INIT_LIST_HEAD(&header->acct_list);
+ LOCK(&xl->mem_acct->rec[type].lock);
+ {
+ list_add (&header->acct_list,
+ &(xl->mem_acct->rec[type].obj_list));
+ }
+ UNLOCK(&xl->mem_acct->rec[type].lock);
+#endif
ptr += sizeof (struct mem_header);
-
/* data follows in this gap of 'size' bytes */
*(uint32_t *) (ptr + size) = GF_MEM_TRAILER_MAGIC;
@@ -157,6 +165,27 @@ __gf_realloc (void *ptr, size_t size)
GF_ASSERT (old_header->magic == GF_MEM_HEADER_MAGIC);
tmp_header = *old_header;
+#ifdef DEBUG
+ int type = 0;
+ size_t copy_size = 0;
+
+ /* Making these changes for realloc is not straightforward. So
+ * I am simulating realloc using calloc and free
+ */
+
+ type = tmp_header.type;
+ new_ptr = __gf_calloc (1, size, type,
+ tmp_header.mem_acct->rec[type].typestr);
+ if (new_ptr) {
+ copy_size = (size > tmp_header.size) ? tmp_header.size : size;
+ memcpy (new_ptr, ptr, copy_size);
+ __gf_free (ptr);
+ }
+
+ /* This is not quite what the man page says should happen */
+ return new_ptr;
+#endif
+
tot_size = size + GF_MEM_HEADER_SIZE + GF_MEM_TRAILER_SIZE;
new_ptr = realloc (old_header, tot_size);
if (!new_ptr) {
@@ -313,6 +342,9 @@ __gf_free (void *free_ptr)
* to NULL */
if (!mem_acct->rec[header->type].num_allocs)
mem_acct->rec[header->type].typestr = NULL;
+#ifdef DEBUG
+ list_del (&header->acct_list);
+#endif
}
UNLOCK (&mem_acct->rec[header->type].lock);
diff --git a/libglusterfs/src/mem-pool.h b/libglusterfs/src/mem-pool.h
index e68e00d..a2a907a 100644
--- a/libglusterfs/src/mem-pool.h
+++ b/libglusterfs/src/mem-pool.h
@@ -46,6 +46,9 @@ struct mem_acct_rec {
uint32_t total_allocs;
uint32_t max_num_allocs;
gf_lock_t lock;
+#ifdef DEBUG
+ struct list_head obj_list;
+#endif
};
struct mem_acct {
@@ -59,6 +62,9 @@ struct mem_header {
size_t size;
struct mem_acct *mem_acct;
uint32_t magic;
+#ifdef DEBUG
+ struct list_head acct_list;
+#endif
int padding[8];
};
diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c
index de97dff..a6f83a2 100644
--- a/libglusterfs/src/xlator.c
+++ b/libglusterfs/src/xlator.c
@@ -604,6 +604,9 @@ xlator_mem_acct_init (xlator_t *xl, int num_types)
if (ret) {
fprintf(stderr, "Unable to lock..errno : %d",errno);
}
+#ifdef DEBUG
+ INIT_LIST_HEAD(&(xl->mem_acct->rec[i].obj_list));
+#endif
}
return 0;