Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: external debugger support #126

Open
nekoniaow opened this issue Nov 5, 2018 · 9 comments
Open

Feature request: external debugger support #126

nekoniaow opened this issue Nov 5, 2018 · 9 comments

Comments

@nekoniaow
Copy link

As mentioned in a post by Chema on the Defence Force forums, it would be very useful to be able to debug emulated Oric code from a full featured debugger (like Visual Studio or GDB) in addition to using Oricutron's internal debugger (cf this post: http://forum.defence-force.org/viewtopic.php?f=22&t=1001&start=90#p15147 and this one: http://forum.defence-force.org/viewtopic.php?p=18359#p18362).

Adding external debugger support can be done relatively easily by using the GDB serial protocol which allows any program to be controlled via a GDB-compatible debugger (Visual Studio supports that protocol for example, as does Visual Studio Code). This would allow people to debug their Oric programs using all the advanced features of their modern IDE debugger. (cf https://ftp.gnu.org/old-gnu/Manuals/gdb-5.1.1/html_node/gdb_125.html for details about that protocol).

As an example, a few people have been working on GDB support for the FS-UAE/Win-UAE Amiga emulator (FrodeSolheim/fs-uae#63) with good results and there does not seem to be any reason why this should not be possible with Oricutron.

Advantages:

  • The debugging features offered by the debugger are usually more complex than what can be reasonably be implemented in Oricutron (multiple windows into memory, source and symbol support, programmable breakpoints, complex watch variables, scripting, etc.)
  • People familiar with a debugger can simply keep using it rather than learning Oricutron's.
  • Allows to split off the debugger from Oricutron via the GDB serial protocol. This would result in less maintenance work on the Oricutron debugger since people could work separately on the emulator or the debugger.
@assinie
Copy link
Collaborator

assinie commented Nov 8, 2018

I think it's not as simple as it sounds.

You can't use GDB because GDB knows nothing about the 6502 CPU. You can use it with FS-UAE/Win-UAE because the 68K is known by GDB.

It's not because you use the GDB protocol that the external debugger magically knows the 6502 CPU.

I think there are 2 different things

  • The external debugger
    • The debugger must be aware of the remote CPU and maybe the whole hardware (ie Oric/Telestrat,...) because it only sends or receives some status to or from Oricutron (register value, memory content, step by step,...). It must know how to disassemble the memory content.
    • If you want to follow some C program, you have to provide the object file to the debugger in a format it can understand. It means the C tool chain must provide this object file or you need some tool to convert from cc65 object file format to the right format.
  • The protocol between Oricutron and the external debugger
    • This may be GDB protocol or not.

So, if you want use GDB as the debugger, you need to patch GDB in order to support the 6502. Same for Visual Studio.
If you want to add some windows to display the video memory (text mode or hires mode), you need to add a plugin to Visual Studio too (and maybe extends the GDB protocol)

Maybe we can see how to add the GDB protocol to Oricutron.
But this is only the "easy" part of the work, you still have to find, or program, the right debugger and the tools needed to translate cc65 object file.

@nekoniaow
Copy link
Author

I think it's not as simple as it sounds.

Oh, it is not simple, I only said "relatively easily", everything is in the "relatively". ;)

You can't use GDB because GDB knows nothing about the 6502 CPU. You can use it with FS-UAE/Win-UAE because the 68K is known by GDB.
It's not because you use the GDB protocol that the external debugger magically knows the 6502 CPU.

You are absolutely right.
I wanted to post about similar efforts in my request but my post was long enough. Here are a few other platforms for which this was done:

I think there are 2 different things

  • The external debugger [snip]
  • The protocol between Oricutron and the external debugger
    • This may be GDB protocol or not.

I agree with your analysis and think going for a GDB based approach has very useful advantages:

  • GDB is already written ;)
  • GDB source code is available which helps in adapting for a new target
  • GDB already has support for most debugging operations (stepping, memory display, register listing, breakpoints, you name it, it probably already has it) and I am pretty sure it has support for platform-specific ones as well.
  • Many IDEs (Visual Studio, Visual Studio Code, many others) already interface with GDB.

So, if you want use GDB as the debugger, you need to patch GDB in order to support the 6502.

Yup, absolutely.

Same for Visual Studio.

I am not too sure since I have not read the docs but VS seems to use a dedicated version of GDB, so one probably only needs to port the 6502 support to that version so the effort could be very small (this needs to be verified).

