Home > On-Demand Archives > Q&A Sessions >
Live Q&A - The Best Defense is Offensive Programming
Tyler Hoffman - Watch Now - EOC 2021 - Duration: 20:07
Thanks for a great talk. Which pressure sensor gave you problems at higher altitudes? I'm looking at BMP390 and a couple others...
Assuming you use malloc_assert() of times, would it be more efficient to make it into a macro, that would be replaced at compile time, than jumping to the function in runtime?
That's a good idea! I'm generally against macros that hide or change functionality and don't mind the extra function call in most cases. You could consider forcing inlining through your compiler options which would have the same benefit but not be a macro.
Very good talk. I am also a fan of these offensive programming techniques. It may sound strange, but have you had to defend the offense; have you had to worry about offensive programming techniques in a critical application scenario. An example would be life support systems, or maybe autonomous driving systems. The reset is not, or less tolerable in these applications. Are there other offensive programming techniques (not hardware based) you would use here?
Personally, I need to dig in more myself and understand what is and isn't allowed in certain types of firmware / devices. I'd argue that letting a firmware continue to run with bugs occurring / corruption / undefined behavior is much, much worse than just resetting the system, especially if the device reboots on the order of milliseconds and can pick up from where it left off on boot.
We talked a little about recovering from faults without resetting the MCU in this Interrupt blog post: https://interrupt.memfault.com/blog/cortex-m-fault-debug#recovering-from-a-fault
I think for critical sections, it's probably OK to lessen the severity of the asserts and make them high-priority logs, but just make sure to track them! Understand why they are still being hit, aggregate and count them, and understand why they are happening. When testing internally, do escalate the issue and really dig into why it's happening.
Bug Report: @ 22 minutes
if (!name|| name_len > 32)
You said if name length is too small it is bad, but this looks to see if the length is too big
Awesome discussion Tyler! Thank you.
16:41:52 From Michael Kirkhart : Avoiding bootloops may be difficult if you have asserts in low level (hardware interface) functions which are used both during initialization and during normal runtime. 16:42:22 From Leandro Pérez : Hi everyone from Colombia 16:43:13 From Leandro Pérez : Yes I too...lol 16:43:32 From Rocco Brandi : I have run the video at 1.25x 16:44:00 From Leandro Pérez : Me too... lol 16:44:15 From Keith J : Changing my thought process as well.... interesting tie in with Steve's keynote and using asserts in production code to allow discovery of root cause of issues 16:44:48 From Rob Meades : I used to follow this approach but what changed my mind was being in the position of being a technology supplier to someone else: the customer hated the idea of code written by a third party calling assert() of _any_ kind. They fixed it by re-stubbing every assert call through to their logging system of course. Maybe the answer is to form an API of your offensive mechanisms. 16:44:48 From Leandro Pérez : I believe that I understand for why reason there are many ASSERT in AWS FreeRTOS 16:45:40 From Mark : Hey Tyler, thanks for the talk. What are your thoughts on having an overall system status that gets passed throughout the software and most functions use the common status? Some industrial devices use the HART communication protocol and have a HART status that's output to the user. I've seen the HART status used in low level functions where if the sensor reading fails, then a HART status is set to something like "Primary Variable Unavailable" and then that gets passed up to the user eventually. 16:45:59 From jvillasante : I think asserting in application code it’s kind of fine if you can swallow that, but in library code it is not. 16:46:31 From Raul Pando : Tyler, something I haven't quiet understood is when there is an assertion that causes a reset to the MCU, how is the context dumped into a core for later inspection, is that done during boot? process? 16:46:46 From Leandro Pérez : yes... lol 16:46:51 From Michael Kirkhart : Shall remain shameless? 16:47:33 From Michael Kirkhart : That goes for any ARM CPU 16:47:36 From Sam : Offensive programming feels like TDD (test driven dev)...true? 16:49:22 From Raul Pando : Thanks 16:52:14 From patelk5 : I work in the medical industry, is offensive programming such a good idea in production environment where failure has real consequences? 16:53:57 From Nathan Jones : Great talk, Tyler! What's your take on including redundant asserts, such as asserting a parameter at each step in the call stack? I'm inclined to keep them in (to mostly protect against myself!), but I've read from some people that there's no need. 16:54:22 From Nathan Jones : I mean, clearly there's no need. But maybe it's still a "good practice". 16:56:39 From Keith J : @patelk5 - also medical industry here - you can still use assert to log and report while recovering... don't you want to know there is an issue? 16:57:06 From Sam : thx 16:57:12 From Erwin : @patelk5: What causes your device to have undefined behaviour will potentiall cause harm so at least you can assure sdafe state! 16:57:14 From Bruce Lueckenhoff : Offensive programming seems very reminiscent of "Design By Contract" -- in addition to assert, DBC has additional concepts: pre-conditions, post-conditions, and invariants. Could you please compare Offensive Programming to Design-By-Contract. 16:57:58 From Nathan Jones : Thanks! 16:58:06 From Leandro Pérez : I remember the "Token" approach in my first C implementation before and after to call a method... it was in 2006 16:59:04 From patelk5 : @keith J thanks for response. I am just curious about a system like an operating table. If you reset the system during surgery, the table would be unusable. Logs would still be useful, but wouldn't it be good to keep the system going? 16:59:33 From Leandro Pérez : Thanks Tyler... Many changes for apply 16:59:33 From Leandro Pérez : lol 16:59:39 From Keith J : Thanks Tyler! 16:59:41 From patelk5 : Thanks Tyler! 16:59:43 From Charles Miller : 3pm meeting..gotta bail..THANK YOU Tyler. 16:59:44 From Christopher Long : Thank you Tyler! Great talk. 16:59:45 From Tyler Gilbert : Good job Tyler! 16:59:46 From Matt Liberty : Thanks Tyler! 16:59:47 From Bruce Lueckenhoff : Thanks Tyler! 17:00:01 From David : Thanks Tyler! 17:00:10 From Agnes B : Thanks Tyler 17:00:35 From Will Hsiung : Thanks Tyler for your talk and Q&A 17:00:44 From Sam : thank you 17:00:51 From javi : I'm on it and it looks great! 17:00:57 From javi : thanks Tyler 17:01:16 From Leandro Pérez : bye
Hi Tyler, the talk and Q&A was very interesting and definitely worthy of being included at the conference, IMHO. I tend to be the only one in my team using assert occasionally, but I?ll try now to sprinkle much more in! What I?ve seen a lot in my career is that a function/method provides a return code, but then it?s often never checked by the caller somewhere in the middle of the stack, effectively swallowing the error. I guess that?s why exceptions make sense in the non-embedded world, as they?re harder to ignore. Different people writing their bit of the code often have their own coding style, such as return bool, -1 or an enum, so there?s often a proliferation of different statuses all meaning the same thing, but often the meaning gets lost like a game of Chinese whispers going up the stack. I often return a bool ok, as it?s human readable what it means and easy to logical AND to daisy chain several. But yes, fail faster with asserts and fix the code , so it doesn?t happen again is best. Thanks again!