Making the Most of Asserts
I record the backtrace and the precise program counter. That’s it. Nothing more. OK. Also a time stamp can be useful and maybe a couple of uintptr_t words the programmer can add to help debug.
Care needs to be taken as the optimizer will sweep all common code into one call to the assert utility, then you don’t know which of several asserts in a function fired! We ended up going with a gcc asm oneliner to get the precise PC.
My biggest problem with code that checks for malloc returning null and attempting to handle it…
…usually it is untested, buggy, and somewhere along the line uses malloc to do it’s job! (Guess what lurks in the depths of a printf?)
The next problem on a system with swap… these days your system is effectively dead/totally dysfunctional loong before malloc returns NULL!
The light weight IP stack uses pool allocators with quite small pools for resources that may have (potentially malicious) spikes in usage. But then you will find all over it the attitude “this is an IP packet, somethings wrong / I can handle it / I don’t know enough / I don’t have enough resources / …” I’ll just drop the packet. If it matters the higher layers will retry.
Another good pattern is to malloc everything you need for this configuration at initialization time … at least then you know then and there that that configuration will work… if you can’t, you reboot to a safe configuration.
When Not to Assert
Never assert on invalid input from users or external untrusted systems. If you do, you open yourself to denial of service attacks (and pissed off users).
Design by Contract
Please read and understand https://en.wikipedia.org/wiki/Design_by_contract
I regard DbC as the most important concepts in producing correct software, and has a lot to say about asserts.