If you want to add some windows to display the video memory (text mode or hires mode), you need to add a plugin to Visual Studio too (and maybe extends the GDB protocol)

On the Oric this is not necessary since video memory is just regular CPU RAM, exposing memory is more than enough and that would be provided by a basic implementation of the GDB protocol.

Maybe we can see how to add the GDB protocol to Oricutron.
But this is only the "easy" part of the work, you still have to find, or program, the right debugger and the tools needed to translate cc65 object file.

Indeed, which is why it is "relatively" easy, not just "easy". ;)
Ok, "reasonably doable" is probably better. ;)

@assinie
Copy link
Collaborator

assinie commented Nov 27, 2018

There is a compile-time option: DEBUG_CPU_TRACE

With this option, a call to mon_traceinst() is made from the m6502_inst() function.
Right now, mon_traceinst() fills a circular buffer with the cpu state, romdis and instruction code. This buffer is dumped to a log file when Oricutron exits.

A first step may be to modify mon_traceinst() to send the data to a network socket.

@assinie
Copy link
Collaborator

assinie commented Nov 27, 2018

Correction: The circular buffer is actually sent to stdout, not to a log file.
Example:

              F4EC  28        PLP                           ---B---- A=03 X=38 Y=03 SP=01EB ROMDIS=0
              F4ED  68        PLA                           ---B--Z- A=03 X=38 Y=03 SP=01EC ROMDIS=0
              F4EE  60        RTS                           ---B--Z- A=00 X=38 Y=03 SP=01ED ROMDIS=0
              EE65  8A        TXA                           ---B--Z- A=00 X=38 Y=03 SP=01EF ROMDIS=0
              EE66  10 03     BPL $EE6B                     ---B---- A=38 X=38 Y=03 SP=01EF ROMDIS=0
              EE6B  A9 01     LDA #$01                      ---B---- A=38 X=38 Y=03 SP=01EF ROMDIS=0
              EE6D  20 9D EE  JSR GetTimer                  ---B---- A=01 X=38 Y=03 SP=01EF ROMDIS=0
GetTimer      EE9D  48        PHA                           ---B---- A=01 X=38 Y=03 SP=01ED ROMDIS=0
              EE9E  0A        ASL                           ---B---- A=01 X=38 Y=03 SP=01EC ROMDIS=0
              EE9F  A8        TAY                           ---B---- A=02 X=38 Y=03 SP=01EC ROMDIS=0
              EEA0  78        SEI                           ---B---- A=02 X=38 Y=02 SP=01EC ROMDIS=0
              EEA1  B9 72 02  LDA $0272,Y                   ---B-I-- A=02 X=38 Y=02 SP=01EC ROMDIS=0
              EEA4  BE 73 02  LDX $0273,Y                   ---B-I-- A=09 X=38 Y=02 SP=01EC ROMDIS=0
              EEA7  58        CLI                           ---B-IZ- A=09 X=00 Y=02 SP=01EC ROMDIS=0
              EEA8  A8        TAY                           ---B--Z- A=09 X=00 Y=02 SP=01EC ROMDIS=0
              EEA9  68        PLA                           ---B---- A=09 X=00 Y=09 SP=01EC ROMDIS=0
              EEAA  60        RTS                           ---B---- A=01 X=00 Y=09 SP=01ED ROMDIS=0
              EE70  C0 00     CPY #$00                      ---B---- A=01 X=00 Y=09 SP=01EF ROMDIS=0
              EE72  D0 12     BNE $EE86                     ---B---C A=01 X=00 Y=09 SP=01EF ROMDIS=0
              EE86  68        PLA                           ---B---C A=01 X=00 Y=09 SP=01EF ROMDIS=0
              EE87  A8        TAY                           ---B---C A=0A X=00 Y=09 SP=01F0 ROMDIS=0
              EE88  68        PLA                           ---B---C A=0A X=00 Y=0A SP=01F0 ROMDIS=0
              EE89  AA        TAX                           ---B--ZC A=00 X=00 Y=0A SP=01F1 ROMDIS=0
              EE8A  68        PLA                           ---B--ZC A=00 X=00 Y=0A SP=01F1 ROMDIS=0
              EE8B  60        RTS                           ---B---C A=40 X=00 Y=0A SP=01F2 ROMDIS=0
              EE30  68        PLA                           ---B---C A=40 X=00 Y=0A SP=01F4 ROMDIS=0
              EE31  4C 4A 02  JMP $024A                     ---B--ZC A=00 X=00 Y=0A SP=01F5 ROMDIS=0
              024A  40        RTI                           ---B--ZC A=00 X=00 Y=0A SP=01F5 ROMDIS=0
              EB88  60        RTS                           -V----Z- A=00 X=00 Y=0A SP=01F8 ROMDIS=0
              C5EB  10 FB     BPL ReadKey                   -V----Z- A=00 X=00 Y=0A SP=01FA ROMDIS=0
