malloc problem

21 Dec 2010

AFAIK malloc() is supposed to return NULL when it cannot allocate the memory. But according to my testing it just seems to crash. If have written a small program with allocates 4 block with 8k each - and it doesn't seem to return from the last call: http://mbed.org/users/hlipka/programs/malloc_test

#include "mbed.h"

#define MALLOC_SIZE 0x2000

DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);

int main() {
        led1=0;
        led2=0;
        led3=0;
        led4=0;
        malloc(MALLOC_SIZE);
        led1=1;
        malloc(MALLOC_SIZE);
        led2=1;
        malloc(MALLOC_SIZE);
        led3=1;
        malloc(MALLOC_SIZE);
        led4=1;
}

This makes it especially problematic to debug memory leaks (I suspect my code has one :(, since this nice library AvailableMemory doesn't work due to this...

21 Dec 2010

Hi Hendrik

I've just published my test program to go with the AvailableMemory library:

It works fine under the beta compiler, giving the following output:

Available memory (bytes to nearest 256) : 24064
Available memory (exact bytes) : 24156

I suggest you import the whole program in beta mode and test it to see if you get the same output.

Anybody not familiar with AvailableMemory, it is a nice function to do a binary search for space available:

Import libraryAvailableMemory

Function to calculate the memory available for malloc

Saludos
Segundo

21 Dec 2010

Replace the main.cpp hello world example above with the following code:

#include "mbed.h"
#include "AvailableMemory.h"
DigitalOut led1(LED1);

#define MALLOC_SIZE 0x2000

int main() {

    led1 = 0;

    printf("Available memory (exact bytes) : %x\n", AvailableMemory(1));
    malloc(MALLOC_SIZE);
    printf("Available memory (exact bytes) : %x\n", AvailableMemory(1));
    malloc(MALLOC_SIZE);
    printf("Available memory (exact bytes) : %x\n", AvailableMemory(1));
    malloc(MALLOC_SIZE);
    printf("Available memory (exact bytes) : %x\n", AvailableMemory(1));
    malloc(MALLOC_SIZE);
    printf("Available memory (exact bytes) : %x\n", AvailableMemory(1));
        
    led1 = 1;
}

The result is:

Available memory (exact bytes) : 5e74
Available memory (exact bytes) : 3e24
Available memory (exact bytes) : 1e1c
Available memory (exact bytes) : 1e1c
Available memory (exact bytes) : 1e1c
21 Dec 2010

Both of your examples work (even without beta mode). But when I change your second example to:

#include "mbed.h"
#include "AvailableMemory.h"
DigitalOut led1(LED1);
DigitalOut led2(LED2);

#define MALLOC_SIZE 0x2000

int main() {

    led1 = 0;
    led2 = 0;

    printf("Available memory (exact bytes) : %x\n", AvailableMemory(1));
    malloc(MALLOC_SIZE);
    led2=1;
    printf("Available memory (exact bytes) : %x\n", AvailableMemory(1));
    malloc(MALLOC_SIZE);
    printf("Available memory (exact bytes) : %x\n", AvailableMemory(1));
    malloc(MALLOC_SIZE);
    printf("Available memory (exact bytes) : %x\n", AvailableMemory(1));
    malloc(MALLOC_SIZE);
    printf("Available memory (exact bytes) : %x\n", AvailableMemory(1));
        
    led1 = 1;
}

it stops working...

21 Dec 2010

Hi Hendrik

The difference between my test code and yours is the number of DigitalOut objects that are declared! With more than one, it doesn't want to play.

If you add a hard fault handler to your original code, you'll see that it is thrown on the final malloc:

extern "C" void HardFault_Handler() { printf("Hard Fault!\n"); while(1); }
doing malloc 1
doing malloc 2
doing malloc 3
doing malloc 4
Hard Fault!

mbed team required

Definitely not the desired behaviour! Hello mbed team, can you have a look at this?

21 Dec 2010

Previous discussion on this topic: http://mbed.org/forum/mbed/topic/433/

21 Dec 2010

Segundo Equipo wrote:

The difference between my test code and yours is the number of DigitalOut objects that are declared! With more than one, it doesn't want to play.

Actually it's even more complicated. The code I pasted originally (on top) works correctly - but if I add a printf() at the end it stops working. So the error condition is having printf() and more than one DigitalOut object defined.

I hope that this is enough to ease finding this...

22 Dec 2010

Hi Hendrik,

Thanks for the report. I was under the impression that this had been fixed in the beta compiler and latest libraries. Your report suggests not, so I'll reopen the ticket.

Please be aware we're planning some time off during Christmas, so it won't be an immediate fix :) Merry Christmas everyone!

Thanks, Simon

22 Dec 2010

I have an additional problem which might be related, but is much more severe: http://mbed.org/cookbook/NetServices#c548 . In that case, some networking calls eat up nearly all available memory (less than 240 bytes left).

I suspect it's not really an issue of the compiler itself, but one of the standard library.

22 Dec 2010

Simon Ford wrote:

Please be aware we're planning some time off during Christmas, so it won't be an immediate fix :) Merry Christmas everyone!

Yeah, I have some time off for myself :)

I hope I can find some workarounds for my out-of-memory problems, since they really stay in the way of my work...

Merry Christmas!

01 Jan 2011

Simon Ford wrote:

Thanks for the report. I was under the impression that this had been fixed in the beta compiler and latest libraries. Your report suggests not, so I'll reopen the ticket.

The real culprit here might not be the compiler itself. I can trace the error to using multiple instances of the mbed Base class. When there is more than one instance of this class (or a class derived from it), the error occurs. See the latest version of my test program above for a simple test case.

Judging from the headers, the base class does some internal registration / book keeping, this functionality might interfere with the memory handling.

20 Jan 2011

Hi Hendrik,

We've been investigating this. Thanks for the program example around Base. It is an example that demonstrates a problem, but actually has nothing to do with Base specifically. I derived a similar example without inheriting from Base that can produce the same problem, and it simply the face that adding things can change the memory requirements/layout.

We'll investigate further below the mbed libraries, and track this down...

Simon

25 Jan 2011

Hi Hendrik, All,

We've just posted a new library version (27) and a patch to the compiler; this should fix these out-of-memory malloc faulting problem you've seen. The program you provided now has the expected behaviour; the first 3 mallocs succeed, and the fourth returns NULL.

To get the new version of the mbed library, just select the mbed library in your program and click "Update to latest version"; it should pull in library version 27, and malloc should no longer cause problems. If you do have further problems, please get back to us.

Thanks, Simon

25 Jan 2011

It works not for all of my test cases. My NTP test case still hangs on malloc. Whats interesting here is that the problem only occurs when the NTP client receives an answer - when I yank out the network cable directly after the network setup, everything is OK. The program also works when using NetServicesMin+NTPClientMin.

For all other programs it works. It also fixes the PWM / floating point problem, and seems to fix most of the other mysterious crashes I have seen (though I have not tested all my programs).

06 Mar 2011

Hendrik Lipka wrote:

The program also works when using NetServicesMin+NTPClientMin.

Hi Hendrik

Could you publish the whole program which works with your cut down libraries? I'd like to look at why they work and the full library doesn't. Can you also let me know if there was a specific solution to the memory leak in the NTP service, or was it just a case of taking out the inheritance from NetService?

Thanks
Daniel

06 Mar 2011

The program is published here (in the version with the normal NetServices library). What you should see is at the end the program tries to find out the available memory, but fails when trying to allocate 240 bytes (not with an error, it just stops).

When you replace NetServices with NetServiceMin+NtpClientMin, it works (at least it did when I checked last time). AFAIR it is just this program which mis-behaves, in my main program NetServices worked fine.

As for the memory leak, I'm not sure what the solution was. But I'm using NetServicesMin and NTPClientMin since it compiles faster, so I'm not sure whether it did go away with the newer mbed version or only when I removed the inheritance (I surely did nothing else).

18 Oct 2011

I have an apparent malloc problem. I have a software that stores data via malloc, prints it out and then frees the memory. The problem is that the software does not crash during malloc, but during reading from the dynamic table via print functions. I suspect malloc and printf/fprintf form a tag team to crash mbed.

The strangest thing is that if I hard reset mbed (plug it off from USB), the software works fine on the first run. On second try it crashes. So it seems that mbed does not run out of memory, but the heap is not free'd correctly. The reset by reset button does not fix the problem; it always requires hard reset.

Any solution?

18 Oct 2011

Hi

Have a look at http://mbed.org/forum/mbed/post/13857/

The code there should allow you (to write code) to check if memory can be allocated as it returns the largest free block on the heap without using malloc.

As it dumps the heap it has none of the malloc problems.

Btw Juho, Your problems seems like printf tries to allocate additional memory on an almost full heap during it's operations.

wvd_vegt

20 Oct 2011

The problem is deeper than just simple stack/heap conflict. The software reads scripts to the heap, prints and releases the memory. The strangest thing is that even if the script loaded is really small (e.g. you could run scripts hundreds of times bigger than that), the software almost definetly crashes on second run.

It seems like it's not dependent on the size of the heap at all, but the memory area gets fragmented eventhough there shouldn't be anything left in the heap because every allocation is freed. I'm really baffled. I suspect that either printf/fprintf does something unexcpected or malloc/free malfunctions.

20 Oct 2011

Hi Juho

If you adept/run the code from the postin i mention you can see how fragmented the heap becomes and if it's corrupted.

I do not have output at hand but it really is handy when investigating heap problems.

wvd_vegt

20 Oct 2011

Hi Joho,

Your problem could actually be you are just being lucky on the first run that your program is not crashing! e.g. on powerup, the RAM is in a somewhat more predictable state, and it could be something like an uninitialised pointer, a non-null terminated string being passed to printf, writing off the end of an array etc which lucks out on your first run because the memory is in one state, but in subsequent runs has been modified.

Can you share a small example that other people can run that demonstrates the problem?

Simon

28 Jun 2012

I just ran into the same or similar issue with the LPC11U24 version, using mbed lib version 40 (beta). When I clal malloc with a very large value, it returns a non-zero value, so my program keeps on chugging along, but with some very odd behavior. I have put in code to check for an alloc greater than some amount (4K for now), but it would be nice if the compiler/library handled this for us.

Thanks, Tyler