How to debug remote Python script in VS Code
Asked Answered
A

4

8

I am doing Python development in Raspberry Pi. I have installed VS Code in my laptop and have installed the ssh extension. Using this I can easily connect to Raspberry Pi. While I am connected I can see that VS Code has also loaded the Python interpreter of Raspberry Pi. I can run my Python script from within the vs code but when I tried to debug the code, nothing happens.

Is it possible to remotely debug the Python script from laptop to Raspberry Pi? How can I enable this?

Antitank answered 16/8, 2022 at 17:33 Comment(0)
A
15

I have resolved this issue. If anyone wants to do remote development and debugging, follow below steps:

  1. Install remote ssh extension in VS code
  2. Once installed, you will find a green icon on the bottom left corner in vs code which allows us to connect to the remote machine.
  3. Connect to the remote machine using the standard ssh command. Alternatively, you can use ssh-keygen to generate a public-private key if you don't want to use the password at every prompt.
  4. Once you are connected to remote machine, you can open the file explorer and create any python file. When you will save this, it will get saved in your remote machine. This way you are using your machine to remotely develop code on another remote machine.
  5. Good thing about vs code is that it selects the remote machine's python interpreter so all the packages which you have installed on your remote machine will work with IntelliSense.
  6. In order to debug the code, we will use debugpy. Install this on both machine (remote & local)
  7. On your remote machine, run below command:

python3 -m debugpy --listen 1.2.3.4:5678 --wait-for-client app.py

here 1.2.3.4 is the IP of remote machine. This will start a remote debugger which will wait for a clients connection.

  1. On your local machine, in VS code open Run & Debug, add a configuration of Python: Remote Attach. Make sure that launch.json has the host as the IP of your remote machine and port as 5678.
  2. Now start debugging as normal and you will notice the code will break at first breakpoint and from here you can proceed normally as we used to do in local debugging process.

TBH, this is best feature VS code has because most of the software allows you to do remote development which is nothing but just a normal SSH but remote debugging gives you more control. I was doing some python project on Raspberry Pi and obviously cannot install VS code or pycharm on it. But with this feature now I can easily develop the code using Pi's python interpreter and debug it as well.

If anyone is having any issues, let me know. Happy to help.

Antitank answered 16/8, 2022 at 23:25 Comment(5)
Note that this solution requires you to open up port 5678 on host 1.2.3.4. If host 1.2.3.4 is a public facing internet host this introduces a serious security risk (or attack vector as the cool kids say). It is safer to use host localhost and (for example) port 8888 and use SSH port forwarding by adding a line like: LocalForward 8888 localhost:8888 in your ~/.ssh/config file.Rajab
I don't think localhost will work here. Localhost will connect to the machine where vscode is running while we want to connect to the machine where debugpy is running and the IP doesn't have to be a public IP, infact all of this work can be done offline without internet.Antitank
My comment mentions 'localhost' in the context of SSH port forwarding. It assumes you already have an SSH connection to the remote host where the process you want to debug is running. And it does work, i am using it myself.Rajab
@Rajab and are you able to remotely debug your python scripts using this ?Antitank
Yes i am. I will put the details in a seperate answer so i can use code blocks.Rajab
R
2

This is an addition to the answer by S Andrew on this page. Remote Python debugging in Visual Studio Code is most securely done using SSH Port Forwarding. Add the following snippet to your .ssh/config file:

Host remote
     HostName remote.host.org
     User jan
     Port 1234
     LocalForward 1238 localhost:1239

Ssh into your remote host and run the program to debug as follows:

~local  > ssh remote
~remote > python3 -m debugpy --listen localhost:1239 --wait-for-client app.py

Inside Visual studio code, create a Remote Run/Debug Configuration that listens to the port localhost:1238.

Your debugging bits will flow through your SSH tunnel and the only port open on your remote host is 1234.

