2021-09-01 04:30 AM
I'm using an STM32F767ZI, and am programming it in C without any additional libraries (bare metal).
I believe there is a memory leak somewhere as a memory allocation that typically would work seems to fail after the program has been running for some time.
I'm familiar with tools such as dmalloc and valgrind, however an embedded environment is (obviously) very different and adds complications.
Are there any reliable tools, similar to the two named above, which could help me to track down memory leaks? Since the system is intended to run indefinitely, it would be preferable if the tool offered functions which can be called from within GDB in order to analyse the currently allocated memory.
If not, what is the best way to go about making something like this myself which can give useful info about where exactly the memory was allocated?
From searching around, I've come across a variety of (unhelpful for my use-case) answers, including suggesting that dynamically allocated memory should be entirely avoided? My system makes HTTP requests, parses them as well as the JSON body, then extracts a value at a specific key. It would be nice to avoid dynamically allocated memory if possible, so is there any way to go about it for something like this? Clearly the issue is that the HTTP response size is unknown, as well as the JSON body.
For reference, here is the link to the HTTP parser I've written: https://github.com/Starman3787/http
And this is a link to the code on the embedded system, if it helps (the HTTP parser used here is essentially the same, although slightly modified to work on an embedded system and reading the response over UART): https://github.com/Starman3787/btc-split-flap/tree/dev/software_v2
Solved! Go to Solution.
2021-09-01 05:14 AM
Personally I've managed to avoid Alloc in most of my designs specifically because it is difficult to ensure equipment will keep working after a long unsupervised time.
Some suggestions/options:
Paul
2021-09-01 05:14 AM
Personally I've managed to avoid Alloc in most of my designs specifically because it is difficult to ensure equipment will keep working after a long unsupervised time.
Some suggestions/options:
Paul
2021-09-01 05:49 AM
Walk the allocation list, monitoring for fragmentation.
Add a light wrapping of malloc/free to find who is responsible for orphans or double releases, etc.
2021-09-01 06:18 AM
Thanks for the helpful response.
I didn't consider that it might be related to memory fragmentation, however this seems likely to be one of the contributing factors as from my tests, the program stopped when calling "realloc()" in order to increase the size of the allocated memory.
Defragging sounds like it would add lots of complexity, and cause more potential for bugs. I think half my problem is not free'ing up memory which needs to be free'd up (due to too much complexity already), leading to a reduced amount of memory available and therefore defragmentation preventing any further allocations. Defragging won't make it any easier to prevent memory from being lost by not being free'd (unless there is some tool which can tell me what has and hasn't been free'd, which there doesn't seem to be).
Alloc'ing in fixed size sectors is probably quite reasonable for me to do, especially since the data received over UART seems to be sent in fixed chunks of a size of up to 1460 IIRC, so it shouldn't be too hard to base the allocation sizes around that.
However, from thinking this through further, I'm wondering this:
For a simple application like this where I only actually need a single value at a certain key from the JSON, does it even make sense to store the entire parsed response, or is it just overkill? Do you think it would be a better idea to: receive the chunks and put them into blocks of a fixed size of 1460 => parse the headers and check the response status etc. => parse the JSON until the required key is found, store and return the value of that and discard everything else (by free'ing up the chunks)? Perhaps I just added a lot of unneeded complexity before? Would be good to get your thoughts on this.
Thanks again.
2021-09-01 06:23 AM
What do you mean by "walk the allocation list"? How can I do this?
2021-09-01 06:23 AM
2021-09-01 06:42 AM
64K wow, it's amazing that programs used to run with so few resources. It makes sense not to store data that will never be used, so I'll probably opt for storing as little as I can.
How big should this array be? I'll need to check how many chunks of data usually seem to be sent over the UART for each response (I hope the number is similar each time) but if not, how is a situation where there are more chunks than are available handled?
2021-09-01 06:47 AM
Allocators typically use a linked-list construct ahead of the location they return to you. https://en.wikipedia.org/wiki/Linked_list
You can also hide data ahead of the address passed to the application code.
2021-09-01 07:13 AM
oh i see
how can i access this linked list? i'm using arm-none-eabi-gcc to compile this, where can i find the location of this list?
2021-09-01 07:18 AM
You have to design the system to handle the needs, or slow things down when getting near full. I expect you'll need to analyze the messages you support to determine how many to reserve for each. If you run out of space then you may be able to handle the same way you would handle a corrupt message? (i.e. discard and wait for a retry? Send a NAK/Fail?)