Improve pvPortMalloc() and family.

fix(esp8266): If MEMLEAK_DEBUG is defined, create an alternate function
called `.._trace` that for each of `pvPortMalloc`, `pvPortZalloc`,
`pvPortCalloc` and `vPortFree`. The original function delegates to this new
tracing function but uses NULL and 0 for the file and line number. This ensures
that the pvPortMalloc exists as a symbol that can be used by the binary blobs
without any problems.

Example output from earlier usage:

~~~
--------Show Malloc--------
F:ppT	L:512	malloc 2064	@ 0x3ffefd08
F:pmT	L:256	malloc 1040	@ 0x3fff0518
F:tiT	L:512	malloc 2064	@ 0x3fff0928
F:uiT	L:640	malloc 2576	@ 0x3fff1138
F:IDLE	L:176	malloc 720	@ 0x3fff1b48
F:Tmr Svc	L:512	malloc 2064	@ 0x3fff1e18
~~~

fix(lwip): Remove declarations of `pvPortMalloc()` and family.

This fixes some of the issues in espressif/ESP8266_RTOS_SDK#189 but some of the
example applications fails. Not ready for merge but comments on my approach
will be appreciated.
This commit is contained in:
Trygve Laugstøl
2018-05-20 20:54:07 +02:00
committed by Wu Jian Gang
parent 9daf22b07b
commit 24ef94f811
5 changed files with 64 additions and 34 deletions

View File

