5 ms·
Assertions should be more debugger-oriented
- mhh__ 4y agoD has a feature which makes the compiler serialize the assert-ed expression into a format string so the runtime values can be printed contextually.
- mike_hearn 4y agoThis is usually called Power Assertions and other languages have them too. Groovy has it, and there's a compiler plugin for Kotlin that adds it. It's very useful and avoids the need to write assertion messages most of the time, whilst still letting you get useful outputs. The article seems to ignore all this, in fact, it argues other languages are even worse than C because assertion failures are exceptions. That seems dubious. In JVM languages assertions descend from a part of the exception hierarchy that normal software rarely catches, so they do tend to propagate to the top of the stack. Nonetheless, the ability to catch an assertion failure and do something with it is useful, because it lets you do things like crash reporting much easier. It also lets you build smaller in-process failure domains.
- telotortium 4y agoIs there a way to automatically break on exceptions in Java, or at least on AssertionError? It looks like it's possible in IntelliJ at least: https://stackoverflow.com/questions/23955273/can-intellij-idea-be-configured-to-break-when-a-junit-assertionerror-occurs https://stackoverflow.com/questions/23955273/can-intellij-id...
- mike_hearn 4y agoYes. You can break on all sorts of conditions. Breaking on any exception isn't all that useful though because lots of code throws and catches exceptions as part of its normal operations unfortunately.
- rco8786 4y agoAnother great idea that’s trivially easy in Ruby “assert == true && binding.pry”
- kjeetgill 4y agoMy favorite underutilized approach to debugging is a hybrid of printf/trace debugging and using an interactive debugger. It's great to be able to tap into a running program and just dump variables at a location to a file. For things that are called a lot and very threaded it's great to not have to lock up the program setting and resuming breakpoints, but the flexibility to be able to introduce new logging as you investigate instead of whatever you thought to log is great.
- deredede 4y ago> (I wish GDB could print a source listing around the breakpoint as context, like Delve, but no such feature exists. The woeful list command is inadequate.) I don't know what Delve does, but learning about GDB's Terminal User Interface (TUI) has been a blessing for me in that regard.
- Galanwe 4y ago> I wish GDB could print a source listing around the breakpoint as context `list`
- deredede 4y agoTe article mentions `list` as being inadequate, and I tend to agree. It needs to be typed in repeatedly, breaking the flow each time, and replacing the "last command" executed with an empty line.
- wavesquid 4y agoTry gdb-dashboard: https://github.com/cyrus-and/gdb-dashboard https://github.com/cyrus-and/gdb-dashboard
- unwind 4y agoThis was really good! I love it when someone looks at the status quo, and just goes "that's how it works, for this and this reason, but it's still not good enough!". Following that up with a trivial re-implementation of a core feature (the C assert() macro) that fixes the problem is icing on the cake, really. It would be cool to add a feature to GDB to make the stock assert() work better, something like a "streamline-assert-trace" option that automatically strips the stack trace back down to the program's source. Doesn't sound completely impossible though I know nothing of GDB's internals.
- maccard 4y agoI work with Unreal Engine which has a whole documentation page [0] on assertions. the default `check` assertion is incredibly useful, and does the "right thing" at so many levels - it pauses the debugger in the callstack on all platforms if attached, _and allows you to resume_ if desired. If not debugging, it will trigger the Unreal runtime's Error handling letting you actually handle the check safely in some error monitoring tools. It's probably my low key favourite feature of Unreal. [0] https://docs.unrealengine.com/4.26/en-US/ProgrammingAndScripting/ProgrammingWithCPP/Assertions/ https://docs.unrealengine.com/4.26/en-US/ProgrammingAndScrip...
- Ciantic 4y ago> Programs are generally not intended to recover from these situations This was my expectation too. It's not always the case in all languages. JavaScript, I found out, just keeps executing a function body even if `console.assert` fails.
- jve 4y agoWell, probably because it is prepended with `console.` - stuff that has to do something about the console and not the program itself :)
- gpderetta 4y agoSanitizers not halting on assertions by default when running under gdb is a pet peeve of mine.
- specialist 4y agoGood article. Tangent: Revisiting Eiffel is on my to do list. IIRC, design-by-contract was a progenitor to (motivator for) assert(). https://en.wikipedia.org/wiki/Eiffel_(programming_language)#Design_by_contract https://en.wikipedia.org/wiki/Eiffel_(programming_language)#... https://en.wikipedia.org/wiki/Design_by_contract https://en.wikipedia.org/wiki/Design_by_contract Young me dismissed Eiffel. Present me kinda likes the syntax. And thinks maybe the overhead of asserting (pre-, post-, invariants) everything could be awesome.
- pvillano 4y agoDbC moves the specification of what a function should do out of doc-strings and test cases and into machine readable code! With fuzzing today, you send one stream of input into an entire program, hope for a crash, then figure out where in the entire execution of the program up to that point things went wrong. You have to figure out how to generate inputs that will exercise every pathway. However, if you had pre and postconditions for every function, you could automatically fuzz individual functions! You don't have to wait for 99% of inputs to get rejected because they don't have the right header. The "unit-fuzzer" would only generate valid inputs for the function it is testing, and check that the function produces valid output, as well as valid inputs for the functions it calls. If you have n functions of complexity k, fuzzing or verifying an entire program takes time k^n. However, if you have pre/postconditions, you can verify every function with k*n work. If you have enough cores, you can do this in parallel in k time. That's insane.
- taeric 4y agoReads like someone that wants a condition and restart system. :)
- mmmm2 4y agoKeep it secret. Keep it safe.