Skip to content

Commit

Permalink
Improve debugging experience (#10)
Browse files Browse the repository at this point in the history
* Fix crash on second CTRL+C
* Download gdb-dashboard automatically
* Stub for downloading files from remote side
* gdb: use monitor command to interact with fs-uae debugger
* Comment how to use monitor command
  • Loading branch information
cahirwpz authored Nov 28, 2022
1 parent 30a94f5 commit b833ff2
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 8 deletions.
16 changes: 15 additions & 1 deletion .gdbinit
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,19 @@ set verbose off

source gdb-dashboard
dashboard -layout breakpoints assembly registers source stack variables
# Please refer to https://github.com/cyrus-and/gdb-dashboard/wiki to learn how to customize visual experience
# Please refer to https://github.com/cyrus-and/gdb-dashboard/wiki
# to learn how to customize visual experience
dashboard -style style_low '2'

# Use `monitor` command to access fs-uae debugger.
# Type `monitor ?` to see the list of available commands.
# Some useful commands are:
# * `v -3` - turn on visual DMA debugger
# * `vo` - turn off visual DMA debugger
# * `o 1` - display and disassembly current copper list
# * `c` - display state of CIA registers
# * `e` - display state of custom registers

# Please use fs-uae debugger carefully - preferably only for inspecting state of
# the machine. It's a very powerful tool but even mistyping a command can break
# a session between gdb and the emulator.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ tags:

cscope.out:
cscope -b $(FILES)

gdb-dashboard:
wget -O $@ https://raw.githubusercontent.com/cyrus-and/gdb-dashboard/master/.gdbinit
7 changes: 5 additions & 2 deletions build/effect.mk
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,17 @@ DEBUGGER ?= gdb
run-floppy: $(EFFECT).exe.dbg $(EFFECT).adf
$(LAUNCH) -e $(EFFECT).exe.dbg -f $(EFFECT).adf

debug-floppy: $(EFFECT).exe.dbg $(EFFECT).adf
debug-floppy: $(EFFECT).exe.dbg $(EFFECT).adf $(TOPDIR)/gdb-dashboard
$(LAUNCH) -d $(DEBUGGER) -f $(EFFECT).adf -e $(EFFECT).exe.dbg

run: $(EFFECT).rom $(EFFECT).exe.dbg $(EFFECT).adf
$(LAUNCH) -r $(EFFECT).rom -e $(EFFECT).exe.dbg -f $(EFFECT).adf

debug: $(EFFECT).rom $(EFFECT).exe.dbg $(EFFECT).adf
debug: $(EFFECT).rom $(EFFECT).exe.dbg $(EFFECT).adf $(TOPDIR)/gdb-dashboard
$(LAUNCH) -d $(DEBUGGER) -r $(EFFECT).rom -e $(EFFECT).exe.dbg -f $(EFFECT).adf

$(TOPDIR)/gdb-dashboard:
make -C $(TOPDIR) gdb-dashboard

.PHONY: run debug run-floppy debug-floppy
.PRECIOUS: $(BOOTLOADER) $(EFFECT).img
26 changes: 25 additions & 1 deletion tools/debug/gdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,30 @@ async def handle_query(self, packet):
# Notify the target that GDB is prepared to serve symbol
# lookup requests.
self.gdb.send_ack('OK')
elif packet.startswith('Rcmd,'):
# Forwards input from `monitor` command to UAE debugger.
raw_cmd = packet.split(',', maxsplit=1)[1]
cmd = bytes.fromhex(raw_cmd).decode('utf-8')
lines = await self.uae.communicate(cmd)
text = '\n'.join(lines) + '\n'
self.gdb.send_ack(text.encode('utf-8').hex())

return True

def handle_file(self, packet):
# Minimal support for `remote get` command to transfer empty files.
cmd, args = packet[0], packet[1].split(',')
if cmd == 'setfs':
self.gdb.send_ack('F0')
elif cmd == 'open':
self.gdb.send_ack('F0')
elif cmd == 'close':
self.gdb.send_ack('F0')
elif cmd == 'pread':
self.gdb.send_ack('F0;') # `pread` command requires semicolon
else:
self.gdb.send_ack('')

@staticmethod
def binary_decode(data):
# Decode GDB binary stream. See:
Expand Down Expand Up @@ -281,7 +302,10 @@ async def handle_packet(self, packet):
elif packet[0] == 'v':
# The correct reply to an unknown 'v' packet is to return the
# empty string.
self.gdb.send_ack('')
if packet.startswith('vFile:'):
self.handle_file(packet.split(':')[1:])
else:
self.gdb.send_ack('')

return True

Expand Down
7 changes: 7 additions & 0 deletions tools/debug/uae.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,10 @@ async def kill(self):


async def UaeDebugger(uaedbg):
# Call FS-UAE debugger on CTRL+C
loop = asyncio.get_event_loop()
loop.add_signal_handler(signal.SIGINT, uaedbg.interrupt)

history = InMemoryHistory()
session = PromptSession('(debug) ', history=history)
with patch_stdout():
Expand All @@ -285,6 +289,9 @@ async def UaeDebugger(uaedbg):
while not cmd:
cmd = await session.prompt_async()
cmd.strip()
# prompt_async removes our SIGINT handler :(
loop.add_signal_handler(signal.SIGINT,
uaedbg.interrupt)
uaedbg.send(cmd)
except EOFError:
uaedbg.resume()
Expand Down
6 changes: 2 additions & 4 deletions tools/uaedbg.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ async def GdbListen():
if args.gdbserver:
await GdbListen()
else:
# Call FS-UAE debugger on CTRL+C
loop.add_signal_handler(signal.SIGINT, uaeproc.interrupt)
prompt_task = asyncio.ensure_future(UaeDebugger(uaeproc))

await uaeproc.wait()
Expand All @@ -70,9 +68,9 @@ async def GdbListen():

if sys.platform == 'win32':
loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop)
else:
loop = asyncio.get_event_loop()
loop = asyncio.SelectorEventLoop()
asyncio.set_event_loop(loop)
# loop.set_debug(True)

parser = argparse.ArgumentParser(
Expand Down

0 comments on commit b833ff2

Please sign in to comment.