@ -118,7 +118,7 @@ bool ICACHE_FLASH_ATTR check_memleak_debug_enable(void)
#define os_free(s) \ #define os_free(s) \
do{\ do{\
static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; \ static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; \
vPortFree(s, mem_debug_file, __LINE__);\ vPortFree_trace(s, mem_debug_file, __LINE__);\
}while(0) }while(0)
#endif #endif
@ -126,7 +126,7 @@ do{\
#define os_malloc(s) \ #define os_malloc(s) \
({ \ ({ \
static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; \ static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; \
pvPortMalloc(s, mem_debug_file, __LINE__, false); \ pvPortMalloc_trace(s, mem_debug_file, __LINE__, false); \
}) })
#endif #endif
@ -134,7 +134,7 @@ do{\
#define os_malloc_iram(s) \ #define os_malloc_iram(s) \
({ \ ({ \
static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; \ static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; \
pvPortMalloc(s, mem_debug_file, __LINE__, true); \ pvPortMalloc_trace(s, mem_debug_file, __LINE__, true); \
}) })
#endif #endif
@ -142,7 +142,7 @@ do{\
#define os_calloc(p, s) \ #define os_calloc(p, s) \
({ \ ({ \
static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; \ static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; \
pvPortCalloc(p, s, mem_debug_file, __LINE__); \ pvPortCalloc_trace(p, s, mem_debug_file, __LINE__); \
}) })
#endif #endif
@ -150,7 +150,7 @@ do{\
#define os_realloc(p, s) \ #define os_realloc(p, s) \
({ \ ({ \
static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; \ static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; \
pvPortRealloc(p, s, mem_debug_file, __LINE__); \ pvPortRealloc_trace(p, s, mem_debug_file, __LINE__); \
}) })
#endif #endif
@ -158,7 +158,7 @@ do{\
#define os_zalloc(s) \ #define os_zalloc(s) \
({ \ ({ \
static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; \ static const char mem_debug_file[] ICACHE_RODATA_ATTR STORE_ATTR = __FILE__; \
pvPortZalloc(s, mem_debug_file, __LINE__); \ pvPortZalloc_trace(s, mem_debug_file, __LINE__); \
}) })
#endif #endif

View File

@ -126,8 +126,18 @@ void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) PRIVILEG
/* /*
* Map to the memory management routines required for the port. * Map to the memory management routines required for the port.
*/ */
//void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION; void *pvPortMalloc( size_t xSize ) PRIVILEGED_FUNCTION;
//void vPortFree( void *pv ) PRIVILEGED_FUNCTION; void *pvPortZalloc( size_t xWantedSize ) PRIVILEGED_FUNCTION;
void *pvPortCalloc( size_t count, size_t size ) PRIVILEGED_FUNCTION;
void vPortFree( void *pv ) PRIVILEGED_FUNCTION;
#ifdef MEMLEAK_DEBUG
void *pvPortMalloc_trace( size_t xWantedSize, const char * file, unsigned line, bool use_iram ) PRIVILEGED_FUNCTION;
void *pvPortZalloc_trace( size_t xWantedSize, const char * file, unsigned line ) PRIVILEGED_FUNCTION;
void *pvPortCalloc_trace( size_t count, size_t size, const char * file, unsigned line ) PRIVILEGED_FUNCTION;
void vPortFree_trace( void *pv, const char * file, unsigned line ) PRIVILEGED_FUNCTION;
#endif
void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION; void vPortInitialiseBlocks( void ) PRIVILEGED_FUNCTION;
size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION; size_t xPortGetFreeHeapSize( void ) PRIVILEGED_FUNCTION;
size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION; size_t xPortGetMinimumEverFreeHeapSize( void ) PRIVILEGED_FUNCTION;

View File

@ -313,10 +313,13 @@ size_t xPortWantedSizeAlign(size_t xWantedSize)
return xWantedSize; return xWantedSize;
} }
#ifndef MEMLEAK_DEBUG
void *pvPortMalloc( size_t xWantedSize ) void *pvPortMalloc( size_t xWantedSize )
#else #ifdef MEMLEAK_DEBUG
void *pvPortMalloc( size_t xWantedSize, const char * file, unsigned line, bool use_iram) {
return pvPortMalloc_trace( xWantedSize, NULL, 0, false );
}
void *pvPortMalloc_trace( size_t xWantedSize, const char * file, unsigned line, bool use_iram )
#endif #endif
{ {
BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink; BlockLink_t *pxBlock, *pxPreviousBlock, *pxNewBlockLink;
@ -492,12 +495,16 @@ static bool is_inited = false;
return pvReturn; return pvReturn;
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifndef MEMLEAK_DEBUG
void vPortFree( void *pv ) void vPortFree( void *pv )
#else #ifdef MEMLEAK_DEBUG
void vPortFree(void *pv, const char * file, unsigned line) {
return vPortFree_trace( pv, NULL, 0 );
}
void vPortFree_trace( void *pv, const char * file, unsigned line )
#endif #endif
{ {
uint8_t *puc = ( uint8_t * ) pv; uint8_t *puc = ( uint8_t * ) pv;
@ -556,6 +563,7 @@ BlockLink_t *pxLink;
} }
} }
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifndef MEMLEAK_DEBUG #ifndef MEMLEAK_DEBUG
@ -615,12 +623,12 @@ void *realloc(void *ptr, size_t nbytes) __attribute__((alias("pvPortRealloc")));
#else #else
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void *pvPortCalloc(size_t count, size_t size, const char * file, unsigned line) void *pvPortCalloc_trace(size_t count, size_t size, const char * file, unsigned line)
{ {
void *p; void *p;
//ets_printf("1,"); //ets_printf("1,");
/* allocate 'count' objects of size 'size' */ /* allocate 'count' objects of size 'size' */
p = pvPortMalloc(count * size, file, line, false); p = pvPortMalloc_trace(count * size, file, line, false);
//ets_printf("2,"); //ets_printf("2,");
if (p) { if (p) {
/* zero the memory */ /* zero the memory */
@ -629,59 +637,70 @@ void *pvPortCalloc(size_t count, size_t size, const char * file, unsigned line)
//ets_printf("3,"); //ets_printf("3,");
return p; return p;
} }
/*-----------------------------------------------------------*/ void *pvPortCalloc(size_t count, size_t size) {
return pvPortCalloc_trace(count, size, NULL, 0);
void *pvPortZalloc(size_t size, const char * file, unsigned line)
{
return pvPortCalloc(1, size, file, line);
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
void *pvPortRealloc(void *mem, size_t newsize, const char *file, unsigned line) void *pvPortZalloc_trace(size_t size, const char * file, unsigned line)
{
return pvPortCalloc_trace(1, size, file, line);
}
void *pvPortZalloc(size_t size) {
return pvPortZalloc_trace( size, NULL, 0 );
}
/*-----------------------------------------------------------*/
void *pvPortRealloc_trace(void *mem, size_t newsize, const char *file, unsigned line)
{ {
if (newsize == 0) { if (newsize == 0) {
vPortFree(mem, file, line); vPortFree_trace(mem, file, line);
return NULL; return NULL;
} }
void *p; void *p;
p = pvPortMalloc(newsize, file, line, false); p = pvPortMalloc_trace(newsize, file, line, false);
if (p) { if (p) {
/* zero the memory */ /* zero the memory */
if (mem != NULL) { if (mem != NULL) {
memcpy(p, mem, newsize); memcpy(p, mem, newsize);
vPortFree(mem, file, line); vPortFree_trace(mem, file, line);
} }
} }
return p; return p;
} }
void *pvPortRealloc(void *mem, size_t newsize) {
return pvPortRealloc_trace(mem, newsize, NULL, 0 );
}
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
//For user //For user
void *malloc(size_t nbytes) void *malloc(size_t nbytes)
{ {
//ets_printf("u_m\n"); //ets_printf("u_m\n");
return pvPortMalloc( nbytes, mem_debug_file, 0, false); return pvPortMalloc_trace( nbytes, mem_debug_file, 0, false);
} }
void free(void *ptr) void free(void *ptr)
{ {
//ets_printf("u_f\n"); //ets_printf("u_f\n");
vPortFree(ptr, mem_debug_file, 0); vPortFree_trace(ptr, mem_debug_file, 0);
} }
void *zalloc(size_t nbytes) void *zalloc(size_t nbytes)
{ {
return pvPortZalloc(nbytes, mem_debug_file, 0); return pvPortZalloc_trace(nbytes, mem_debug_file, 0);
} }
void *calloc(size_t count, size_t nbytes) void *calloc(size_t count, size_t nbytes)
{ {
return pvPortCalloc(count, nbytes, mem_debug_file, 0); return pvPortCalloc_trace(count, nbytes, mem_debug_file, 0);
} }
void *realloc(void *ptr, size_t nbytes) void *realloc(void *ptr, size_t nbytes)
{ {
return pvPortRealloc(ptr, nbytes, mem_debug_file, 0); return pvPortRealloc_trace(ptr, nbytes, mem_debug_file, 0);
} }
/* /*

View File

@ -194,10 +194,6 @@
/** /**
* Use DRAM instead of IRAM * Use DRAM instead of IRAM
*/ */
extern void *pvPortMalloc( size_t xWantedSize, const char * file, unsigned line, bool use_iram);
extern void *pvPortZalloc( size_t xWantedSize, const char * file, unsigned line);
extern void *pvPortCalloc(size_t count, size_t size, const char * file, unsigned line);
extern void vPortFree(void *pv, const char * file, unsigned line);
#define mem_clib_free os_free #define mem_clib_free os_free
#define mem_clib_malloc os_malloc #define mem_clib_malloc os_malloc
#define mem_clib_calloc os_calloc #define mem_clib_calloc os_calloc

View File

@ -21,6 +21,7 @@
#include "esp8266/ets_sys.h" #include "esp8266/ets_sys.h"
#include "esp8266/eagle_soc.h" #include "esp8266/eagle_soc.h"
#include "esp8266/uart_register.h" #include "esp8266/uart_register.h"
#include "FreeRTOS.h"
#define PANIC_UART 0 #define PANIC_UART 0
@ -91,7 +92,11 @@ void _sbrk_r(void *ptr, int incr)
void *_malloc_r(struct _reent *r, size_t n) void *_malloc_r(struct _reent *r, size_t n)
{ {
#ifndef MEMLEAK_DEBUG
return pvPortMalloc(n); return pvPortMalloc(n);
#else
return pvPortMalloc_trace(n, NULL, 0, false);
#endif
} }
void *_realloc_r(struct _reent *r, void *old_ptr, size_t n) void *_realloc_r(struct _reent *r, void *old_ptr, size_t n)