cmds/commands: Update 'client-addr' to support Unix domain sockets (#3819)

* cmds/commands: Update 'client-addr' to support Unix domain sockets

This change updates the '--client-addr' flag to accept Unix domain sockets (UDS). Currently, the --listen flag supports UDS, but --client-addr does not. This modification ensures consistency across the APIs and improves support for vscode-go, which uses reverse mode (via client-addr) to connect to DAP.

Fixes #3814

* Undo formatter changes in dlv_test.go

* Update commands.go
This commit is contained in:
Nilesh Singh 2024-09-30 23:50:48 +05:30 committed by GitHub
parent ed40291572
commit 8b878fb238
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 52 additions and 9 deletions

@ -33,7 +33,7 @@ dlv dap [flags]
### Options ### Options
``` ```
--client-addr string host:port where the DAP client is waiting for the DAP server to dial in --client-addr string Address where the DAP client is waiting for the DAP server to dial in. Prefix with 'unix:' to use a unix domain socket.
-h, --help help for dap -h, --help help for dap
``` ```

@ -244,7 +244,7 @@ will exit when the debug session ends.`,
Run: dapCmd, Run: dapCmd,
ValidArgsFunction: cobra.NoFileCompletions, ValidArgsFunction: cobra.NoFileCompletions,
} }
dapCommand.Flags().StringVar(&dapClientAddr, "client-addr", "", "host:port where the DAP client is waiting for the DAP server to dial in") dapCommand.Flags().StringVar(&dapClientAddr, "client-addr", "", "Address where the DAP client is waiting for the DAP server to dial in. Prefix with 'unix:' to use a unix domain socket.")
must(dapCommand.RegisterFlagCompletionFunc("client-addr", cobra.NoFileCompletions)) must(dapCommand.RegisterFlagCompletionFunc("client-addr", cobra.NoFileCompletions))
// TODO(polina): support --tty when dlv dap allows to launch a program from command-line // TODO(polina): support --tty when dlv dap allows to launch a program from command-line
@ -463,7 +463,8 @@ Some backends can be configured using environment variables:
* DELVE_DEBUGSERVER_PATH specifies the path of the debugserver executable for the lldb backend * DELVE_DEBUGSERVER_PATH specifies the path of the debugserver executable for the lldb backend
* DELVE_RR_RECORD_FLAGS specifies additional flags used when calling 'rr record' * DELVE_RR_RECORD_FLAGS specifies additional flags used when calling 'rr record'
* DELVE_RR_REPLAY_FLAGS specifies additional flags used when calling 'rr replay' * DELVE_RR_REPLAY_FLAGS specifies additional flags used when calling 'rr replay'
`}) `,
})
rootCommand.AddCommand(&cobra.Command{ rootCommand.AddCommand(&cobra.Command{
Use: "log", Use: "log",
@ -581,12 +582,7 @@ func dapCmd(cmd *cobra.Command, args []string) {
} }
cfg.Listener = listener cfg.Listener = listener
} else { // with a predetermined client. } else { // with a predetermined client.
var err error conn = netDial(dapClientAddr)
conn, err = net.Dial("tcp", dapClientAddr)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to connect to the DAP client: %v\n", err)
return 1
}
} }
server := dap.NewServer(cfg) server := dap.NewServer(cfg)

@ -922,6 +922,53 @@ func TestDAPCmdWithClient(t *testing.T) {
} }
} }
// TestDAPCmdWithUnixClient tests dlv dap --client-addr can be started with unix domain socket and shut down.
func TestDAPCmdWithUnixClient(t *testing.T) {
tmpdir := os.TempDir()
if tmpdir == "" {
return
}
listenPath := filepath.Join(tmpdir, "dap_test")
listener, err := net.Listen("unix", listenPath)
if err != nil {
t.Fatalf("cannot setup listener required for testing: %v", err)
}
defer listener.Close()
dlvbin := getDlvBin(t)
cmd := exec.Command(dlvbin, "dap", "--log-output=dap", "--log", "--client-addr=unix:"+listener.Addr().String())
buf := &bytes.Buffer{}
cmd.Stdin = buf
cmd.Stdout = buf
assertNoError(cmd.Start(), t, "start dlv dap process with --client-addr flag")
// Wait for the connection.
conn, err := listener.Accept()
if err != nil {
cmd.Process.Kill() // release the socket file
t.Fatalf("Failed to get connection: %v", err)
}
t.Log("dlv dap process dialed in successfully")
client := daptest.NewClientFromConn(conn)
client.InitializeRequest()
client.ExpectInitializeResponse(t)
// Close the connection.
if err := conn.Close(); err != nil {
cmd.Process.Kill()
t.Fatalf("Failed to get connection: %v", err)
}
// Connection close should trigger dlv-reverse command's normal exit.
if err := cmd.Wait(); err != nil {
cmd.Process.Kill()
t.Fatalf("command failed: %v\n%s\n%v", err, buf.Bytes(), cmd.Process.Pid)
}
}
func TestTrace(t *testing.T) { func TestTrace(t *testing.T) {
dlvbin := getDlvBin(t) dlvbin := getDlvBin(t)