Skip to content

dd86k/aliceserver

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

71 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

About Aliceserver

Aliceserver is a debugger server implementing the DAP and MI protocols, using Alicedbg as the debugger back-end.

This is major work in progress! Don't expect it to replace GDB or LLDB any time soon.

Why?

  • lldb-mi is generally no longer available as a prebuilt binary after LLDB 9.0.1.
  • lldb and variants (including lldb-vscode/lldb-dap) all require the Python runtime.
  • gdb-mi is fine, but GDC is generally unavailable for Windows.
  • gdb-dap is written in Python and thus requires it.
  • Mago, and mago-mi, are only available for Windows on x86/AMD64 platforms.
  • All transport options in one package.
  • Aliceserver provides future directions for features in Alicedbg.

Uses:

  • Integrating your favorite text or code editor that implements a debugger UI.
  • Automated debugging integration testing.
  • Reusable high-level integration of Alicedbg.

Planned features:

  • Multi-session support using TCP sockets.
  • Multi-session support using UNIX sockets and Windows NamedPipes.
  • Multi-session settings (unique session only, new session per connection).

Implementation Details

+-------------------------------------------+
| Aliceserver                               |
| +---------------------------------------+ |
| |                Server                 | |
| +---------------------------------------+ |
|      ^               ^            ^       |
|      |               |            |       |
|      |               v            v       |
|      |          +----------+ +----------+ |
|      v          | Adapter  | | Adapter  | |
| +-----------+   +----------+ +----------+ |
| | Transport |   | Debugger | | Debugger | |
+-+-----------+---+----------+-+----------+-+
       ^               ^            ^
       v               v            v
   +~~~~~~~~~+    +~~~~~~~~~~+ +~~~~~~~~~~+
   | Client  |    | Process  | | Process  |
   +~~~~~~~~~+    +~~~~~~~~~~+ +~~~~~~~~~~+

Aliceserver is implemented using an Object-Oriented Programming model.

The debugger server provides types and structures that the adapters and debuggers must interpret.

Aliceserver does not yet support multi-session.

Transports

Transports handle the transport of data from and to clients.

The medium can include streams, sockets, anything really.

Each transport classes inherit transport.ITransport.

Available transports:

  • StdioTransport: Implements a transport using standard streams.

Adapters

Adapters have the responsability of handling the behavior of the given transport and the debugger instances.

Using the transport instance, adapters need to parse requests and send formatted replies and events back to the client via the transport instance.

Using the debugger instance, adapters need to interpret commands and handle debugger events.

After setting up instances, the server calls IAdapter.loop(ITransport, IDebugger).

Each adapter inherits adapter.IAdapter.

Available adapters:

  • DAPAdapter: Implements Debug Adapter Protocol as an adapter.
  • MIAdapter: Implements GDB's Machine Interface as an adapter.

Debuggers

Used to interface a debugger that manipulates processes.

Each debugger classes inherit debugger.IDebugger.

Right now, only AlicedbgDebugger is available as a debugger.

Adapter Details

DAP

Debugger Adapter Protocol (DAP) is a HTTP-like JSON protocol that was introduced in vscode-debugadapter-node and was readapted as a standalone protocol for debugging various processes and runtimes in Visual Studio Code.

The protocol leaves a lot of nuance regarding implementation details, which can be a little infuriating to work with.

This chapter reuses terminology from DAP, such as Integer meaning, strictly speaking, a 32-bit integer number (int), and Number meaning a 64-bit double-precision floating-point number (IEEE 754 double).

Connection Details

DAP has two connection models: Single-session and multi-session.

  • Single-session: Using standard I/O (stdio), a single adapter instance is started.
  • Multi-session: Using TCP/IP, every new connection initiates a new debug session.

Messages are encoded as HTTP messages using the UTF-8 encoding.

Currently, there is only one header field, Content-Length, that determines the length of the message (payload). This field is read as an Integer.

The body (payload) is assumed to be encoded as JSON.

A typical request may look like this:

Content-Length: 82\r\n
\r\n
{"seq":1,"type":"request","command":"initialize","arguments":{"adapterId":"test"}}

And a typical response may look like this:

Content-Length: 81\r\n
\r\n
{"command":"initialize","request_seq":1,"seq":1,"success":true,"type":"response"}

Both client and server maintain their own sequence number, starting at 1.

NOTE: lldb-vscode starts their seq number at 0, while not as per specification, it poses no difference to its usage.

Supported Requests

Implementation-specific details:

  • launch request:
    • arguments:path: (Required) [String] File path.
  • attach request:
    • arguments:pid: (Required) [Integer] Process ID.

Command support:

Command Supported? Comments
attach ✔️ __restart argument not supported.
breakpointLocations
completions
configurationDone
continue
dataBreakpointInfo
disassemble
disconnect ✔️
evaluate
exceptionInfo
goto
gotoTargets
initialize ✔️ Locale is not supported.
launch ✔️ noDebug and __restart are not supported.
loadedSources
modules
next
pause
readMemory
restart
restartFrame
reverseContinue
scopes
setBreakpoints
setDataBreakpoints
setExceptionBreakpoints
setExpression
setFunctionBreakpoints
setInstructionBreakpoints
setVariable
source
stackTrace
stepBack
stepIn
stepInTargets
stepOut
terminate ✔️
terminateThreads
threads
variables
writeMemory

Supported Events

Event Supported? Comments
breakpoint
capabilities
continued
exited ✔️
initialized
invalidated
loadedSource
memory
module
output
process
progressEnd
progressStart
progressUpdate
stopped
terminated
thread

MI

Machine Interface is a line-oriented protocol introduced in GDB 5.1.

Connection Details

In a typical setting, MI uses the standard streams to communicate with the child process.

Once the server starts running, it may already emit console streams, until (gdb)\n is printed, indicating that the server is ready to receive commands.

Commands are almost the same as you would use on GDB:

attach 12345\n

Replies to commands start with a ^ character:

^done\n

Or on error (note: \\n and \\" denote c-string formatting):

^error,msg="Example text.\\n\\nValue: \\"Test\\""\n

Events, console streams, logs, start with a significant unique character.

For example, command input (e.g., test\n) will be replied as &"test\\n"\n using c-string formatting.

Reply/Event Character Description
Result ^ Used to reply to a command, if successful or errorneous.
Exec * Async execution state changed.
Notify = Async notification related to the debugger.
Status + Async status change.
Console Stream ~ Console messages intended to be printed.
Target Stream @ Program output when truly asynchronous, for remote targets.
Log Stream & Internal debugger messages.

Some commands may start with -.

Supported Requests

NOTE: Command focus is on GDB, lldb-mi commands may work.

Request Commands Supported? Comments
Attach attach ✔️
Launch -exec-run, target exec, -exec-arguments ✔️
Continue -exec-continue ✔️
Terminate -exec-abort ✔️
Detach -exec-detach, detach ✔️
Set working directory environment-directory ✔️
Disconnect q, quit, -gdb-exit ✔️

Supported Events

Request Details Supported? Comments
Continued ✔️
Exited Reasons: exited, exited-normally ✔️
Output
Stopped

Licensing

This project is licensed under the BSD-3-Clause-Clear license.