Fixing “REENT malloc succeeded” Assertion

One little nasty assertion in the GNU standard library appeared a few days ago, kind out of nowhere, reporting “REENT malloc succeeded”:

Obviously it was caused by the call to srand() which sets the ‘seed’ for the standard library (pseudo) random number generator. The assertion happens as well later for calling the rand() function.

The random numbers are used for a little ‘asteroids’ game used in one of my classes (“Advanced Embedded Systems”):

Interestingly, the assertion for srand() occurred only in a few projects, but not in others. In my case I used NewLib-nano with as in MCUXpresso 11.6.x.

There were several reports in different forums about this assert and message, but none of the proposed solutions did make sense to me

“try to add this line of code “srand(time(NULL));” before calling rand() function, it worked for me.” (link)

nor worked in my case.

But some more investigations turned out that it has to do something with memory allocation, more precise with the heap and malloc().

And indeed, the projects which failed had the heap size set to zero (see “How to make sure no Dynamic Memory is used“):

Changing that to >0 (e.g. 1 KByte), and the assertion disappeared :-).

With this I have a workaround, but I’m still worried by the fact that the library random number generator needs some heap memory.

But in case you encounter the same assertion, I hope this article helps you out.

Happy de-asserting 🙂

Links

19 thoughts on “Fixing “REENT malloc succeeded” Assertion

  1. And well you should worry about it. Defects involving dynamically allocated memory tend not so much to fail, as to go down in flames. Although I will use it in my own tools, I would never inflict it on one of my embedded customers.

    Thanks for the warning!

    Like

    • Hi Gary,
      yes, dynamic memory allocation is always something to be concerned about. printf() in newlib (at least in some versions) require dynamic memory allocation too. But it was new to me for srand() and rand(), so I learned (again) something new.

      Like

  2. Agree you should be worried. Basically a recipe for disaster, especially if combined with multitasking, where this can lead to crashes. NXP use use a professional Runtime library such as SEGGER’s emRun MCUXpresso and get rid of this nasty problem

    Like

  3. Should read something like “IMHO, NXP should use a professional Runtime library such as SEGGER’s emRun in MCUXpresso”. I should not post before fully waking up I guess…

    Like

    • Lots of coffee helps in my case :-). I agree. The GNU standard library is not the best solution for everyone. This is why I avoid printf (https://mcuoneclipse.com/2013/04/19/why-i-dont-like-printf/) and other functions of the Standard C/C++ library. Instead, we are using for most of our projects are own ‘standard’ library which covers the needed functions. Well, we did not think about srand() and rand(), so I guess we will end up with our own implementation for it too 😉

      Like

  4. It looks to me that dynamic memory allocation is used because the heap pointer’s address is essentially random for each malloc() call, so this enables the RNG algorithm to generate a quasi-random seed.

    Like

  5. I ran into that too. They did a terrible thing. Which is trying to ‘fix’ the problem that rand() isn’t re-entrant by playing hack games with malloc().

    Like

    • I see that they would use malloc as an extra kind of random source, but they could have used the stack pointer for it too. I guess I have to look for a different way to generate pseudo-random values in the future.

      Like

      • Erich,

        Back in the days of ubiquitous pocket calculators, the HP-45 had a built-in random number generator. It worked by running an auto-reloadable, 1 MHz counter over the range of numbers. It captured the counter content whenever the user pressed a key. Perhaps that algorithm could be molded into something useful here.

        Like

        • I’m doing similar things to get a random number seed, like waiting for the user to press a key and then use the number of milliseconds as a random number base. Or reading things like task stack pointer from other tasks, or using the on-chip temperature sensor value.

          Like

      • My feeling is rand() historically is not thread safe and comes with no guarantee’s at all. That is not something that anyone should try to ‘fix’ because you aren’t going to fix broken programs that way.

        Side note: I think the era where people think it’s a great idea to allocate memory via unmanaged inline calls to malloc() and free() is drawing to a rapid close.

        Like

        • I don’t get it why rand() could not be implemented in a thread-safe way from the start. It is a pseudo-random number anyway, so getting entropy sources like stack pointer, program counter or other registers into account does not need any global storage. Or I’m making it too simple?

          Like

        • I can’t reply directly to your response but. I think it’s part of the toxic culture around the C language and the standard library’s where no one is allowed to add anything to fix important stuff[1]. But of course you can ‘fix’ stuff that isn’t broken like rand() which is what it is.

          Myself for random numbers on interrupts I shift and xor the system timer and other randomish data into an accumulator and then hash it.

          [1] Like how for 25 years they refuse to add an actual safe string and memory copy functions. Like they think any replacement needs to be safer but of course not too safe.

          Like

        • Not sure if can be named ‘toxic’, my feeling is that the library folks are very conservative, and my feeling is that they are not developing real world safety critical applications.
          This is why at the university we added our own ‘safe’ and reentrant string routines, simply to overcome these problems. That whole rand() thing reassured my mantra “do not use the standard library”, I should have known better.
          While the C standard library has been very conservative, my feeling the C++ one has been gone overboard with all the functionality. There has been discussions using Rust for a while, and certainly it gets momentum, and that language helps writing better code. But my feeling is that it is not the bad programming language (or library) which causes issues, but bad programmers.

          Like

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.