In ARC XCode application, it uses native C library.
When the library functions are called continuously about 2000 times, the application stopped working on iPad device.
The 'Instrument' showed that, only 'Malloc' is getting accumulated and 'free' is not considered.
I have no clue, what happens with the 'free' call.
The code is given below:
Memory allocations:
efHeapSize = EF_MIN_HEAPSIZE; pEFHeap = (void
*)malloc(efHeapSize);
cedHeapsize = heapMemorySize - efHeapSize; pCEDHeap = (void
*)malloc(cedHeapsize);
Memory Free:
if (pEFHeap != NULL) {
free (pEFHeap);
pEFHeap = NULL;
printf("pEFHeap freed \n");
}
if (pCEDHeap != NULL) {
free (pCEDHeap);
pCEDHeap = NULL;
printf("pCEDHeap freed \n");
}
Related
I have a GUI written in R that utilizes Tcl/TK package as well a C .dll that also uses Tcl library. I have done some research on this issue, and it seems to be memory related. I am an inexperienced programmer, so I am not sure where I should be looking for this memory issue. Each call of malloc() has a matching free(), and same with the analogous Tcl_Alloc() and Tcl_Free(). This error is very hard to reproduce as well, thus I am afraid I cannot provide a reproducible example as it is seemingly random in nature. One pattern is however that it seems to only happen upon closure of the program, though this is very inconsistent.
By making this post, I am hoping to gain a logical process that one should take in an attempt to debug this problem in a general context under Tcl/Tk - C - R applications. I am not looking for a solution specific to my code, but rather what an individual should think about when encountering this problem.
The message comes from the function Ptr2Block() in tclThreadAlloc.c (or there's something else about which produces the same error message; possible but unlikely) which is Tcl's thread-specific memory allocator (which is used widely inside Tcl to reduce the number of times global locks are hit). Specifically, it's this bit:
if (blockPtr->magicNum1 != MAGIC || blockPtr->magicNum2 != MAGIC) {
Tcl_Panic("alloc: invalid block: %p: %x %x",
blockPtr, blockPtr->magicNum1, blockPtr->magicNum2);
}
The problem? Those zeroes should be MAGIC (which is equal to 0xEF). This indicates that something has overwritten the memory block's metadata — which also should include the size of the block, but that is now likely hot garbage — and program memory integrity can no longer be trusted. Alas, at this point we're now dealing with a program in a broken state where the breakage happened some time previously; the place where the panic happened is merely where detection of the bug happened, not the actual location of the bug.
Debugging further is usually done by building a version of everything with fancy memory allocators turned off (in Tcl's code, this is done by defining the PURIFY symbol when building) and then running the resulting code — which hopefully still has the bug — with a tool like electricfence or purify (hence the special symbol name) to see what sort of out-of-bounds errors are found; they're very good at hunting down this sort of issue.
I would advise you to start by having a closer look to the sizeof() values provided to your Tcl_Alloc() calls in this C .dll.
I'm writing myself a Tcl binding for a C library and I faced recently exactly the same problem and therefore I'm assuming you may have the same error than me in your code.
Here below a minimal example that reproduces the problem:
#include <tcl.h>
#include <stdlib.h> // malloc
static unsigned int dataCtr;
struct tDataWrapper {
const char *str; // Tcl_GetCommandName(interp, cmd)
unsigned int n; // dataCtr value
void *data; // pointer to wrapped object
};
static void wrapDelCmd(ClientData clientData)
{
struct tDataWrapper *wrap = (struct tDataWrapper *) clientData;
if (wrap != NULL) {
/* with false sizeof value provided while creating the wrapper
* (see above), this data pointer would overwrite the
* overhead section of the allocated tcl memory block
* from what I understood and this is what can be causing
* the panic with message like following one when the
* memory is freed with ckfree (here after calling unload)
* alloc: invalid block: 0000018F2624E760: 0 0 */
printf("DEBUG: #%s(%s) &wrap->data #%p\n",
__func__, wrap->str, &wrap->data);
if (wrap->data != NULL) {
// call your wrapped API to deinstantiate the object
}
ckfree(wrap);
}
}
static int wrapCmd(ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[])
{
struct tDataWrapper *wrap = (struct tDataWrapper *) clientData;
if (wrap == NULL)
return TCL_ERROR;
else if (wrap->data != NULL) {
// call your wrapped API to do something with instantiated object
return TCL_OK;
} else {
Tcl_Obj *obj = Tcl_ObjPrintf("wrap: {str=\"%s\", n=%u, data=%llx}",
wrap->str, wrap->n, (unsigned long long) wrap->data);
if (obj != NULL) {
Tcl_SetObjResult(interp, obj);
return TCL_OK;
} else
return TCL_ERROR;
}
}
static int newCmd(ClientData clientData, Tcl_Interp *interp,
int objc, Tcl_Obj *const objv[])
{
struct tDataWrapper *wrap;
Tcl_Obj *obj;
Tcl_Command cmd;
// 3) this is correct
// if ((wrap = attemptckalloc(sizeof(struct tDataWrapper))) == NULL)
// 2) still incorrect but GCC gives more warning regarding the inconsistent pointer handling
// if ((wrap = malloc(sizeof(struct tDataWrapper *))) == NULL)
// 1) this is incorrect
if ((wrap = attemptckalloc(sizeof(struct tDataWrapper *))) == NULL)
Tcl_Panic("%s:%u: attemptckalloc failed\n", __func__, __LINE__);
else if ((obj = Tcl_ObjPrintf("data%u", dataCtr+1)) == NULL)
Tcl_Panic("%s:%u: Tcl_ObjPrintf failed\n", __func__, __LINE__);
else if ((cmd = Tcl_CreateObjCommand(interp, Tcl_GetString(obj),
wrapCmd, (ClientData) wrap, wrapDelCmd)) == NULL)
Tcl_Panic("%s:%u: Tcl_CreateObjCommand failed\n", __func__, __LINE__);
else {
wrap->str = Tcl_GetCommandName(interp, cmd);
wrap->n = dataCtr;
wrap->data = NULL; // call your wrapped API to instantiate an object
dataCtr++;
Tcl_SetObjResult(interp, obj);
}
return TCL_OK;
}
int Allocinvalidblock_Init(Tcl_Interp *interp)
{
dataCtr = 0;
return (Tcl_CreateObjCommand(interp, "new",
newCmd, (ClientData) NULL, NULL)
== NULL) ? TCL_ERROR : TCL_OK;
}
int Allocinvalidblock_Unload(Tcl_Interp *interp, int flags)
{
Tcl_Namespace *ns = Tcl_GetGlobalNamespace(interp);
Tcl_Obj *obj;
Tcl_Command cmd;
unsigned int i;
for(i=0; i<dataCtr; i++) {
if ((obj = Tcl_ObjPrintf("data%u", i+1)) != NULL) {
if ((cmd = Tcl_FindCommand(interp,
Tcl_GetString(obj), ns, TCL_GLOBAL_ONLY)) != NULL)
Tcl_DeleteCommandFromToken(interp, cmd);
Tcl_DecrRefCount(obj);
}
}
return TCL_OK;
}
Once built (for example with Code::Blocks as shared library project linking against C:/msys64/mingw64/lib/libtcl.dll.a), the error can be triggered when more than a data object is created and the library immediately unloaded:
load bin/Release/libAllocInvalidBlock.dll
new
new
unload bin/Release/libAllocInvalidBlock.dll
If used otherwise the crash may even be not triggered... Anyway, such an error in the C code is not particularly obvious to identify (although easy to fix) because the compilation is running without any warning (although -Wall compiler flag is set).
I am working on STM32L475 IoT kit which is an ARM M4 Cortex device. I want to swap two regions of flash memory. The board I am using has two banks for flash memory each having a size of 512KB.So I have 1 MB Flash memory. I read that for swapping contents of flash memory you have to first unlock it, then erase it and then write it and lock the flash memory after the operation is over.
There is another restriction that at a time only 2KB of memory can be copied which is defined as a page. So only page by page copying of memory is possible. For my application I have to swap application 1 and 2 which are stored in FLASH memory,if some conditions are met. Though both the applications have been allotted 384 KB of memory each but both of them actually use less memory than that(say 264 KB for example).
I tried to follow the above steps but its not working. Here is the code which I tried:-
#define APPLICATION_ADDRESS 0x0800F000
#define APPLICATION2_ADDRESS 0x0806F800
#define SWAP_ADDRESS 0x0806F000
boolean swap(void)
{
char *app_1=( char*) APPLICATION_ADDRESS;//points to the 1st address of application1
char *app_2=(char*) APPLICATION2_ADDRESS;//points to the 1st address of application2
int mem1 = getMemorySize((unsigned char*)APPLICATION_ADDRESS);//returns the number of bytes in Application1
int mem2 = getMemorySize((unsigned char*)APPLICATION2_ADDRESS);//returns the number of bytes in Application2
int limit;
if(mem1>mem2)
limit= mem1;
else
limit= mem2;
Unlock_FLASH();
int lm = limit/2048;
for(int i=1; i<=lm; i++,app_1+=2048,app_2+=2048)
{
int *swap = (int *)SWAP_ADDRESS;
Erase_FLASH(swap);
Write_FLASH(app_1, swap);
Erase_FLASH(app_1);
Write_FLASH(app_2, app_1);
Erase_FLASH(app_2);
Write_FLASH(swap, app_2);
}
Lock_FLASH();
return TRUE;
}
void Unlock_FLASH(void)
{
while ((FLASH->SR & FLASH_SR_BSY) != 0 );
// Check if the controller is unlocked already
if ((FLASH->CR & FLASH_CR_LOCK) != 0 ){
// Write the first key
FLASH->KEYR = FLASH_FKEY1;
// Write the second key
FLASH->KEYR = FLASH_FKEY2;
}
}
void Erase_FLASH(int *c)
{
FLASH->CR |= FLASH_CR_PER; // Page erase operation
FLASH->ACR = c; // Set the address to the page to be written
FLASH->CR |= FLASH_CR_STRT;// Start the page erase
// Wait until page erase is done
while ((FLASH->SR & FLASH_SR_BSY) != 0);
// If the end of operation bit is set...
if ((FLASH->SR & FLASH_SR_EOP) != 0){
// Clear it, the operation was successful
FLASH->SR |= FLASH_SR_EOP;
}
//Otherwise there was an error
else{
// Manage the error cases
}
// Get out of page erase mode
FLASH->CR &= ~FLASH_CR_PER;
}
void Write_FLASH(int *a, int *b)
{
for(int i=1;i<=2048;i++,a++,b++)
{
FLASH->CR |= FLASH_CR_PG; // Programing mode
*(__IO uint16_t*)(b) = *a; // Write data
// Wait until the end of the operation
while ((FLASH->SR & FLASH_SR_BSY) != 0);
// If the end of operation bit is set...
if ((FLASH->SR & FLASH_SR_EOP) != 0){
// Clear it, the operation was successful
FLASH->SR |= FLASH_SR_EOP;
}
//Otherwise there was an error
else{
// Manage the error cases
}
}
FLASH->CR &= ~FLASH_CR_PG;
}
void Lock_FLASH(void)
{
FLASH->CR |= FLASH_CR_LOCK;
}
Here swap buffer is used to store each page(2KB) temporarily as a buffer while swapping. Also the variable limit stores the maximum size out of application 1 and 2 so that there is no error while swapping in case of unequal memory sizes as mentioned before. So basically I am swapping page by page, that is only 2 KB at a time.
Can anyone figure out whats wrong in the code?
Thanks,
Shetu
2K is 2048 bytes, not 2024. Fix the increments all over the code.
There is another restriction that at a time only 2KB of memory can be copied
and yet another, that these memory blocks must be aligned to 2KB.
This address
#define APPLICATION2_ADDRESS 0x08076400
is not properly aligned, it should have a value that is evenly divisible by 2048 (0x800).
I'm using STM32F407VG Discovery Board and I've issue with DMA memory to memory transfer. I want to copy 32 bytes of data from one place in memory to other using DMA by writing copy_dma() function. In while loop i'm checking Transfer Complete flag but DMA never returns it. I want to ask where i'm making mistake? Maybe something in configuration is wrong. I'm using Standart Peripheral Libraries. Here's my code.
#include "stm32f4xx.h"
#define BUFFER_SIZE 32
uint8_t src_buffer[BUFFER_SIZE];
uint8_t dst_buffer[BUFFER_SIZE];
void copy_dma(void);
int main(void)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
int i;
DMA_InitTypeDef dma;
DMA_DeInit(DMA1_Stream4);
DMA_StructInit(&dma);
dma.DMA_Channel = DMA_Channel_1;
dma.DMA_PeripheralBaseAddr = (uint32_t)src_buffer;
dma.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
dma.DMA_Memory0BaseAddr = (uint32_t)dst_buffer;
dma.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma.DMA_BufferSize = BUFFER_SIZE;
dma.DMA_DIR = DMA_DIR_MemoryToMemory;
dma.DMA_FIFOMode = DMA_FIFOMode_Disable;
dma.DMA_MemoryBurst = DMA_MemoryBurst_Single;
dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
dma.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
dma.DMA_Mode = DMA_Mode_Normal;
dma.DMA_Priority = DMA_Priority_High;
DMA_Init(DMA1_Stream4, &dma);
for (i = 0; i < BUFFER_SIZE; i++) {
src_buffer[i] = 100 + i;
}
copy_dma();
while(1) {
}
}
void copy_dma(void) {
DMA_Cmd(DMA1_Stream4, ENABLE);
while (DMA_GetFlagStatus(DMA1_Stream4, DMA_FLAG_TCIF4) == RESET);
}
In app note "Using the STM32F2 and STM32F4 DMA controller"(http://stm32.eefocus.com/download/index.php?act=down&id=6312)
is mentioned:
"Memory to memory (only DMA2 is able to do such transfer, in this mode, the circular and direct modes are not allowed.)"
So, try to use DMA2.
In addition to Mariusz Górka's awnser:
When using the DMA you need to know which memory region you are using. The stm32f4 has a memory section called Core Coupled Memory (CCM). The DMA does not have access to this region.
Check your map file and make sure your buffers are not in the region 0x10000000 - 0x1000FFFF.
I working with Keil, MDK-ARM Pro 4.71 for a Cortex-M3 target(STM32F107).
I have compiled the Lua interpreter and a Lua "timer" module that interfaces the chip's timers. I'd like to call a lua function when the timer is elapsed.
Here is a sample use :
t = timer.open()
t.event = function() print("Bing !") end
t:start()
Until here, everything works fine :-) ! I see the "Bing !" message being printed each time the timer elapses.
Now if I use a closure :
t = timer.open()
i = 0
t.event = function() i = i + 1; print(i); end
t:start()
I'm having a bad memory access in the GC after some amount of timer's updates. Since it's an embedded context with very few memory, I may be running out of memory quite fast if there is a leak.
Here is the "t.event" setter (ELIB_TIMER is a C structure representing my timer) :
static int ElibTimerSetEvent(lua_State* L)
{
ELIB_TIMER* pTimer_X = ElibCheckTimer(L, 1, TRUE);
if (pTimer_X->LuaFuncKey_i != LUA_REFNIL)
{
luaL_unref(L, LUA_REGISTRYINDEX, pTimer_X->LuaFuncKey_i);
pTimer_X->LuaFuncKey_i = LUA_REFNIL;
}
if (!lua_isnil(L, 2))
{
pTimer_X->LuaFuncKey_i = luaL_ref(L, LUA_REGISTRYINDEX);
}
return 0;
}
And here is the native callback implementation :
static void ElibTimerEventHandler(SYSEVT_HANDLE Event_H)
{
ELIB_TIMER* pTimer_X = (ELIB_TIMER*)SWLIB_SYSEVT_GetSideData(Event_H);
lua_State* L = pTimer_X->L;
int i = lua_gettop(L);
if (pTimer_X->LuaFuncKey_i != LUA_REFNIL)
{
lua_rawgeti(L, LUA_REGISTRYINDEX, pTimer_X->LuaFuncKey_i);
lua_call(L, 0, 0);
lua_settop(L, i);
}
}
This is synchronized externally, so this isn't a synchronization issue.
Am I doing something wrong ?
EDIT
Here is the callstack (with a lua_pcall instead of lua_call, but it is the same). The first line is my hard fault handler.
I have found the problem ! I ran out of stack (native stack, not Lua) space :p.
I guess this specific script was causing a particularly long call stack. After increasing the allocated memory for my native stack, the problem is gone. On the opposite, if I reduce it, I can't even initialize the interpreter.
Many thanks to those who tried to help here.
Found a bug in your C code. You broke the lua stack in static int ElibTimerSetEvent(lua_State* L)
luaL_ref will pop the value on the top of Lua stack: http://www.lua.org/manual/5.2/manual.html#luaL_ref
So you need to copy the value to be refed, before the call to luaL_ref:
lua_pushvalue(L, 2); // push the callback to stack top, and then it will be consumed by luaL_ref()
Please fix this and try again.
My pthread_detach calls fail with a "Bad file descriptor" error. The calls are in the destructor for my class and look like this -
if(pthread_detach(get_sensors) != 0)
printf("\ndetach on get_sensors failed with error %m", errno);
if(pthread_detach(get_real_velocity) != 0)
printf("\ndetach on get_real_velocity failed with error %m", errno);
I have only ever dealt with this error when using sockets. What could be causing this to happen in a pthread_detach call that I should look for? Or is it likely something in the thread callback that could be causing it? Just in case, the callbacks look like this -
void* Robot::get_real_velocity_thread(void* threadid) {
Robot* r = (Robot*)threadid;
r->get_real_velocity_thread_i();
}
inline void Robot::get_real_velocity_thread_i() {
while(1) {
usleep(14500);
sensor_packet temp = get_sensor_value(REQUESTED_VELOCITY);
real_velocity = temp.values[0];
if(temp.values[1] != -1)
real_velocity += temp.values[1];
} //end while
}
/*Callback for get sensors thread*/
void* Robot::get_sensors_thread(void* threadid) {
Robot* r = (Robot*)threadid;
r->get_sensors_thread_i();
} //END GETSENSORS_THREAD
inline void Robot::get_sensors_thread_i() {
while(1) {
usleep(14500);
if(sensorsstreaming) {
unsigned char receive;
int read = 0;
read = connection.PollComport(port, &receive, sizeof(unsigned char));
if((int)receive == 19) {
read = connection.PollComport(port, &receive, sizeof(unsigned char));
unsigned char rest[54];
read = connection.PollComport(port, rest, 54);
/* ***SET SENSOR VALUES*** */
//bump + wheel drop
sensor_values[0] = (int)rest[1];
sensor_values[1] = -1;
//wall
sensor_values[2] = (int)rest[2];
sensor_values[3] = -1;
...
...
lots more setting just like the two above
} //end if header == 19
} //end if sensors streaming
} //end while
} //END GET_SENSORS_THREAD_I
Thank you for any help.
The pthread_* functions return an error code; they do not set errno. (Well, they may of course, but not in any way that is documented.)
Your code should print the value returned by pthread_detach and print that.
Single Unix Spec documents two return values for this function: ESRCH (no thread by that ID was found) and EINVAL (the thread is not joinable).
Detaching threads in the destructor of an object seems silly. Firstly, if they are going to be detached eventually, why not just create them that way?
If there is any risk that the threads can use the object that is being destroyed, they need to be stopped, not detached. I.e. you somehow indicate to the threads that they should shut down, and then wait for them to reach some safe place after which they will not touch the object any more. pthread_join is useful for this.
Also, it is a little late to be doing that from the destructor. A destructor should only be run when the thread executing it is the only thread with a reference to that object. If threads are still using the object, then you're destroying it from under them.