A debugger may be able to defend his integrity and memory space even in arcane architectures.
Granted that in the most common implementations, where you want to save speed and memory, and simplify the debug code, you are dependent on hardware protections provided by more advanced architectures.
The software can very well have anti-debug measures built-in for known debuggers or accidentally overwrite it in the course of loading or even in the normal operation of the program.
However, if you are willing to sacrifice memory and speed, it is rather easy to do "emulation" in the same CPU/interpreting critical commands and running others in a controlled area, at least more easy than implementing an emulation in a foreign architecture, as you are implementing actual arithmetic and bit operations using the native machine code instructions .
Taking the ZX Spectrum as an example, think it as an emulator for Z80 written in Z80 binary code just for the purpose of having an advanced debugger - think of it like pretending Z80 code is a foreign CPU, or as p-code and interpreting it (similar to how a BASIC program works).
To be fair, before I wrote my own Spectrum emulator for Windows, I was toying around for long about writing a native Z80 interpreter/emulator in the actual Z80 machine as a proof of concept, and even wrote the basics of this idea for debugging in a real ZX Spectrum 48K behaviour of undocumented Z80 opcodes for my emulation.
Even more interestingly yet, in machines like the TC/TS 2068 where you can control RAM paging from the 48K mode, you might get away with debugging full 48K programs if you get your paging code right.
Actually with such scenario you might even page in a screen with the debug interface and at the when running the commands write to the actual addresses/pages of the "real" screen.
Such a tool, besides the obvious debugging capabilities, would perhaps be more interesting as an educational tool if used contemporarily before emulation development systems in more advanced architectures became common place to hobbyists.
You might even extend such a tool with help of hardware, where you load a very protected piece of software (a turbo loader with the Alkatraz protection for instance), and later on take control of it with a NMI interrupt, passing control to such debugger in another page of RAM.
P.S. The comment of TS/TC 2068 might also apply to Spectrum +2 hardware, never had one so not sure.
The concept is also not new, and it was implemented in the past, albeit in more advanced systems. One of the oldest (from 1994) and better example I know of, is Bochs
Bochs (pronounced "box") is a portable IA-32 and x86-64 IBM PC
compatible emulator and debugger mostly written in C++ (...) It
supports emulation of the processor(s) (including protected mode),
memory, disks, display, Ethernet, BIOS and common hardware peripherals
Many guest operating systems can be run using the emulator including
DOS, several versions of Microsoft Windows, BSDs, Linux, Xenix and
Rhapsody (precursor of Mac OS X). Bochs runs on many host operating
systems, including Android, iOS, Linux, Mac OS X, PlayStation 2,
Windows, Windows Mobile.
Bochs is mostly used for operating system development (when an
emulated operating system crashes, it does not crash the host
operating system, so the emulated OS can be debugged) and to run other
guest operating systems inside already running host operating systems.
It can also be used to run older software – such as PC games – which
will not run on non-compatible, or too fast computers.