ReadKey       C5E8  20 3B 02  JSR $023B                     -V----Z- A=00 X=00 Y=0A SP=01FA ROMDIS=0
              023B  4C 78 EB  JMP CheckKbd                  -V----Z- A=00 X=00 Y=0A SP=01F8 ROMDIS=0
CheckKbd      EB78  AD DF 02  LDA $02DF                     -V----Z- A=00 X=00 Y=0A SP=01F8 ROMDIS=0
              EB7B  10 0B     BPL $EB88                     -V----Z- A=00 X=00 Y=0A SP=01F8 ROMDIS=0
              EB88  60        RTS                           -V----Z- A=00 X=00 Y=0A SP=01F8 ROMDIS=0
              C5EB  10 FB     BPL ReadKey                   -V----Z- A=00 X=00 Y=0A SP=01FA ROMDIS=0
ReadKey       C5E8  20 3B 02  JSR $023B                     -V----Z- A=00 X=00 Y=0A SP=01FA ROMDIS=0
              023B  4C 78 EB  JMP CheckKbd                  -V----Z- A=00 X=00 Y=0A SP=01F8 ROMDIS=0

@prb28
Copy link

prb28 commented Dec 27, 2018

Hi,
I'm the coder of the vscode amiga assembly extension. I stumbled in your link to the FS-UAE issue.
As you guessed there are two parts for the GDB debuging:

  • In FS-UAE emulator there is the "server" protocol implemented (mainly here) and linked to the console debugger.
  • In vscode there is an extension that implements the client protocol and "knows" the processor, the assembly language and the file formats to extract the debugging infos and create the breakpoints and display the registers.
    I didn't use gdb as client, but only the remote protocol definition.
    I hope this helps, feel free, to ask any question.

@nekoniaow
Copy link
Author

I'm the coder of the vscode amiga assembly extension. I stumbled in your link to the FS-UAE issue.
[...]
I didn't use gdb as client, but only the remote protocol definition.
I hope this helps, feel free, to ask any question.

Hi @prb28 ! Thanks for the notice, this is definitely helpful.
A cursory look at your additions in https://github.com/emoon/fs-uae/blob/master/src/remote_debug/remote_debug.cpp makes me think your work should be fairly adaptable to Oricutron in principle.
I suppose the main changes to VSCode who enable the remote debugging are those in https://github.com/prb28/vscode-amiga-assembly/blob/master/src/fsUAEDebug.ts ?

@prb28
Copy link

prb28 commented Jan 2, 2019

In the vscode extension the most important files for debugging are the socket communication proxy: https://github.com/prb28/vscode-amiga-assembly/blob/master/src/gdbProxy.ts (some parsing modifications must be done for registers, breakpoints, etc.) and the vscode interface: https://github.com/prb28/vscode-amiga-assembly/blob/master/src/fsUAEDebug.ts (at least you must modify the source line to memory offset match, and certainly more things...).
You will find the glue to the extension in: https://github.com/prb28/vscode-amiga-assembly/blob/master/src/debugAdapter.ts and https://github.com/prb28/vscode-amiga-assembly/blob/master/src/extension.ts.

@nekoniaow
Copy link
Author

In the vscode extension the most important files for debugging are [...]

Ok, thanks again, this indeed confirms that the VS Code interface is indeed fairly isolated and very easily adaptable.
Now, I must admit I would much prefer having to deal with a Visual Studio extension rather than VS Code (I try to avoid Electron apps) but the opportunity seems to good to pass.
Thanks again!

@prb28
Copy link

prb28 commented Jan 6, 2019

For the vscode interface there is the Language server protocol: https://microsoft.github.io/language-server-protocol/ , https://code.visualstudio.com/api/language-extensions/language-server-extension-guide.
It may spare some electron development.
At the time, there was already an effort to implement the gdb remote protocol by emoon so I used his code, but there are others solution that can be considered: Nodejs protocol or GDB Mi protocol.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants