bloombloombloom / Bloom

A debug interface for AVR-based embedded systems development on GNU/Linux.
https://bloom.oscillate.io/
Other
65 stars 4 forks source link

Bloom does not operate properly with CLion 2022.1 (due to lack of memory address validation) #37

Closed navnavnav closed 2 years ago

navnavnav commented 2 years ago

When debugging in CLion 2022.1, GDB & CLion end up in an endless loop when attempting to generate a backtrace, once target execution comes to a stop. CLion repeatedly requests stack frames from GDB, but GDB fails to identify the outermost frame, so it ends up walking down the stack, reading two bytes at a time, attempting to identify the outermost frame. And because GDB isn't aware of the target's RAM size, it doesn't know when to stop walking down the stack (keep in mind that the stack on AVR targets starts at the top of the RAM, so walking down the stack means walking up the RAM).

This issue results in CLion's debugger becoming very slow or unresponsive (as it waits for GDB), and no longer usable.

Observing avr-gdb's input, when run under CLion 2022.1, we have the following:

-gdb-set print elements 256
-gdb-set print repeats 0
-gdb-set print object on
-gdb-set print asm-demangle on
-gdb-set python print-stack full
-gdb-set backtrace past-main on
-gdb-set backtrace past-entry on
-gdb-show mi-async
-gdb-set mi-async on

So CLion is configuring GDB to include frames before the entry point of the application (via the -gdb-set backtrace past-entry on command). This is why GDB isn't stopping at the frame preceding main() (which it used to do, with CLion 2021.1 - because that version of CLion only enabled backtrace past-main, and not backtrace past-entry.).

This isn't an issue with CLion. In fact, it has exposed an issue with Bloom. Bloom is not properly validating memory addresses sent by GDB, in memory access command packets. This means we're currently allowing GDB to request any memory address it likes, even if that address is outside of the target's memory boundary. Also, the debug tools don't seem to care about this either; If you attempt to read memory at an address outside of the target's memory boundary, the debug tool just returns 0xFF for each byte. I believe this is why GDB is failing to identify the outermost frame (or at least partially why).

We need to ensure that Bloom does not permit GDB to access any memory at an invalid address. This should prevent GDB from attempting to find frames where none exist.

navnavnav commented 2 years ago

The fix for this has been pushed to the develop branch. The fix resolves the issue with CLion debugging. GDB will now stop attempting to identify stack frames once it's reached the bottom of the stack (because Bloom now rejects any request to read RAM at an invalid address).

These changes will be shipped in v0.9.0. I'm going to leave this issue open, in case anyone comes looking for it whilst I continue work on v0.9.0 (it will be a while before it's ready for publishing).