Python How to setup for Remote debugging with VSCode

eye-catch Python

Here is the official page for the remote debugging setting but it was not clear to me how to set it up until I really tried it.

Sponsored links

Add a new entry to launch.json

Firstly, you need to add a new entry to launch.json. You can copy the following entry but you can also add it by using the UI from VSCode.

{
    "name": "Python: Remote Attach",
    "type": "python",
    "request": "attach",
    "connect": {
        "host": "192.168.100.1",
        "port": 5678
    },
    "pathMappings": [
        {
            "localRoot": "${workspaceFolder}",
            "remoteRoot": "."
        }
    ],
    "justMyCode": true
},

Of course, host and port must be adjusted to your environment.

I struggled with pathMappings setting. I was not sure which path to be specified here.

{
    "pathMappings": [
        {
            "localRoot": "${workspaceFolder}",
            "remoteRoot": "."
        }
    ],
}

If the path is incorrect, the program doesn’t stop on a breakpoint.

Sponsored links

Which path should be set to pathMappings

Let’s assume the following environment.

# Local
~/myPackage/src/main.py

# Remote
~/somewhere/entry/src/main.py

VSCode on localhost open the folder ~/myPackage.

When Current directory is the same as executed file directory

The current directory on a remote server is ~/somewhere/entry/src. Run the following command for debugging. The program doesn’t start until a client connects to the debugger.

python3 -m debugpy --listen 192.168.100.1:5678 --wait-for-client ./main.py

In this case, pathMappings must be the following.

{
    "pathMappings": [
        {
            "localRoot": "${workspaceFolder}/src",
            "remoteRoot": "."
        }
    ],
}

If you start debugging from the localhost, the program stops on a breakpoint.

When Current directory is different from the executed file directory

The current directory on a remote server is ~/somewhere. Run the following command for debugging.

python3 -m debugpy --listen 192.168.100.1:5678 --wait-for-client ./entry/src/main.py

In this case, pathMappings must be the following.

{
    "pathMappings": [
        {
            "localRoot": "${workspaceFolder}/src",
            "remoteRoot": "./entry/src"
        }
    ],
}

An absolute path is also available. For example…

{
    "pathMappings": [
        {
            "localRoot": "${workspaceFolder}/src",
            "remoteRoot": "/home/usr_name/myPackage/entry/src"
        }
    ],
}

The target file is used from another file

Let’s try another case where the target file is used by another file and we don’t know where the main entry point is. It’s impossible to run the debugpy from the command line because we don’t know the entry point.

In this case, let’s add the debug code to our package. The special code is written in the official page at Starting debugging step 3.

# ~/myPackage/src/folder1/my_funcs.py
from datetime import datetime
import time


def show_message(message):
    # ---------------------------- Add this code to your package
    import debugpy

    # Allow other computers to attach to debugpy at this IP address and port.
    debugpy.listen(('192.168.100.1', 5678))

    # Pause the program until a remote debugger is attached
    debugpy.wait_for_client()
    # -----------------------------
    print(str(datetime.now()) + ": " + str(message))


def sleep(secs):
    time.sleep(secs)

Then, this code is called by another package. The program stops at debugpy.wait_for_client() until a client connects to it. As written on the official page, don’t forget to comment out the added code. The code on the localhost must be commented out like the following.

# ~/myPackage/src/folder1/my_funcs.py
from datetime import datetime
import time


def show_message(message):
    # ---------------------------- Add this code to your package
    # import debugpy

    # # Allow other computers to attach to debugpy at this IP address and port.
    # debugpy.listen(('192.168.100.1', 5678))

    # # Pause the program until a remote debugger is attached
    # debugpy.wait_for_client()
    # -----------------------------
    print(str(datetime.now()) + ": " + str(message))


def sleep(secs):
    time.sleep(secs)

The path to localRool and remoteRoot is the path where the target file exists.

Make sure that the function is actually called before connecting.

Comments

Copied title and URL