Skip to content

FlavienVolant/sindarin-dap

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

88 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sindarin-dap

sindarin-dap is an implementation of a Debug Adapter Protocol (DAP) client. It relies on the structures and types provided by Pharo-LanguageServer.

The main goal of this project is to map Sindarin commands to their DAP equivalents, allowing the debugger to be controlled through Sindarin scripts.

The client currently works exclusively over socket connections.

Installation

Metacello new
	baseline: 'PharoDAPClient';
	repository: 'github://FlavienVolant/sindarin-dap:main';
	load

Architecture

DAPClient

DAPClient is the base class responsible for:

  • Managing the connection to the DAP server
  • Sending messages on the main thread
  • Receiving responses on a separate thread

It also implements a callback mechanism to handle:

  • Responses to specific requests
  • Incoming requests and events from the DAP server

SindarinDAPClient

SindarinDAPClient is the main entry point of the project.

It extends DAPClient and provides an implementation of Sindarin commands as DAP messages.

Unlike DAPClient, this client is designed to behave synchronously by waiting for responses. See:

  • handleAsyncResponse: anAction returning: key

Since the client may need to store data inside the debuggee, and this behavior depends on the target language, the following methods are left as subclass responsibilities:

  • dapRegistryAt: keyAsString put: valueAsString
  • initializeDapRegistry

These require DAP capabilities such as supportSetExpressions or supportSetVariables.

DAPClientBuilder

DAPClientBuilder is the recommended way to configure and initialize a DAP client.

It handles:

  • The handshake with the DAP server
  • Sending initialization data at the correct time

See the Examples initialize methods for usage.

ClientDAPPresenter

ClientDAPPresenter is a UI tool that displays all:

  • Requests
  • Responses
  • Events

that go through the client.

Supported Languages

The client currently supports:

  • Python -> DAPClientForPY
  • Java -> DAPClientForJAVA
  • JavaScript -> DAPClientForJS

Refer to the corresponding help/documentation for each language to learn how to set up your environment and start debugging.

Python

This client uses debugpy as the DAP adapter.

Installation

Install debugpy using pip:

pip install debugpy

Starting the DAP Adapter

Run your Python script with debugpy and wait for the client to attach:

python -m debugpy --listen 5678 --wait-for-client py/script.py

Client Configuration (Pharo)

The DAP client is configured via DAPClientForPY. You can adapt the following example to your setup:

	DAPClientBuilder new
		client: self;
		port: 5678;
		adapterID: 'python';
		attachArguments: self attachArguments;
		breakpoint: '/path/to/your/script.py' line: 8;
		functionBreakpoint: 'toto' condition: 'True';
		startClientSession

attachArguments
	^ {
		  ('name' -> 'Attach to Python').
		  ('type' -> 'python').
		  ('connect' -> {
			   ('host' -> 'localhost').
			   ('port' -> 5678) } asDictionary).
		  ('redirectOutput' -> true).
		  ('showReturnValue' -> true) } asDictionary

Starting the Debugging Session

  • Start the debugpy adapter (see above)
  • In a Pharo Playground, run:
client := ClientDAPPresenter newWithClient: DAPClientForPY new.
client open.

JavaScript (Node.js)

This client uses the Microsoft vscode-js-debug adapter.

Requirements

Getting the JavaScript Debug Adapter

Download a release from:

https://github.com/microsoft/vscode-js-debug/releases

Extract it, then locate the DAP server entry point:

js-debug/src/dapDebugServer.js

Starting the Target Script

Run your Node.js script in debug mode:

node --inspect-brk=0.0.0.0:9229 js/script.js

This starts Node with the inspector protocol enabled and waits for a debugger to attach.

Starting the DAP Adapter

Launch the debug adapter server:

node js-debug/src/dapDebugServer.js 5678

The adapter will listen for DAP connections on port 5678.

Client Configuration (Pharo)

This adapter require the client to support startDebuggingRequest. Therefore, a second DAP client (DAPClientForJSStartDebug) is created with extended attachArguments.

initialize
	super initialize.

	requestHandlers
		at: 'startDebugging'
		put: [ :req | self handleStartDebuggingRequest: req ]


handleStartDebuggingRequest: aStartDebuggingRequest

	| childClient |

	childClient := DAPClientForJSStartDebug new
		attachOtherArguments:
			(aStartDebuggingRequest
				at: 'arguments'
				at: 'configuration').

	childClient startSession.

	(ClientDAPPresenter newWithClient: childClient) open

Starting a Session

startSession
	
	DAPClientBuilder new
		client: self;
		adapterID: 'node';
		port: 5678;
		attachArguments: self attachArguments;
		startClientSession

attachArguments
	
	^ {
		('name' -> 'Attach Node.js script.js').
		('type' -> 'pwa-node').
		('request' -> 'attach').
		('address' -> 'localhost').
		('port' -> 9229).
		('continueOnAttach' -> true)
	} asDictionary

Starting the Debugging Session

  • Start your Node.js script with --inspect-brk
  • Start the vscode-js-debug adapter
  • In a Pharo Playground, run:
client := DAPClientForJS new startSession.

Java

The Java client relies on the java-debug adapter from Microsoft.
This adapter is designed to work as a plugin for the Java Language Server (eclipse.jdt.ls).

Requirements

  • eclipse.jdt.ls (Java Language Server)
  • java-debug plugin

Getting the Java Debug Adapter

One simple way to obtain the adapter is to install the VS Code extension:

  • Debugger for Java (Microsoft)

After installation, you can find the required JAR in:

.vscode/extensions/vscjava.vscode-java-debug-<version>/server/

Look for a file like:

com.microsoft.java.debug.plugin-<version>.jar

Preparing the Target JVM

The Java program must be started in debug mode using JDWP, so the debugger can attach to it:

java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005 \
  -cp target/classes \
  example.Main

This starts the JVM in debug mode and listens on port 5005.

Starting the LSP Server with java-debug

To use java-debug, you must start eclipse.jdt.ls with the debug plugin included in the bundles initialization option:

{
  "initializationOptions": {
    "bundles": [
      "path/to/com.microsoft.java.debug.plugin-<version>.jar"
    ]
  }
}

Starting a Debug Session

Once eclipse.jdt.ls is running, send the following command via your LSP client:

{
  "command": "vscode.java.startDebugSession"
}

The server will respond with a port number where the DAP adapter is listening.

Client Configuration (Pharo)

Use DAPClientForJAVA and configure it with the port returned by the LSP server:

	DAPClientBuilder new
		client: self;
		port: 63461; "Replace with the returned port"
		adapterID: 'java';
		attachArguments: self attachArguments;
		breakpoint:
			'/path/to/your/project/src/main/java/example/Main.java'
		line: 5;
		breakpoint:
			'/path/to/your/project/src/main/java/example/Main.java'
		line: 9;
		functionBreakpoint: 'example.Bar#toto'
		condition:
			'true';
		startClientSession

attachArguments

	^ {
		  ('name' -> 'Attach to Java').
		  ('type' -> 'server').
		  ('hostName' -> 'localhost').
		  ('port' -> 5005).
		  ('projectName' -> 'java') } asDictionary

Starting the Debugging Session

  • Start your Java program with JDWP enabled
  • Start eclipse.jdt.ls with the java-debug plugin
  • Send the vscode.java.startDebugSession command via your LSP client
  • Retrieve the port from the response
  • In a Pharo Playground, run:
client := ClientDAPPresenter newWithClient: DAPClientForJAVA new.
client open.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors