mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
Helper function to catch memory pool leaks.
This commit is contained in:
parent
6fe905c705
commit
d828b9a4d7
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.46 -
|
Version 2.02.46 -
|
||||||
================================
|
================================
|
||||||
|
Add memory pool leaks detection.
|
||||||
Use copy of PV structure when manipulating with global PV lists.
|
Use copy of PV structure when manipulating with global PV lists.
|
||||||
Always return exit error status when locking of volume group fails.
|
Always return exit error status when locking of volume group fails.
|
||||||
Fix mirror log convert validation question.
|
Fix mirror log convert validation question.
|
||||||
|
@ -1817,12 +1817,15 @@ void dm_lib_release(void)
|
|||||||
update_devs();
|
update_devs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dm_pools_check_leaks(void);
|
||||||
|
|
||||||
void dm_lib_exit(void)
|
void dm_lib_exit(void)
|
||||||
{
|
{
|
||||||
dm_lib_release();
|
dm_lib_release();
|
||||||
if (_dm_bitset)
|
if (_dm_bitset)
|
||||||
dm_bitset_destroy(_dm_bitset);
|
dm_bitset_destroy(_dm_bitset);
|
||||||
_dm_bitset = NULL;
|
_dm_bitset = NULL;
|
||||||
|
dm_pools_check_leaks();
|
||||||
dm_dump_memory();
|
dm_dump_memory();
|
||||||
_version_ok = 1;
|
_version_ok = 1;
|
||||||
_version_checked = 0;
|
_version_checked = 0;
|
||||||
|
@ -30,7 +30,9 @@ typedef struct {
|
|||||||
} pool_stats;
|
} pool_stats;
|
||||||
|
|
||||||
struct dm_pool {
|
struct dm_pool {
|
||||||
|
struct dm_list list;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
void *orig_pool; /* to pair it with first allocation call */
|
||||||
|
|
||||||
int begun;
|
int begun;
|
||||||
struct block *object;
|
struct block *object;
|
||||||
@ -65,10 +67,13 @@ struct dm_pool *dm_pool_create(const char *name, size_t chunk_hint)
|
|||||||
mem->stats.bytes = 0;
|
mem->stats.bytes = 0;
|
||||||
mem->stats.maxbytes = 0;
|
mem->stats.maxbytes = 0;
|
||||||
|
|
||||||
|
mem->orig_pool = mem;
|
||||||
|
|
||||||
#ifdef DEBUG_POOL
|
#ifdef DEBUG_POOL
|
||||||
log_debug("Created mempool %s", name);
|
log_debug("Created mempool %s", name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
dm_list_add(&_dm_pools, &mem->list);
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,6 +108,7 @@ void dm_pool_destroy(struct dm_pool *p)
|
|||||||
{
|
{
|
||||||
_pool_stats(p, "Destroying");
|
_pool_stats(p, "Destroying");
|
||||||
_free_blocks(p, p->blocks);
|
_free_blocks(p, p->blocks);
|
||||||
|
dm_list_del(&p->list);
|
||||||
dm_free(p);
|
dm_free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ struct chunk {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct dm_pool {
|
struct dm_pool {
|
||||||
|
struct dm_list list;
|
||||||
struct chunk *chunk, *spare_chunk; /* spare_chunk is a one entry free
|
struct chunk *chunk, *spare_chunk; /* spare_chunk is a one entry free
|
||||||
list to stop 'bobbling' */
|
list to stop 'bobbling' */
|
||||||
size_t chunk_size;
|
size_t chunk_size;
|
||||||
@ -51,6 +52,7 @@ struct dm_pool *dm_pool_create(const char *name, size_t chunk_hint)
|
|||||||
while (new_size < p->chunk_size)
|
while (new_size < p->chunk_size)
|
||||||
new_size <<= 1;
|
new_size <<= 1;
|
||||||
p->chunk_size = new_size;
|
p->chunk_size = new_size;
|
||||||
|
dm_list_add(&_dm_pools, &p->list);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,6 +67,7 @@ void dm_pool_destroy(struct dm_pool *p)
|
|||||||
c = pr;
|
c = pr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dm_list_del(&p->list);
|
||||||
dm_free(p);
|
dm_free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
|
|
||||||
#include "dmlib.h"
|
#include "dmlib.h"
|
||||||
|
|
||||||
|
/* FIXME: thread unsafe */
|
||||||
|
static DM_LIST_INIT(_dm_pools);
|
||||||
|
void dm_pools_check_leaks(void);
|
||||||
|
|
||||||
#ifdef DEBUG_POOL
|
#ifdef DEBUG_POOL
|
||||||
#include "pool-debug.c"
|
#include "pool-debug.c"
|
||||||
#else
|
#else
|
||||||
@ -52,3 +56,22 @@ void *dm_pool_zalloc(struct dm_pool *p, size_t s)
|
|||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dm_pools_check_leaks(void)
|
||||||
|
{
|
||||||
|
struct dm_pool *p;
|
||||||
|
|
||||||
|
if (dm_list_empty(&_dm_pools))
|
||||||
|
return;
|
||||||
|
|
||||||
|
log_error("You have a memory leak (not released memory pool):");
|
||||||
|
dm_list_iterate_items(p, &_dm_pools) {
|
||||||
|
#ifdef DEBUG_POOL
|
||||||
|
log_error(" [%p] %s (%u bytes)",
|
||||||
|
p->orig_pool,
|
||||||
|
p->name, p->stats.bytes);
|
||||||
|
#else
|
||||||
|
log_error(" [%p]", p);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user