1

Following How do I create a module in MISRAC:2012 that follows Dir 4.12 and 4.8? discussion. I fail to see how memory pools are MISRA C Dir 4.12 compliant.

If we read the directive 4.12 it is said that dynamic memory usage shall not be used to avoid undefined behavior as specified in rule 21.3 that enumerates the following failure modes, amongst other, as examples:

  • Accessing allocate memory before storing a value into it.
  • A pointer to freed memory is used in any way.

Later on, directive 4.12 says that "If a decision is made to use dynamic memory" (and I read here "deviation") "care shall be taken that ensures software behaves in a predictable manner".

In the mentioned previous thread, @Lundin answer completly ignores the undefined behavior risk and just focuses on the deterministic behavior of a memory pool implementation compared to a malloc/free implementation, which it seems to me is the deviation path, no the rule itself. The rule, as it is written, it is said to prevent bad application usage of dynamically allocated/freed memory by the application leading to undefined behavior.

Finally, even if the stack is dynamic, the protocol to access it is totally controlled by the compiler, so I would say it cannot be compared to memory pools or any othe dynamic memory allocation mechanism in terms of reliability.

It looks to me that MISRA C rationale on Dir 4.12 warns about the risk of the dynamic memory protocol itself to lend to undefined behavior when accessing memory. Confusingly enough, then it says that if you decide to use dynamic memory you should be aware of the deterministic behavior of allocations, which is another orthogonal matter.

MISRA C mixes, for example, "accessing to a freed pointer" (the problem said to be prevented) with deterministic behavior of allocation/deallocation (the other problem said to prevent if you use dynamic memory).

My interpretation is that if you want your software to be realiable you should control both. So maybe the most appropiate would be to:

  1. Evaluate if dynamic memory is really needed
  2. If so, deviate the rule and stablish controls to prevent both: application access errors and undeterministic allocation/deallocation behavior.
  • one possible motivation is that with a pool you know exactly how many objects are used, while `malloc` may fragment memory in an unpredictable manner – user253751 May 15 '23 at 15:12
  • Can you explain more fully what undefined behavior risk you claim Lundin's answer ignores? As far as I can see, none of the specifics enumerated in rule 21.3 apply to the approach he described. – John Bollinger May 15 '23 at 16:42
  • More generally, are you actually asking a question here? If so, what is it? This is a Q&A site, not a discussion forum. – John Bollinger May 15 '23 at 16:45
  • @JohnBollinger I already did in the post "Accessing allocate memory before storing a value into it" and "A pointer to freed memory is used in any way" are both undefined behaviours that can happen with a memory pool solution. About whether it is a question, a comment or an answer, I would say I have a legitimate question about "whether memory pools are legit in MISRA C Dir 4.12 eyes or if they should require a deviation" but I am afraid I formulated it more like an answer to previous Lundin post, but just because it was easier tome to formulate the question will all previous context. – Carlos Marsal Castillero May 16 '23 at 16:27
  • @user253751 There are a lot of arguments in favour of memory pools vs malloc/free as the first has much fewer failure modes so it is much more easy to make reliable software. Lundin does already an excellent job listing them in his post. The question is not about which memory management strategy is less error-prone, but whether using memory pools should trigger a MISRA C deviation or not. – Carlos Marsal Castillero May 16 '23 at 17:10
  • @CarlosMarsalCastillero, it is fine your question to arise from a different one, and fine for it to reference that or any other, but it still has to actually *be* a question in its own right. And it is not clear from reading *this* question what it is actually asking. If you mean to ask whether memory pools are legit with respect to MISRA C, then great, but *put that in the question*. This is how why know what to address in an answer. – John Bollinger May 16 '23 at 17:12

1 Answers1

0

First of all, we have to realize that MISRA-C, being a technical document meant to be read by C programmers, places the same technical meaning into dynamic allocation as the C language does. It refers to data with allocated storage duration as defined by ISO C, or if you will allocation using "the heap" or "the freestore". So dynamic allocation doesn't just mean "some arbitrary memory that changes allocated size in run-time" (like for example the stack also does).

Second, we have to realize that MISRA C didn't come up with this ban alone but also inherited it from standards for functional safety (IEC 61508 and ISO 26262), standards for aviation software (DO-178 and the Joint Strike Fighter standards) and so on. All of which ban dynamic allocation.

The MISRA C directive just mentions a few of the problems related to dynamic allocation and not the biggest ones either. Overall the MISRA C document isn't very good or consistent with listing rationales and sources. In this specific case I don't think they even bothered to flesh out the document's rationale, since there are many more problematic things not mentioned.

I have written a more detailed and complete explanation of all the problems associated with these functions: Why should I not use dynamic memory allocation in embedded systems? Note that this is not just aimed to safety-related embedded systems but to all embedded systems.

The major arguments in that list isn't really the "dynamicness" nor the usual problems related to "dangling pointers" and memory leaks. The major arguments against it from that linked post is that it is slow, it is memory consuming, it is bloat and all for no good reason. All in all 13 solid arguments why it shouldn't be used and 0 arguments why it should be used.

In terms of undefined behavior specifically, apart what was already mentioned by MISRA, my post also addresses a few aspects not mentioned: indeterminate values and the effective type system, each which have lots of controversy, ISO C Defect Reports and generally poorly-specified behavior. In addition, my post also mentions the bad API of the standard C functions - malloc/realloc come with several very well-known bugs.

I really doubt that anyone with a bit of understanding how heap allocation works 1) in general 2) on a microcontroller, can ever "evaluate if dynamic memory is really needed" and come to any other conclusion than that using it on a (bare metal/RTOS) microcontroller system is senseless.

