codelldb icon indicating copy to clipboard operation
codelldb copied to clipboard

code --open-url does not work inside docker container (vs-code server)

Open JanJamaszyk-FlyNow opened this issue 4 years ago • 8 comments

When executing code open-url using vs-code remote containers (https://code.visualstudio.com/docs/remote/containers) to communicate with the debugging extension I get the foillowing error:

$ code --open-url
Ignoring option open-url: not supported for code.
At least one file or folder must be provided.

My expectation is that open-url is not supported in the vs-code server version. Is there anything we can do about that? This is what help tells me:

$ code --help
code 1.52.1

Usage: code [options][paths...]

To read from stdin, append '-' (e.g. 'ps aux | grep code | code -')

Options
  -d --diff <file> <file>           Compare two files with each other.
  -a --add <folder>                 Add folder(s) to the last active window.
  -g --goto <file:line[:character]> Open a file at the path on the specified line and character position.
  -n --new-window                   Force to open a new window.
  -r --reuse-window                 Force to open a file or folder in an already opened window.
  -w --wait                         Wait for the files to be closed before returning.
  -h --help                         Print usage.

Troubleshooting
  -v --version Print version.
  -s --status  Print process usage and diagnostics information.

JanJamaszyk-FlyNow avatar Jan 04 '21 07:01 JanJamaszyk-FlyNow

Well, technically, "--open-url" is an implementation detail, it isn't documented as a valid option in vscode --help. xdg-open <uri> should have worked though (on Linux), but it doesn't...

vadimcn avatar Jan 05 '21 00:01 vadimcn

https://github.com/microsoft/vscode-remote-release/issues/4260

vadimcn avatar Jan 05 '21 01:01 vadimcn

Please upvote the linked issue if you'd like this fixed.

vadimcn avatar Jan 07 '21 17:01 vadimcn

Hi, I managed to solved this using the rcp server alternative (as documented here: https://github.com/vadimcn/vscode-lldb/blob/v1.6.5/MANUAL.md#rpc-server). It's really awesome, thanks!

@vadimcn , I just have one question, in the docs you say about :

Unfortunately, starting debug sessons via the "open-url" interface has two problems:

  • It launches debug session in the last active VSCode window.
  • It does not work with VSCode remoting.

For me, the rcp server solution keeps connecting to the wrong window. Is there a way I could make it target the right window? Even when I make sure that the correct window is 'active', it still connects to the wrong window. My case is perhaps a bit peculiar, as I use git worktree to have multiple branches of the same repo open in different folders (this way I can work on multiple projects in a repo in parallel). But each copy of that shares the same .vscode settings, so unfortunately, differentiating each window by e.g. port number (or token?) isn't ideal...

For those who are curious, I've got it running with bazel using this as --run_under script:

#!/usr/bin/env python3

import json
import os
import socket
import sys

def send_codelldb_config(hostname, port, config):
    encoded_config = bytes(json.dumps(config),encoding="utf-8")

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        s.connect((hostname, port))
        s.sendall(encoded_config)
        s.shutdown(socket.SHUT_WR)
        data = s.recv(1024)
        print("Received: {}".format(data))
    finally:
        print("Connection closed.")
        s.close()

config = {}
config['program'] = sys.argv[1]
config['args'] = sys.argv[2:]
config['env'] = dict(os.environ)
config['token'] = 'secret'
config['sourceMap'] = {'/proc/self/cwd': '${workspaceFolder}'}
config['cwd'] = os.getcwd()
config['relativePathBase'] = os.getcwd()

send_codelldb_config("127.0.0.1", 12345, config)

koenlek avatar Aug 12 '21 02:08 koenlek

Sorry, but this feature is designed assuming you have a unique rpc server configuration per window. You can have a separate .vscode subdirectory in each worktree, can't you?

vadimcn avatar Aug 12 '21 07:08 vadimcn

I see, that makes sense... The settings are in fact symlinked into the worktrees (like shared dotfiles), so editing it in one worktree also edits it in the other 🤔. I'm trying to come up with ideas for workarounds, but I'm not seeing a lot of possibilities...

I guess the plugin spawns a tcp server as soon as it sees the rcp settings, right? So if I have multiple windows, whoever sets up the server first (or last?) is going to receive all the requests, right?

How about making a command > LLDB: Restart RCP Server or > LLDB: Kill RCP Server? If we could restart with tcp socket option SO_REUSEADDR, then I think we should be good, becomes then whoever restarted last should claim the address (ip:port).

Note that I did try already to > Developer: Reload Window, but that didn't fix it. I actually think that just adding SO_REUSEADDR would fix that. One risk of SO_REUSEADDR though is that if somebody configures a port that's already used for something else, the rpc server might break that by claiming that port... So maybe put it behind a bool config for the rcp server instead to be safe...

Does this sound reasonable? If time permits I might take a stab at it myself.

koenlek avatar Aug 12 '21 15:08 koenlek

I found the code here, though it looks like net.Socket already uses SO_REUSEADDR by default according to these docs. I'll do a bit more experimentation on my side to try and better understand this...

koenlek avatar Aug 12 '21 15:08 koenlek

Okay, so SO_REUSEADDR won't work, we'd need SO_REUSEPORT (just google on the differences, you'll need SO_REUSEPORT to be able to claim an already used ip:port combo), but SO_REUSEPORT is not exposed by the nodejs library that's being used by CodeLLDB...

I found the following workaround in case you have multiple workspaces using the same ip:port settings (assuming ip:port is 127.0.01:12345):

# Option 1: ​Kill process that currently holds it, then reload (CMD+SHIFT+P, Developer: Reload Window) the workspace that you'd like to run the RPC server.
netstat -lnp | grep 'tcp .*127.0.0.1:12345' | sed -e 's/.*LISTEN *//' -e 's#/.*##' | xargs kill

## Option 2: Close the current socket that currently holds it, then reload (CMD+SHIFT+P, Developer: Reload Window) the workspace that you'd like to run the RPC server.
Perhaps cleaner (only closes the socket, rather than killing the whole process), but requires reloading the old window that previously owned the socket. to avoid flooding the lldb plugin console in vscode with warning messages)
sudo ss -lnK src 127.0.0.1:12345

In addition to this workaround, it could perhaps we useful to add a command like: LLDB: Stop RPC Server and LLDB: Start RPC Server to help resolve conflicts of socket ownership...

koenlek avatar Aug 26 '21 03:08 koenlek