Well, my intention was that you might want to breakpoint IRQs 8 or 9. Suppose you set a breakpoint in the IRQ 9 ISR. How on earth would your debugger get a keystroke to tell it proceed?
Hmmm... yes, that might be a problem. My naive solution is to just tell the user 'bad things will happen if you try that'. A better solution might be to hook the hardware interrupts and trigger a semaphore. If the semaphore is nonzero, the debugger cannot be invoked.
On a potentially similar note, I can make it so that the main loop of the debugger is invoked AFTER the keyboard interrupt is serviced
in full (both the new routine and the BIOS routine)- by altering the return address on the stack a la a context switch. Currently the debugger is invoked within an invocation of INT 9 if the correct key combination is detected (which the register values already on the stack). I'm not exactly sure what other issues that would cause at this time, though.
Consider an arbitrary stack frame for a program. The debugger will allocate it's own call frame. When the debugger is invoked- either from keypress, absolute jump, breakpoint int, or trace int... doesn't matter!- the stack frame allocated for it- and the current SP/BP- should be considered the new 'bottom' of physical stack as far as the debugger is concerned. The program's stack frame below this address is 'illegal' for the debugger to use or modify (read is okay, and required if we want the program's stack frame
). We should NEVER be executing ANY debugging code if the current address of top of the stack (SP) is greater than the address when the debugger was invoked.
The above procedure probably also means that I have to keep track of how the debugger was invoked (either keypress, break, trace, jump, etc), but we'll see...
Addendum after giving it some more thought:
Basically, the debugger will always exit before executing the next instruction prior to invocation, even if it's in the middle of an interrupt such as the keyboard interrupt or even timer interrupt.
The only routines I can really envision being non-reentrant is the timer (0x08) and keyboard hardware interrupts (0x09 and 0x16)- even then the debugger shouldn't really crash... just debugging such a routine would be unreliable because data was modified outside the context of the debugger.
If you want to observe how arcane things can get, consider, say, a background floppy formatter that's activated with a hotkey combination. You can get the hotkey combination all right, but you don't know what the foreground program is doing or where it might be--and yet you need to display things, get keyboard input and run from your own stack, but leave the user's program running while you format the floppy. It's an interesting mental exercise.
I'm not sure I see the issue here... why would I need to display things and get keyboard input for a program that formats a floppy
in the background? Even if it needs to, I don't see the issue with the same interrupt being called twice... I thought the BIOS interrupts at least were re-entrant. The OS can still handle keyboard and video while the floppy drive does its format, and the timer interrupt can be hooked to check the floppy drive and send a command if necessary every 18.2 ms.