As for using statically allocated memory pools, they dodge pretty much all of the mentioned problems. Sure, they can also run into problems with effective type/strict aliasing just like malloc but that is about it. The advantage of rolling out your own static pool is that it's simple: it barely has any overhead, it gives as easy overview of how much memory that is allocated at any point in time, it doesn't fragment, it is contiguous and cache-friendly.

The question you link to is specifically about how to allocate opaque types (encouraged by MISRA Dir 4.8), as the OP there says "I am looking for guidance on Dir 4.8", in a MISRA-compliant system. So that's what my answer focused on, not about the MISRA UB rationale for Dir 4.12. An answer for how to implement such memory pools/opaque type allocators in practice can be found here.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Your reliability comparison of "heap/free storage/malloc/free" vs memory pools is totally spot on and very welcomed. However, my question is more about whether memory pools are legit in MISRA C or if they should trigger a deviation. If your argument about MISRA C dynamic memory being ISO C "allocated storage" were to be true the question could be closed. However, MISRA C says "This rule applies to [...] The Standard Library, and Third-party packages" and "*for convenience*, these examples are based around the use of The Standard Library dynamic memory", as if referring to something broader. – Carlos Marsal Castillero May 16 '23 at 17:05
  • Even though it is not clear to me whether the answer settles whether memory pools are MISRA C Dir 4.12 compliant or not, I think there is enough information for anybody to make a decision on whether to use them or not in their code and whether to create a deviation for Rule 4.12 or not. I am afraid that the lack of definition of dynamic memory in the MISRA C text cannot be fixed. – Carlos Marsal Castillero May 16 '23 at 17:18
  • @CarlosMarsalCastillero The MISRA directive is quite clear and not the slightly ambiguous here. It uses common terms well-known to all C programmers. Illustrated with examples containing malloc and free, which are part of the standard library. "The standard library" is a formal term and refers to everything mentioned in chapter 7 of ISO C 9899. Whereas "Third-party packages" refers to things like strdup/getline etc. – Lundin May 16 '23 at 17:52
  • @CarlosMarsalCastillero - as Lundin states, the Directive is quite unambiguous... any use of dynamic memory allocation is a violation of D.4.12. The C Standard Library functions are fundamentally broken, while use of any third party code is undecidable from an analysis viewpoint. Should you wish to use dynamic memory allocation, whether by using STDLIB or otherwise, you have the option of a deviation. Statically defined memory pools are fine... – Andrew May 19 '23 at 12:32
  • PS: MISRA C is a live document... if you have suggestions for improvements etc were all ears :-) – Andrew May 19 '23 at 13:14
  • @Andrew Is there a consolidated version with all amendments though? Because first paying for the main document and then dig through some 4+ amendments isn't a great experience... – Lundin May 19 '23 at 21:19
  • You mean MISRA C:2023? https://www.misra.org.uk/misra-c2023-released/ – Andrew May 20 '23 at 07:26
  • We're moving to PDF and Print on Demand in future, so hopefully, less need for amendments - just straight to new editions/revisions – Andrew May 20 '23 at 07:27
  • Let me explain. The ambiguity, as I see it, comes into play when it says "STDLIB memory allocation and deallocation routines can lead to UB. Any other memory allocation system is likely to exhibit UBs that are similar". Then in rule 21.3 one of the examples says "A pointer to freed memory is used". If I have a memory pool implementation that features deallocation, couldn't the same UB happen? Then, I interpret that MISRA C is not warning about a specific runtime allocation scheme, but anything that defines a variable address at runtime (non-static, non-global) and programmatically (non-auto). – Carlos Marsal Castillero May 20 '23 at 15:14
  • 1
    @Andrew Hah ok I hadn't heard of that yet. I was digging through all the amendment not long ago at all. Nice work, I'll get a copy of that :) – Lundin May 20 '23 at 17:46
  • @CarlosMarsalCastillero Why would you implement deallocation on a MCU system though? That likely doesn't make any sense to have. And as I already said, the MISRA rationale could be improved a lot, it's not focusing on the main problems with dynamic allocation, just the most obvious ones. Although there are some specific things with free() specifically that renders a memory location "indeterminate" which the compiler can abuse during optimizations, [see this](https://stackoverflow.com/questions/75533693/clang-15-miscompiles-code-accessing-indeterminate-values). – Lundin May 20 '23 at 17:55
  • @CarlosMarsalCastillero If you roll out a manual static allocation memory pool with deallocation, then the values it had before you declared a cell not used are guaranteed to be preserved. And there will be no weird optimizations as can happen with malloc/free. Also as seen by the defect reports in that link I posted, this is a weakly specificed part of C and there's no consensus within the ISO C working group and the mainstream compilers. – Lundin May 20 '23 at 17:57
  • You really do need to join the MISRA C WG, Lundin :-) – Andrew May 22 '23 at 08:06
  • @Andrew I did participate in the 2012 review. But alas I'm just a MISRA C "power user", my current job doesn't really leave enough time to participate in standardization. – Lundin May 22 '23 at 08:17
  • @Lundin I didn't know that free rendered a memory location indeterminate, it is good to know. About deallocating something dynamically allocated I guess it depends on the usage. For a GUI framework that wants to reuse memory used by screen widgets, it could make sense when switching screens. I see, however, the point here. MISRA C is just an ISO C subset and as such is concerned with _undefined_ and _implementation defined_ behaviour. Maybe it does not make sense to interpret it outside this scope, and as such my interpretation of dynamic memory outside ISO C just does not make sense. – Carlos Marsal Castillero May 30 '23 at 17:11