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

cmd/dlv: add --client-addr flag to run dap with a predefined client #2568

Merged
merged 11 commits into from
Oct 13, 2021
8 changes: 4 additions & 4 deletions Documentation/usage/dlv_dap.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ The server does not yet accept multiple client connections (--accept-multiclient
While --continue is not supported, stopOnEntry launch/attach attribute can be used to control if
execution is resumed at the start of the debug session.

The --connect flag is a special flag that makes the server operate in reverse mode.
In this mode, Delve connects to a DAP client listening on host:port,
instead of listening for connections.
The --client-addr flag is a special flag that makes the server initiate a debug session
by dialing in to the host:port where a DAP client is waiting. This server process
will exit when the debug session ends.

```
dlv dap
Expand All @@ -28,7 +28,7 @@ dlv dap
### Options

```
--connect string host:port of the DAP client when running in reverse mode.
--client-addr string host:port where the DAP client is waiting for the DAP server to dial in
```

### Options inherited from parent commands
Expand Down
22 changes: 11 additions & 11 deletions cmd/dlv/cmds/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ var (
// disableASLR is used to disable ASLR
disableASLR bool

// dapConnect is dap subcommand's flag that specifies the address of a DAP client.
// If it is specified, the dap server operates in reverse mode and
// and dials into the client waiting there.
dapConnect string
// dapClientAddr is dap subcommand's flag that specifies the address of a DAP client.
// If it is specified, the dap server starts a debug session by dialing to the client.
// The dap server will serve only for the debug session.
dapClientAddr string

// backend selection
backend string
Expand Down Expand Up @@ -192,12 +192,12 @@ The server does not yet accept multiple client connections (--accept-multiclient
While --continue is not supported, stopOnEntry launch/attach attribute can be used to control if
execution is resumed at the start of the debug session.

The --connect flag is a special flag that makes the server operate in reverse mode.
In this mode, Delve connects to a DAP client listening on host:port,
instead of listening for connections.`,
The --client-addr flag is a special flag that makes the server initiate a debug session
by dialing in to the host:port where a DAP client is waiting. This server process
will exit when the debug session ends.`,
Run: dapCmd,
}
dapCommand.Flags().StringVar(&dapConnect, "connect", "", "host:port of the DAP client when running in reverse mode.")
dapCommand.Flags().StringVar(&dapClientAddr, "client-addr", "", "host:port where the DAP client is waiting for the DAP server to dial in")
polinasok marked this conversation as resolved.
Show resolved Hide resolved

rootCommand.AddCommand(dapCommand)

Expand Down Expand Up @@ -449,7 +449,7 @@ func dapCmd(cmd *cobra.Command, args []string) {
var server *dap.Server
disconnectChan := make(chan struct{})

if dapConnect == "" {
if dapClientAddr == "" {
listener, err := net.Listen("tcp", addr)
if err != nil {
fmt.Printf("couldn't start listener: %s\n", err)
Expand All @@ -470,9 +470,9 @@ func dapCmd(cmd *cobra.Command, args []string) {
} else { // reverse mode
hyangah marked this conversation as resolved.
Show resolved Hide resolved
headless = true // TODO(github.com/go-delve/delve/issues/2552): consider the same for the normal mode.
hyangah marked this conversation as resolved.
Show resolved Hide resolved

conn, err := net.Dial("tcp", dapConnect)
conn, err := net.Dial("tcp", dapClientAddr)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to connect to the DAP proxy server: %v\n", err)
fmt.Fprintf(os.Stderr, "Failed to connect to the DAP client: %v\n", err)
return 1
}
server = dap.NewReverseServer(&service.Config{
Expand Down
4 changes: 2 additions & 2 deletions cmd/dlv/dlv_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ func TestDapReverse(t *testing.T) {
dlvbin, tmpdir := getDlvBin(t)
defer os.RemoveAll(tmpdir)

cmd := exec.Command(dlvbin, "dap", "--log-output=dap", "--log", "--connect", listener.Addr().String())
cmd := exec.Command(dlvbin, "dap", "--log-output=dap", "--log", "--client-addr", listener.Addr().String())
buf := &bytes.Buffer{}
cmd.Stdin = buf
cmd.Stdout = buf
Expand All @@ -670,7 +670,7 @@ func TestDapReverse(t *testing.T) {
}
t.Log("dlv-reverse dialed in successfully")

client := daptest.NewClientWithConn(conn)
client := daptest.NewClientFromConn(conn)
client.InitializeRequest()
client.ExpectInitializeResponse(t)

Expand Down
6 changes: 4 additions & 2 deletions service/dap/daptest/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ func NewClient(addr string) *Client {
if err != nil {
log.Fatal("dialing:", err)
}
return NewClientWithConn(conn)
return NewClientFromConn(conn)
}

func NewClientWithConn(conn net.Conn) *Client {
// NewClientFromConn creates a new Client with the given TCP connection.
// Call Close to close the connection.
func NewClientFromConn(conn net.Conn) *Client {
c := &Client{conn: conn, reader: bufio.NewReader(conn)}
c.seq = 1 // match VS Code numbering
return c
Expand Down
6 changes: 3 additions & 3 deletions service/dap/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,17 +203,17 @@ const (
// disconnects or requests shutdown. Once config.DisconnectChan is closed,
// Server.Stop() must be called to shutdown this single-user server.
func NewServer(config *service.Config) *Server {
return newServer(config, nil, false)
return newServer(config, nil)
}

// NewReverseServer creates a special DAP server that operates in reverse mode.
// Reverse DAP server is not actually running a TCP server listening on a port,
// but communicates with the provided net.Conn only for a single debug session.
func NewReverseServer(config *service.Config, conn net.Conn) *Server {
hyangah marked this conversation as resolved.
Show resolved Hide resolved
return newServer(config, conn, true)
return newServer(config, conn)
}

func newServer(config *service.Config, conn net.Conn, inReverseMode bool) *Server {
func newServer(config *service.Config, conn net.Conn) *Server {
logger := logflags.DAPLogger()
if config.Listener != nil {
logflags.WriteDAPListeningMessage(config.Listener.Addr().String())
Expand Down