mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2026-05-20 07:06:53 +08:00
bug #26213 "Problem with memory allocation when debugging": memp_sizes contained the wrong sizes (including sanity regions); memp pools for MEM_USE_POOLS were too small; Added option MEM_USE_POOLS_TRY_BIGGER_POOL to try the next bigger malloc pool if one is empty (only usable with MEM_USE_POOLS).
This commit is contained in:
@@ -67,14 +67,6 @@
|
||||
#if MEM_USE_POOLS
|
||||
/* lwIP head implemented with different sized pools */
|
||||
|
||||
/**
|
||||
* This structure is used to save the pool one element came from.
|
||||
*/
|
||||
struct mem_helper
|
||||
{
|
||||
memp_t poolnr;
|
||||
};
|
||||
|
||||
/**
|
||||
* Allocate memory: determine the smallest pool that is big enough
|
||||
* to contain an element of 'size' and get an element from that pool.
|
||||
@@ -85,13 +77,17 @@ struct mem_helper
|
||||
void *
|
||||
mem_malloc(mem_size_t size)
|
||||
{
|
||||
struct mem_helper *element;
|
||||
struct memp_malloc_helper *element;
|
||||
memp_t poolnr;
|
||||
mem_size_t required_size = size + sizeof(struct memp_malloc_helper);
|
||||
|
||||
for (poolnr = MEMP_POOL_FIRST; poolnr <= MEMP_POOL_LAST; poolnr++) {
|
||||
#if MEM_USE_POOLS_TRY_BIGGER_POOL
|
||||
again:
|
||||
#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */
|
||||
/* is this pool big enough to hold an element of the required size
|
||||
plus a struct mem_helper that saves the pool this element came from? */
|
||||
if ((size + sizeof(struct mem_helper)) <= memp_sizes[poolnr]) {
|
||||
plus a struct memp_malloc_helper that saves the pool this element came from? */
|
||||
if (required_size <= memp_sizes[poolnr]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -99,17 +95,23 @@ mem_malloc(mem_size_t size)
|
||||
LWIP_ASSERT("mem_malloc(): no pool is that big!", 0);
|
||||
return NULL;
|
||||
}
|
||||
element = (struct mem_helper*)memp_malloc(poolnr);
|
||||
element = (struct memp_malloc_helper*)memp_malloc(poolnr);
|
||||
if (element == NULL) {
|
||||
/* No need to DEBUGF or ASSERT: This error is already
|
||||
taken care of in memp.c */
|
||||
/** @todo: we could try a bigger pool if this one is empty! */
|
||||
#if MEM_USE_POOLS_TRY_BIGGER_POOL
|
||||
/** Try a bigger pool if this one is empty! */
|
||||
if (poolnr < MEMP_POOL_LAST) {
|
||||
poolnr++;
|
||||
goto again;
|
||||
}
|
||||
#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* save the pool number this element came from */
|
||||
element->poolnr = poolnr;
|
||||
/* and return a pointer to the memory directly after the struct mem_helper */
|
||||
/* and return a pointer to the memory directly after the struct memp_malloc_helper */
|
||||
element++;
|
||||
|
||||
return element;
|
||||
@@ -125,12 +127,12 @@ mem_malloc(mem_size_t size)
|
||||
void
|
||||
mem_free(void *rmem)
|
||||
{
|
||||
struct mem_helper *hmem = (struct mem_helper*)rmem;
|
||||
struct memp_malloc_helper *hmem = (struct memp_malloc_helper*)rmem;
|
||||
|
||||
LWIP_ASSERT("rmem != NULL", (rmem != NULL));
|
||||
LWIP_ASSERT("rmem == MEM_ALIGN(rmem)", (rmem == LWIP_MEM_ALIGN(rmem)));
|
||||
|
||||
/* get the original struct mem_helper */
|
||||
/* get the original struct memp_malloc_helper */
|
||||
hmem--;
|
||||
|
||||
LWIP_ASSERT("hmem != NULL", (hmem != NULL));
|
||||
|
||||
@@ -122,7 +122,7 @@ static struct memp *memp_tab[MEMP_MAX];
|
||||
static
|
||||
#endif
|
||||
const u16_t memp_sizes[MEMP_MAX] = {
|
||||
#define LWIP_MEMPOOL(name,num,size,desc) MEMP_ALIGN_SIZE(size),
|
||||
#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEM_ALIGN_SIZE(size),
|
||||
#include "lwip/memp_std.h"
|
||||
};
|
||||
|
||||
@@ -193,7 +193,7 @@ memp_overflow_check_element(struct memp *p, u16_t memp_size)
|
||||
}
|
||||
#endif
|
||||
#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0
|
||||
m = (u8_t*)p + MEMP_SIZE + memp_size - MEMP_SANITY_REGION_AFTER_ALIGNED;
|
||||
m = (u8_t*)p + MEMP_SIZE + memp_size;
|
||||
for (k = 0; k < MEMP_SANITY_REGION_AFTER_ALIGNED; k++) {
|
||||
if (m[k] != 0xcd) {
|
||||
LWIP_ASSERT("detected memp overflow!", 0);
|
||||
@@ -218,7 +218,7 @@ memp_overflow_check_all(void)
|
||||
p = p;
|
||||
for (j = 0; j < memp_num[i]; ++j) {
|
||||
memp_overflow_check_element(p, memp_sizes[i]);
|
||||
p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i]);
|
||||
p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -242,10 +242,10 @@ memp_overflow_init(void)
|
||||
memset(m, 0xcd, MEMP_SANITY_REGION_BEFORE_ALIGNED);
|
||||
#endif
|
||||
#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0
|
||||
m = (u8_t*)p + MEMP_SIZE + memp_sizes[i] - MEMP_SANITY_REGION_AFTER_ALIGNED;
|
||||
m = (u8_t*)p + MEMP_SIZE + memp_sizes[i];
|
||||
memset(m, 0xcd, MEMP_SANITY_REGION_AFTER_ALIGNED);
|
||||
#endif
|
||||
p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i]);
|
||||
p = (struct memp*)((u8_t*)p + MEMP_SIZE + memp_sizes[i] + MEMP_SANITY_REGION_AFTER_ALIGNED);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -277,7 +277,11 @@ memp_init(void)
|
||||
for (j = 0; j < memp_num[i]; ++j) {
|
||||
memp->next = memp_tab[i];
|
||||
memp_tab[i] = memp;
|
||||
memp = (struct memp *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i]);
|
||||
memp = (struct memp *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i]
|
||||
#if MEMP_OVERFLOW_CHECK
|
||||
+ MEMP_SANITY_REGION_AFTER_ALIGNED
|
||||
#endif
|
||||
);
|
||||
}
|
||||
}
|
||||
#if MEMP_OVERFLOW_CHECK
|
||||
@@ -317,8 +321,8 @@ memp_malloc_fn(memp_t type, const char* file, const int line)
|
||||
|
||||
memp = memp_tab[type];
|
||||
|
||||
if (memp != NULL) {
|
||||
memp_tab[type] = memp->next;
|
||||
if (memp != NULL) {
|
||||
memp_tab[type] = memp->next;
|
||||
#if MEMP_OVERFLOW_CHECK
|
||||
memp->next = NULL;
|
||||
memp->file = file;
|
||||
|
||||
Reference in New Issue
Block a user