Rajab answered 21/12, 2023 at 17:4 Comment(3)
I have a similar set up to the OP. VSC is on my laptop and I remote debug a python script on a Raspberry Pi. Both are inside my LAN. I ssh from the laptop to the Pi using RSA key via the SSH Remote extension in VSC. Can you explain why this is more secure than simply ssh'ing in to the remote machine and specifying it's internal IP address and an arbitrary port number in launch.json and the same in the debugpy command in the remote machine?Monoplane
@Monoplane Opening up a port on your host means have a process on that host accept and handle packets that arrive through that port. This allows attackers to feed that process junk food until it croaks. SSHD was made to withstand junk food. Special purpose code like 'debugpy' was not. This makes you host vulnerable, which might not be so bad since your Pi is on your LAN. However, security is like an onion, it is all about the layers and even inner layers should be as strong as possible.Rajab
Thanks for that. I am using the SSH Remote extension with VSC. So I ssh from VSC on my laptop to my Pi. I find that I do not need to do any local port forwarding. With debugpy listening on localhost on the Pi I can specify that localhost:port socket details in launch.json and remote debug with it from VSC on my Laptop through the SSH connection. Surely it would be the same even if my Pi was outside my Lan, as long as I ssh to the remote host from the VSC SSH Remote extension then I can connect to the localhost on that remote machine via SSH, right? Unless I am misunderstanding something.Monoplane
L
1

To highly simplify the remote debugging process between two windows machines, make is universal for all IDEs and avoid SSH file permission errors on Windows, I made my own python library that solves this problem.

Just run pip install pywinrd and create those two scripts:-

Server.py

from PyWinRD.Server import WinRDServer

server = WinRDServer()
server.start()

Client.py

from PyWinRD.Client import WinRDClient

client = WinRDClient()
client.connect()

client.deploy('path/to/file/or/folder')
client.debug('path/to/python/script')
client.terminal('termninal command')

client.disconnect()

Run Server.py on the host Windows machine, and Client.py on your machine, you will have the ability to execute terminal commands, deploy extra files/folders and debug any python script you want on the host machine.

A copy of all the stdout, stderr calls on the python script you are debugging will be redirected to your machine in real-time (ex. print and raise statements).

All the stdin calls will be redirected to your machine only (ex. input statements), so the server will not interfere with them.

Lindsey answered 14/3, 2023 at 12:55 Comment(0)
M
0

It is frustrating there are so many out-dated instructions how to remote debug Python scripts from VSC.

As of August 2024 there is a far easier way to set this up that answers the OP's question which involved VSC being installed on a laptop and debugging a Python script saved on a Raspberry Pi also in the same LAN.

Once you have installed the Remote SSH extension on your local machine use that to SSH via VSC in to your remote machine. Now install the Python Debugger extension on your remote system.

Since you have ssh'd in to that remote system via the VSC extension VSC just debugs the script on that remote system as though it is LOCAL.

  1. Place a breakpoint (red dot) on the line you want script execution to stop at.
  2. From File Menu > Run > Start Debugging (F5)... The Command Palette will open and it will say:
  3. Select Debugger <-- Choose Python Debugger
  4. Then choose...
  5. Python File Debug the currently active Python File.
  6. Now use F10, F11 etc to step through the lines of code.

You DO NOT need to...

  • Do ssh local port forwarding.
  • Separately install debugpy from the command line in your local and remote environments.
  • Run debugpy from the command line.
  • Have a copy of the Python script in your local environment AND another on the remote environment. You only need ONE copy in the remote environment.
  • You don't even need a launch.json.

I checked about what sockets were opened by separately ssh'ing from a Terminal in to the "remote system" (my Raspberry Pi running Ubuntu) and they are all localhost.

ubuntu@ubuntu:~$ lsof -i
COMMAND     PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
code-f1e1 76603 ubuntu    9u  IPv4 519530      0t0  TCP localhost:43675 (LISTEN)
code-f1e1 76603 ubuntu   12u  IPv4 519534      0t0  TCP localhost:43675->localhost:34540 (ESTABLISHED)
python    77190 ubuntu    4u  IPv4 520559      0t0  TCP localhost:39819 (LISTEN)
python    77190 ubuntu    8u  IPv4 522535      0t0  TCP localhost:45381 (LISTEN)
python    77190 ubuntu    9u  IPv4 521557      0t0  TCP localhost:45381->localhost:59082 (ESTABLISHED)
python    77190 ubuntu   11u  IPv4 521558      0t0  TCP localhost:35979->localhost:37454 (ESTABLISHED)
python    77218 ubuntu    3u  IPv4 520157      0t0  TCP localhost:37454->localhost:35979 (ESTABLISHED)
python    77228 ubuntu    3u  IPv4 520164      0t0  TCP localhost:59082->localhost:45381 (ESTABLISHED)
Monoplane answered 18/8 at 21:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.