switch to freeRtos malloc + improve malloc_safe utils, fixed memleak
This commit is contained in:
+3
-1
@@ -95,7 +95,7 @@
|
||||
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configSUPPORT_STATIC_ALLOCATION 1
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 0
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configCPU_CLOCK_HZ ( SystemCoreClock )
|
||||
@@ -109,6 +109,8 @@
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 2
|
||||
#define configENABLE_BACKWARD_COMPATIBILITY 0
|
||||
|
||||
#define configTOTAL_HEAP_SIZE 4096
|
||||
|
||||
/* Co-routine definitions. */
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||
|
||||
+7
-6
@@ -2,13 +2,14 @@
|
||||
// Created by MightyPork on 2017/11/21.
|
||||
//
|
||||
|
||||
#include <framework/system_settings.h>
|
||||
#include "platform.h"
|
||||
#include "framework/settings.h"
|
||||
#include "utils/ini_parser.h"
|
||||
#include "TinyFrame.h"
|
||||
#include "framework/unit_registry.h"
|
||||
#include "comm/messages.h"
|
||||
#include "framework/system_settings.h"
|
||||
#include "utils/malloc_safe.h"
|
||||
|
||||
static TinyFrame tf_;
|
||||
TinyFrame *comm = &tf_;
|
||||
@@ -61,7 +62,7 @@ static void settings_bulkread_cb(BulkRead *bulk, uint32_t chunk, uint8_t *buffer
|
||||
{
|
||||
// clean-up request
|
||||
if (buffer == NULL) {
|
||||
free(bulk);
|
||||
free_ck(bulk);
|
||||
iw_end();
|
||||
dbg("INI read complete.");
|
||||
return;
|
||||
@@ -80,8 +81,8 @@ static TF_Result lst_ini_export(TinyFrame *tf, TF_Msg *msg)
|
||||
{
|
||||
dbg("Bulk read INI file");
|
||||
|
||||
BulkRead *bulk = malloc(sizeof(BulkRead));
|
||||
assert_param(bulk);
|
||||
BulkRead *bulk = malloc_ck(sizeof(BulkRead));
|
||||
assert_param(bulk != NULL);
|
||||
|
||||
bulk->frame_id = msg->frame_id;
|
||||
bulk->len = iw_measure_total(settings_build_units_ini);
|
||||
@@ -115,7 +116,7 @@ static void settings_bulkwrite_cb(BulkWrite *bulk, const uint8_t *chunk, uint32_
|
||||
dbg("INI write failed");
|
||||
}
|
||||
|
||||
free(bulk);
|
||||
free_ck(bulk);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -129,7 +130,7 @@ static TF_Result lst_ini_import(TinyFrame *tf, TF_Msg *msg)
|
||||
{
|
||||
dbg("Bulk write INI file");
|
||||
|
||||
BulkWrite *bulk = malloc(sizeof(BulkWrite));
|
||||
BulkWrite *bulk = malloc_ck(sizeof(BulkWrite));
|
||||
assert_param(bulk);
|
||||
|
||||
bulk->frame_id = msg->frame_id;
|
||||
|
||||
@@ -206,5 +206,31 @@ void __attribute__((naked)) HardFault_Handler(void)
|
||||
while (1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
char *heap_end = 0;
|
||||
caddr_t _sbrk(int incr) {
|
||||
extern char _end; // this is the end of bbs, defined in LD
|
||||
extern char _estack; // this is the end of the allocable memory - defined in LD. Top level stack lives here.
|
||||
char *prev_heap_end;
|
||||
|
||||
if (heap_end == 0) {
|
||||
heap_end = &_end;
|
||||
}
|
||||
prev_heap_end = heap_end;
|
||||
|
||||
if (heap_end + incr > &_estack) {
|
||||
/* Heap and stack collision */
|
||||
dbg("\r\nOUT OF MEMORY");
|
||||
return (char*)-1;
|
||||
}
|
||||
#if DEBUG_MALLOC
|
||||
PRINTF(" !sbrk(%d),total=%d! ", incr, (int)(heap_end - &_end));
|
||||
#endif
|
||||
|
||||
heap_end += incr;
|
||||
return (caddr_t) prev_heap_end;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* USER CODE END 1 */
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include "macro.h"
|
||||
|
||||
#if USE_DEBUG_UART
|
||||
|
||||
|
||||
@@ -87,11 +87,10 @@ static bool savebuf_ovhandler(PayloadBuilder *pb, uint32_t more)
|
||||
void settings_save(void)
|
||||
{
|
||||
HAL_StatusTypeDef hst;
|
||||
bool suc;
|
||||
|
||||
assert_param(save_buffer == NULL); // It must be NULL here - otherwise we have a leak
|
||||
save_buffer = malloc_ck(FLASH_SAVE_BUF_LEN, &suc);
|
||||
assert_param(suc);
|
||||
save_buffer = malloc_ck(FLASH_SAVE_BUF_LEN);
|
||||
assert_param(save_buffer != NULL);
|
||||
|
||||
PayloadBuilder pb = pb_start(save_buffer, FLASH_SAVE_BUF_LEN, savebuf_ovhandler);
|
||||
|
||||
@@ -151,7 +150,7 @@ void settings_save(void)
|
||||
assert_param(hst == HAL_OK);
|
||||
fls_printf("--- Flash done ---\r\n");
|
||||
|
||||
free(save_buffer);
|
||||
free_ck(save_buffer);
|
||||
save_buffer = NULL;
|
||||
|
||||
#if DEBUG_FLASH_WRITE
|
||||
|
||||
+3
-10
@@ -5,6 +5,7 @@
|
||||
#include "platform.h"
|
||||
#include "unit.h"
|
||||
#include "resources.h"
|
||||
#include "unit_base.h"
|
||||
|
||||
char unit_tmp512[UNIT_TMP_LEN];
|
||||
|
||||
@@ -16,16 +17,8 @@ void clean_failed_unit(Unit *unit)
|
||||
dbg("!! Init of [%s] failed!", unit->name);
|
||||
|
||||
// Free if it looks like it might've been allocated
|
||||
if (isDynAlloc(unit->data)) {
|
||||
dbg("Freeing allocated unit data");
|
||||
free(unit->data);
|
||||
unit->data = NULL;
|
||||
}
|
||||
if (isDynAlloc(unit->name)) {
|
||||
dbg("Freeing allocated name");
|
||||
free((void *) unit->name);
|
||||
unit->name = NULL;
|
||||
}
|
||||
free_ck(unit->data);
|
||||
free_ck(unit->name);
|
||||
|
||||
dbg("Releasing any held resources");
|
||||
// Release any already claimed resources
|
||||
|
||||
+14
-20
@@ -58,8 +58,8 @@ void ureg_add_type(const UnitDriver *driver)
|
||||
assert_param(driver->deInit != NULL);
|
||||
assert_param(driver->handleRequest != NULL);
|
||||
|
||||
UregEntry *re = calloc_ck(1, sizeof(UregEntry), &suc);
|
||||
assert_param(suc);
|
||||
UregEntry *re = calloc_ck(1, sizeof(UregEntry));
|
||||
assert_param(re != NULL);
|
||||
|
||||
re->driver = driver;
|
||||
re->next = NULL;
|
||||
@@ -81,11 +81,7 @@ static void free_le_unit(UlistEntry *le)
|
||||
pUnit->driver->deInit(pUnit);
|
||||
// Name is not expected to be freed by the deInit() function
|
||||
// - was alloc'd in the settings load loop
|
||||
if (isDynAlloc(pUnit->name)) {
|
||||
dbg("Freeing allocated name");
|
||||
free((void *) pUnit->name);
|
||||
pUnit->name = NULL;
|
||||
}
|
||||
free_ck(pUnit->name);
|
||||
}
|
||||
|
||||
/** Add unit to the list, updating references as needed */
|
||||
@@ -103,7 +99,6 @@ static void add_unit_to_list(UlistEntry *le)
|
||||
// create a unit instance (not yet loading or initing - just pre-init)
|
||||
Unit *ureg_instantiate(const char *driver_name)
|
||||
{
|
||||
bool suc = true;
|
||||
error_t rv;
|
||||
|
||||
// Find type in the repository
|
||||
@@ -111,8 +106,8 @@ Unit *ureg_instantiate(const char *driver_name)
|
||||
while (re != NULL) {
|
||||
if (streq(re->driver->name, driver_name)) {
|
||||
// Create new list entry
|
||||
UlistEntry *le = calloc_ck(1, sizeof(UlistEntry), &suc);
|
||||
CHECK_SUC();
|
||||
UlistEntry *le = calloc_ck(1, sizeof(UlistEntry));
|
||||
if (le == NULL) return NULL;
|
||||
|
||||
le->next = NULL;
|
||||
|
||||
@@ -132,7 +127,7 @@ Unit *ureg_instantiate(const char *driver_name)
|
||||
|
||||
dbg("!! Unit type %s failed to pre-init! %s", driver_name, error_get_message(rv));
|
||||
clean_failed_unit(pUnit);
|
||||
free(le);
|
||||
free_ck(le);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -211,7 +206,7 @@ bool ureg_load_units(PayloadParser *pp)
|
||||
|
||||
// NAME
|
||||
pp_string(pp, typebuf, 16);
|
||||
pUnit->name = strdup(typebuf);
|
||||
pUnit->name = strdup_ck(typebuf);
|
||||
assert_param(pUnit->name);
|
||||
|
||||
// callsign
|
||||
@@ -247,7 +242,7 @@ void ureg_remove_all_units(void)
|
||||
next = le->next;
|
||||
|
||||
free_le_unit(le);
|
||||
free(le);
|
||||
free_ck(le);
|
||||
|
||||
le = next;
|
||||
}
|
||||
@@ -274,17 +269,17 @@ bool ureg_instantiate_by_ini(const char *restrict driver_name, const char *restr
|
||||
char *name = NULL;
|
||||
if (delim != NULL) {
|
||||
// not last
|
||||
name = strndup(p, delim - p);
|
||||
name = strndup_ck(p, delim - p);
|
||||
p = delim + 1;
|
||||
} else {
|
||||
// last name
|
||||
name = strdup(p);
|
||||
name = strdup_ck(p);
|
||||
p = NULL; // quit after this loop ends
|
||||
}
|
||||
assert_param(name);
|
||||
Unit *pUnit = ureg_instantiate(driver_name);
|
||||
if (!pUnit) {
|
||||
free(name);
|
||||
free_ck(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -514,9 +509,8 @@ void ureg_report_active_units(TF_ID frame_id)
|
||||
}
|
||||
msglen += count; // one byte per message for the callsign
|
||||
|
||||
bool suc = true;
|
||||
uint8_t *buff = calloc_ck(1, msglen, &suc);
|
||||
if (!suc) {
|
||||
uint8_t *buff = calloc_ck(1, msglen);
|
||||
if (buff == NULL) {
|
||||
com_respond_error(frame_id, E_OUT_OF_MEM);
|
||||
return;
|
||||
}
|
||||
@@ -539,7 +533,7 @@ void ureg_report_active_units(TF_ID frame_id)
|
||||
|
||||
com_respond_buf(frame_id, MSG_SUCCESS, buff, msglen);
|
||||
}
|
||||
free(buff);
|
||||
free_ck(buff);
|
||||
}
|
||||
|
||||
Unit *ureg_get_rsc_owner(Resource resource)
|
||||
|
||||
@@ -57,7 +57,8 @@ GEX_CFLAGS = \
|
||||
-MD -Wno-redundant-decls -Wno-unused-parameter \
|
||||
-Wno-unused-variable -Wno-inline \
|
||||
-fmerge-constants -fmerge-all-constants -Wno-implicit-fallthrough \
|
||||
-fno-exceptions -finline-small-functions -findirect-inlining -Wno-strict-aliasing -Wno-float-equal -Wno-discarded-qualifiers -fstack-usage
|
||||
-fno-exceptions -finline-small-functions -findirect-inlining -Wno-strict-aliasing -Wno-float-equal \
|
||||
-Wno-discarded-qualifiers -fstack-usage
|
||||
|
||||
GEX_CDEFS_BASE = \
|
||||
-D__weak="__attribute__((weak))" \
|
||||
@@ -75,7 +76,8 @@ GEX_CDEFS = $(GEX_CDEFS_BASE) \
|
||||
-DDEBUG_FLASH_WRITE=0 \
|
||||
-DVERBOSE_HARDFAULT=0 \
|
||||
-DUSE_STACK_MONITOR=0 \
|
||||
-DUSE_DEBUG_UART=0
|
||||
-DUSE_DEBUG_UART=0 \
|
||||
-DDEBUG_MALLOC=0
|
||||
|
||||
else
|
||||
|
||||
@@ -86,7 +88,8 @@ GEX_CDEFS = $(GEX_CDEFS_BASE) \
|
||||
-DDEBUG_FLASH_WRITE=0 \
|
||||
-DVERBOSE_HARDFAULT=1 \
|
||||
-DUSE_STACK_MONITOR=1 \
|
||||
-DUSE_DEBUG_UART=1
|
||||
-DUSE_DEBUG_UART=1 \
|
||||
-DDEBUG_MALLOC=0
|
||||
|
||||
endif
|
||||
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
#define TSK_STACK_MAIN 160
|
||||
#endif
|
||||
|
||||
#define TSK_STACK_MSG 180 // TF message handler task stack size (all unit commands run on this thread)
|
||||
// 180 is normally enough if not doing extensive debug logging
|
||||
#define TSK_STACK_MSG 200 // TF message handler task stack size (all unit commands run on this thread)
|
||||
|
||||
#define BULK_READ_BUF_LEN 256 // Buffer for TF bulk reads
|
||||
#define UNIT_TMP_LEN 512 // Buffer for internal unit operations
|
||||
|
||||
@@ -103,9 +103,8 @@ static void DI_writeIni(Unit *unit, IniWriter *iw)
|
||||
/** Allocate data structure and set defaults */
|
||||
static error_t DI_preInit(Unit *unit)
|
||||
{
|
||||
bool suc = true;
|
||||
struct priv *priv = unit->data = calloc_ck(1, sizeof(struct priv), &suc);
|
||||
if (!suc) return E_OUT_OF_MEM;
|
||||
struct priv *priv = unit->data = calloc_ck(1, sizeof(struct priv));
|
||||
if (priv == NULL) return E_OUT_OF_MEM;
|
||||
|
||||
// some defaults
|
||||
priv->port_name = 'A';
|
||||
@@ -167,8 +166,7 @@ static void DI_deInit(Unit *unit)
|
||||
rsc_teardown(unit);
|
||||
|
||||
// Free memory
|
||||
free(unit->data);
|
||||
unit->data = NULL;
|
||||
free_ck(unit->data);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@@ -96,9 +96,8 @@ static void DO_writeIni(Unit *unit, IniWriter *iw)
|
||||
/** Allocate data structure and set defaults */
|
||||
static error_t DO_preInit(Unit *unit)
|
||||
{
|
||||
bool suc = true;
|
||||
struct priv *priv = unit->data = calloc_ck(1, sizeof(struct priv), &suc);
|
||||
if (!suc) return E_OUT_OF_MEM;
|
||||
struct priv *priv = unit->data = calloc_ck(1, sizeof(struct priv));
|
||||
if (priv == NULL) return E_OUT_OF_MEM;
|
||||
|
||||
// some defaults
|
||||
priv->port_name = 'A';
|
||||
@@ -153,8 +152,7 @@ static void DO_deInit(Unit *unit)
|
||||
rsc_teardown(unit);
|
||||
|
||||
// Free memory
|
||||
free(unit->data);
|
||||
unit->data = NULL;
|
||||
free_ck(unit->data);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@@ -129,9 +129,8 @@ static void UI2C_writeIni(Unit *unit, IniWriter *iw)
|
||||
/** Allocate data structure and set defaults */
|
||||
static error_t UI2C_preInit(Unit *unit)
|
||||
{
|
||||
bool suc = true;
|
||||
struct priv *priv = unit->data = calloc_ck(1, sizeof(struct priv), &suc);
|
||||
if (!suc) return E_OUT_OF_MEM;
|
||||
struct priv *priv = unit->data = calloc_ck(1, sizeof(struct priv));
|
||||
if (priv == NULL) return E_OUT_OF_MEM;
|
||||
|
||||
// some defaults
|
||||
priv->periph_num = 1;
|
||||
@@ -282,8 +281,7 @@ static void UI2C_deInit(Unit *unit)
|
||||
rsc_teardown(unit);
|
||||
|
||||
// Free memory
|
||||
free(unit->data);
|
||||
unit->data = NULL;
|
||||
free_ck(unit->data);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@@ -79,11 +79,10 @@ static void Npx_writeIni(Unit *unit, IniWriter *iw)
|
||||
/** Allocate data structure and set defaults */
|
||||
static error_t Npx_preInit(Unit *unit)
|
||||
{
|
||||
bool suc = true;
|
||||
struct priv *priv = unit->data = calloc_ck(1, sizeof(struct priv), &suc);
|
||||
if (!suc) return E_OUT_OF_MEM;
|
||||
struct priv *priv = unit->data = calloc_ck(1, sizeof(struct priv));
|
||||
if (priv == NULL)
|
||||
|
||||
// some defaults
|
||||
// some defaults
|
||||
priv->pin_number = 0;
|
||||
priv->port_name = 'A';
|
||||
priv->pixels = 1;
|
||||
@@ -127,8 +126,7 @@ static void Npx_deInit(Unit *unit)
|
||||
rsc_teardown(unit);
|
||||
|
||||
// Free memory
|
||||
free(unit->data);
|
||||
unit->data = NULL;
|
||||
free_ck(unit->data);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@@ -169,9 +169,8 @@ static void USPI_writeIni(Unit *unit, IniWriter *iw)
|
||||
/** Allocate data structure and set defaults */
|
||||
static error_t USPI_preInit(Unit *unit)
|
||||
{
|
||||
bool suc = true;
|
||||
struct priv *priv = unit->data = calloc_ck(1, sizeof(struct priv), &suc);
|
||||
if (!suc) return E_OUT_OF_MEM;
|
||||
struct priv *priv = unit->data = calloc_ck(1, sizeof(struct priv));
|
||||
if (priv == NULL) return E_OUT_OF_MEM;
|
||||
|
||||
// some defaults
|
||||
priv->periph_num = 1;
|
||||
@@ -359,8 +358,7 @@ static void USPI_deInit(Unit *unit)
|
||||
rsc_teardown(unit);
|
||||
|
||||
// Free memory
|
||||
free(unit->data);
|
||||
unit->data = NULL;
|
||||
free_ck(unit->data);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@@ -50,9 +50,8 @@ static void Tst_writeIni(Unit *unit, IniWriter *iw)
|
||||
/** Allocate data structure and set defaults */
|
||||
static error_t Tst_preInit(Unit *unit)
|
||||
{
|
||||
bool suc = true;
|
||||
struct priv *priv = unit->data = calloc_ck(1, sizeof(struct priv), &suc);
|
||||
if (!suc) return E_OUT_OF_MEM;
|
||||
struct priv *priv = unit->data = calloc_ck(1, sizeof(struct priv));
|
||||
if (priv == NULL) return E_OUT_OF_MEM;
|
||||
|
||||
//
|
||||
|
||||
@@ -78,8 +77,7 @@ static void Tst_deInit(Unit *unit)
|
||||
//
|
||||
|
||||
// Free memory
|
||||
free(unit->data);
|
||||
unit->data = NULL;
|
||||
free_ck(unit->data);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@@ -98,7 +96,7 @@ static void br_longtext(struct bulk_read *bulk, uint32_t chunk, uint8_t *buffer)
|
||||
{
|
||||
// clean-up request
|
||||
if (buffer == NULL) {
|
||||
free(bulk);
|
||||
free_ck(bulk);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -109,7 +107,7 @@ static void bw_dump(struct bulk_write *bulk, const uint8_t *chunk, uint32_t len)
|
||||
{
|
||||
// clean-up request
|
||||
if (chunk == NULL) {
|
||||
free(bulk);
|
||||
free_ck(bulk);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -133,7 +131,7 @@ static error_t Tst_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, Pa
|
||||
return E_SUCCESS;
|
||||
|
||||
case CMD_BULKREAD:;
|
||||
BulkRead *br = malloc(sizeof(struct bulk_read));
|
||||
BulkRead *br = malloc_ck(sizeof(struct bulk_read));
|
||||
assert_param(br);
|
||||
|
||||
br->len = (uint32_t) strlen(longtext);
|
||||
@@ -144,7 +142,7 @@ static error_t Tst_handleRequest(Unit *unit, TF_ID frame_id, uint8_t command, Pa
|
||||
return E_SUCCESS;
|
||||
|
||||
case CMD_BULKWRITE:;
|
||||
BulkWrite *bw = malloc(sizeof(struct bulk_write));
|
||||
BulkWrite *bw = malloc_ck(sizeof(struct bulk_write));
|
||||
assert_param(bw);
|
||||
|
||||
bw->len = 10240;
|
||||
|
||||
@@ -42,9 +42,8 @@ struct priv {
|
||||
/** Allocate data structure and set defaults */
|
||||
static error_t UUSART_preInit(Unit *unit)
|
||||
{
|
||||
bool suc = true;
|
||||
struct priv *priv = unit->data = calloc_ck(1, sizeof(struct priv), &suc);
|
||||
if (!suc) return E_OUT_OF_MEM;
|
||||
struct priv *priv = unit->data = calloc_ck(1, sizeof(struct priv));
|
||||
if (priv == NULL) return E_OUT_OF_MEM;
|
||||
|
||||
// some defaults
|
||||
priv->periph_num = 1;
|
||||
@@ -618,7 +617,7 @@ static void UUSART_deInit(Unit *unit)
|
||||
rsc_teardown(unit);
|
||||
|
||||
// Free memory
|
||||
free(unit->data);
|
||||
free_ck(unit->data);
|
||||
unit->data = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,17 +12,6 @@ static inline bool inIRQ(void)
|
||||
return __get_IPSR() != 0;
|
||||
}
|
||||
|
||||
register char *__SP asm("sp");
|
||||
|
||||
static inline bool isDynAlloc(const void *obj)
|
||||
{
|
||||
// this is the 0x20000000-something address that should correspond to heap bottom
|
||||
extern char heapstart __asm("end");
|
||||
|
||||
return ((uint32_t)obj >= (uint32_t)&heapstart)
|
||||
&& ((uint32_t)obj < (uint32_t)__SP);
|
||||
}
|
||||
|
||||
/** Tight asm loop */
|
||||
#define __asm_loop(cycles) \
|
||||
do { \
|
||||
|
||||
+3
-5
@@ -23,17 +23,15 @@ char *iwbuffer = NULL;
|
||||
void iw_begin(void)
|
||||
{
|
||||
assert_param(iwbuffer == NULL);
|
||||
bool suc = true;
|
||||
iwbuffer = malloc_ck(IWBUFFER_LEN, &suc);
|
||||
assert_param(suc);
|
||||
iwbuffer = malloc_ck(IWBUFFER_LEN);
|
||||
assert_param(iwbuffer != NULL);
|
||||
}
|
||||
|
||||
/** Release the helper buffer */
|
||||
void iw_end(void)
|
||||
{
|
||||
assert_param(iwbuffer != NULL);
|
||||
free(iwbuffer);
|
||||
iwbuffer = NULL;
|
||||
free_ck(iwbuffer);
|
||||
}
|
||||
|
||||
#define IW_VPRINTF() do { \
|
||||
|
||||
+26
-30
@@ -1,48 +1,44 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <inttypes.h>
|
||||
#include "platform.h"
|
||||
#include "debug.h"
|
||||
#include "stm32_assert.h"
|
||||
#include "malloc_safe.h"
|
||||
|
||||
#if 1
|
||||
|
||||
void *malloc_safe_do(size_t size, const char *file, uint32_t line)
|
||||
void *malloc_ck_do(size_t size, const char *file, uint32_t line)
|
||||
{
|
||||
void *mem = malloc(size);
|
||||
if (mem == NULL) abort_msg("MALLOC FAILED", file, line);
|
||||
return mem;
|
||||
}
|
||||
|
||||
void *calloc_safe_do(size_t nmemb, size_t size, const char *file, uint32_t line)
|
||||
{
|
||||
void *mem = calloc(size, nmemb);
|
||||
if (mem == NULL) abort_msg("CALLOC FAILED", file, line);
|
||||
return mem;
|
||||
}
|
||||
|
||||
|
||||
void *malloc_ck_do(size_t size, bool *suc, const char *file, uint32_t line)
|
||||
{
|
||||
void *mem = malloc(size);
|
||||
void *mem = pvPortMalloc(size);
|
||||
_malloc_trace(size, mem, file, line);
|
||||
if (mem == NULL) {
|
||||
warn_msg("MALLOC FAILED", file, line);
|
||||
*suc = false;
|
||||
mem = NULL;
|
||||
}
|
||||
return mem;
|
||||
}
|
||||
|
||||
void *calloc_ck_do(size_t nmemb, size_t size, bool *suc, const char *file, uint32_t line)
|
||||
void *calloc_ck_do(size_t nmemb, size_t size, const char *file, uint32_t line)
|
||||
{
|
||||
void *mem = calloc(size, nmemb);
|
||||
void *mem = pvPortMalloc(size*nmemb);
|
||||
_malloc_trace(nmemb*size, mem, file, line);
|
||||
if (mem == NULL) {
|
||||
warn_msg("CALLOC FAILED", file, line);
|
||||
*suc = false;
|
||||
mem = NULL;
|
||||
}
|
||||
memset(mem, 0, size*nmemb);
|
||||
return mem;
|
||||
}
|
||||
|
||||
#endif
|
||||
char *strdup_ck_do(const char *s, const char* file, uint32_t line)
|
||||
{
|
||||
size_t len = strlen(s) + 1;
|
||||
void *new = malloc_ck_do(len, file, line);
|
||||
if (new == NULL) return NULL;
|
||||
return (char *) memcpy (new, s, len);
|
||||
}
|
||||
|
||||
char *strndup_ck_do(const char *s, uint32_t len, const char* file, uint32_t line)
|
||||
{
|
||||
// TODO verify - this was not tested
|
||||
size_t alen = MIN(strlen(s) + 1, len);
|
||||
uint8_t *new = malloc_ck_do(alen, file, line);
|
||||
if (new == NULL) return NULL;
|
||||
memcpy (new, s, alen-1);
|
||||
new[alen-1] = '\0';
|
||||
return (char *) new;
|
||||
}
|
||||
|
||||
+29
-8
@@ -9,14 +9,35 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void *malloc_safe_do(size_t size, const char* file, uint32_t line) __attribute__((malloc));
|
||||
void *calloc_safe_do(size_t nmemb, size_t size, const char* file, uint32_t line) __attribute__((malloc));
|
||||
void *malloc_ck_do(size_t size, bool *suc, const char* file, uint32_t line) __attribute__((malloc));
|
||||
void *calloc_ck_do(size_t nmemb, size_t size, bool *suc, const char* file, uint32_t line) __attribute__((malloc));
|
||||
void *malloc_ck_do(size_t size, const char* file, uint32_t line) __attribute__((malloc));
|
||||
void *calloc_ck_do(size_t nmemb, size_t size, const char* file, uint32_t line) __attribute__((malloc));
|
||||
char *strdup_ck_do(const char *s, const char* file, uint32_t line) __attribute__((malloc));
|
||||
char *strndup_ck_do(const char *s, uint32_t len, const char* file, uint32_t line) __attribute__((malloc));
|
||||
|
||||
#define malloc_s(size) malloc_safe_do(size, __BASE_FILE__, __LINE__)
|
||||
#define calloc_s(nmemb, size) calloc_safe_do(nmemb, size, __BASE_FILE__, __LINE__)
|
||||
#define malloc_ck(size, suc) malloc_ck_do(size, suc, __BASE_FILE__, __LINE__)
|
||||
#define calloc_ck(nmemb, size, suc) calloc_ck_do(nmemb, size, suc, __BASE_FILE__, __LINE__)
|
||||
#if DEBUG_MALLOC
|
||||
|
||||
#define _malloc_trace(len, obj, file, line) do { PRINTF("~ malloc(%d) -> 0x%p at ", len, obj); PUTS(file); PUTCHAR(':'); PRINTF("%d\r\n", (int)line); } while (0)
|
||||
#define _free_trace(obj, file, line) do { PRINTF("~ free(0x%p) at ", obj); PUTS(file); PUTCHAR(':'); PRINTF("%d\r\n", (int)line); } while (0)
|
||||
#define malloc_ck(size) malloc_ck_do(size, __BASE_FILE__, __LINE__)
|
||||
#define calloc_ck(nmemb, size) calloc_ck_do(nmemb, size, __BASE_FILE__, __LINE__)
|
||||
#define strdup_ck(s) strdup_ck_do(s, __BASE_FILE__, __LINE__)
|
||||
#define strndup_ck(s, len) strndup_ck_do(s, (uint32_t)(len), __BASE_FILE__, __LINE__)
|
||||
#else
|
||||
#define _malloc_trace(len, obj, file, line)
|
||||
#define _free_trace(obj, file, line)
|
||||
#define malloc_ck(size) malloc_ck_do(size, "", 0)
|
||||
#define calloc_ck(nmemb, size) calloc_ck_do(nmemb, size, "", 0)
|
||||
#define strdup_ck(s) strdup_ck_do(s, "", 0)
|
||||
#define strndup_ck(s, len) strndup_ck_do(s, (uint32_t)(len), "", 0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Free an allocated object, and assign it to NULL.
|
||||
*/
|
||||
#define free_ck(obj) do { \
|
||||
_free_trace(obj, __BASE_FILE__, __LINE__); \
|
||||
if ((obj) != NULL) vPortFree((void *)(obj)); \
|
||||
obj = NULL; \
|
||||
} while (0)
|
||||
|
||||
#endif // MALLOC_SAFE_H
|
||||
|
||||
+3
-2
@@ -23,6 +23,7 @@
|
||||
|
||||
/**** pts: sam2p-specific defines ****/
|
||||
#include "snprintf.h"
|
||||
#include "malloc_safe.h"
|
||||
/* #include <stdarg.h> -- from snprintf.h */
|
||||
#ifdef NULL /* as on Mac OS/X 10.5.7 <stdlib.h> */
|
||||
# undef NULL
|
||||
@@ -32,7 +33,7 @@
|
||||
# define malloc ::operator new
|
||||
#else
|
||||
# include <stdlib.h> /* malloc() */
|
||||
#include <debug.h>
|
||||
#include "debug.h"
|
||||
|
||||
#endif
|
||||
#define size_t size_t /* normally: int, unsigned */
|
||||
@@ -834,7 +835,7 @@ size_t vasprintf(char **ptr, const char *format, va_list ap)
|
||||
ret = vsnprintf((char*)NULL, 0, format, ap);
|
||||
if (ret+1 <= 1) return ret; /* pts: bit of old unsigned trick... */
|
||||
|
||||
if (NULL==(*ptr = (char *)malloc(ret+1))) return (size_t)-1;
|
||||
if (NULL==(*ptr = (char *)malloc_ck(ret+1))) return (size_t)-1;
|
||||
ret = vsnprintf(*ptr, ret+1, format, ap);
|
||||
|
||||
return ret;
|
||||
|
||||
Reference in New Issue
Block a user