By the late 80's gdb was already fully working in many embedded environments
Um. For x86 and 68000 class CPUs...
Don't forget the Intel i960 and by the mid 90's the ARM support was there and obviously with full gdb support.
It just strikes me as odd that more than 20 years after good source level debugging has been available that
a processor like the AVR lacks some internal hardware capabilities and IDEs like the Arduino IDE don't at least provide
some mechanisms to at least make it a bit easier for those that want to push things further for a software only
Atmel apparently doesn't document their debugging features, which is sorta sucky of them, IMO. Otherwise ArduinoISP could support some debugging features.
The Visual Micro "invasive, software based" debugging sounds interesting. It'll be interesting to see how well it works. Unlike x86 and 68k, the AVR doesn't have a lot of the support needed for a good debugger, and having code in flash where you can't swap in breakpoint instructions "on the fly" is a pain.
I'm guessing that the reason their debug interfaces are not documented is that I bet
if using something like debug wire or JTAG that there is a way you could circumvent the read-only fuses.
While the lack of documented debugger interfaces on the AVR and its harvard architecture does makes
things more difficult for a software only debugger implementation, I don't think it is prevents it.
The biggest thing I find missing in the AVR is the lack of TRAP instruction.
The current gdb sets soft breakpoints by inserting a BREAK instruction into the flash which is a NOP if
the debug fuse isn't set. But the BREAK instruction requires atmels h/w in order to use it.
To stay in a s/w only implementation, avr gdb can be changed to use some other instruction sequence
but it is difficult to find something that is a single instruction. Not that it has to be a single instruction
but it can make things easier.
I've looked at using a pin change interrupt to simulate a BREAK/TRAP.
You can then use a single instruction to set the pin level when you want the "trap", but that potentially burns a pin.
But it also does allow using a switch input to drop into the debugger.
(If you want to really get control of everything including the ability to break in ISR code
you have to steal the highest priority interrupt)
Swapping in the "break" instruction sequence into the flash can be done but is tricky as it
can require some support in the bootloader section in order to modify the users flash contents.
But it's definitely doable. It requires a bit of tricky code that can flip between user and bootloader code
(This is another place where a TRAP instruction would be useful)
Single stepping can be done without resorting to modifying the flash with some clever code
that uses a HARD stuck interrupt (using the same interrupt/pin that could be used for regular breakpoints).
The Atmel hardware solutions don't do this, they set a BREAK instruction in flash and then restore the code
during each single step on the non jtag implementations. This causes flash wear.
Looking at internal AVR registers and program variables is easy and comes "for free" as it just kind of works
once you have a gdbmon in place.
I know how to do it all, and I think it would only be a few hundred bytes of code at most to do it,
I just haven't spent the time tie it all together and finish it up.