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
WSL2 support for in Cortex-Debug. Discussion and Strategy #467
Comments
Just my $0.02: I would want to be able to work in either of those two setups:
The second approach may seem more complex, but it offers the advantage that the tool environment for a project can be shrink-wrapped in a ready-made container that is described concisely with a Dockerfile that can be maintained and versioned in its own git repository. Multiple such containers can be supported in parallel for different projects, without them getting in each other's way. The problem of how GDB talks to the probe is a multifaceted one, that depends a lot on the actual probe. It will have to be a network connection of some sort. Some example scenarios are:
The first step would be to offer information on how to configure those scenarios properly, i.e. to describe what should work or what shouldn't. In this step it would be acceptable having to start some server manually, instead of having everything happening automatically when the debug button is pressed. It would also be acceptable to enter IP addresses or other settings manually depending on the local setup. The second step would be to automate this stuff as much as possible. Does this help you, @haneefdm ? |
@s13n Oh, helps a LOT, and thank you for such detail. And, a lot to think about over the weekend. Would you agree with the following?
|
I would be able to live with constraint 1, but perhaps others will disagree. I think constraint 2 is a bit too restrictive. I would say GDB server should run either where the probe is, or where GDB is. Supporting a third location would be overkill. This also supports the JLink remote server. One instance where it matters is when you use a JLink with network interface, for example the JLink Pro. You want to run the JLink GDB server where the GDB is, otherwise you end up installing the SEGGER software on both the host and in the dev container. Of course, with a USB connected probe, you have to install the respective software on the host. |
I added Constraint 2 because of the physical interface (USB) the HW connects to. This is more of a constraint to me as I have to find a solution that works in that way. And, I am not saying supporting a 3rd location at all -- sorry, if my words implied that. To summarize, the gdb-server and the HW under debug are always on the same machine, attached at the hip, so to say. It is also a generalization, beyond WIndows+WSL2. |
Well, USB isn't the only physical interface that is supported by probes, it is only the most common one (by far). Why would you restrict yourself like that? What do you gain? |
I am not restricting myself to it. It is a reality that I am stating. Once the server is not local, then it is remote. There is no in-between and I don't see WSL as an in-between thing. Maybe this is where I am wrong. I really don't care how the gdb-server connects to the HW. We got the following scenarios
It is 2/3 that we are trying to address to make it look almost like # 1. Note that we NEVER talk to the gdb-server which is why we don't care where it lives. 90+% of the time TCP ports are used and sometimes serial ports. But someone has to launch it. We never had to worry if the gdb-server is using USB or some other communication mechanism. The reason GDB is run where the compiling is done is because of pathnames embedded in the elf file. If these are not right, then breakpoints don't work, stack traces will not have references back to source code, etc. One thing we did not talk about is where is VSCode running? In my head, gdb and VSCode are running on the same machine. One reason is that all communication with GDB happens over stdio, while gdb itself may talk to the gdb-server over some connection (local or remote). Another is that this is the model GDB has chosen and has worked for over 3 decades. Btw, I the MB failed on the PC where I used to have WSL installed. It was my only PC. I ordered a PC and waiting. I normally do my testing in a VM but here that gets convoluted. Mac running Win in VM which in turn hosting WSL2. So, no experiments until next week. |
Have a look at https://code.visualstudio.com/docs/remote/remote-overview for some overview of how VS Code is used in remote mode, which includes WSL2. We are talking about a scenario where VS Code runs on Windows in remote mode. The remote OS is either the WSL2 subsystem directly, or a docker container running within WSL2. The VS Code Server runs there, the source code resides there, and the cross tools including GDB run there. The WSL2 case has the feature that you can launch Windows software from within the WSL2 subsystem. AFAIK you can't do this from within a docker container, but maybe the fact that VS Code runs on Windows provides a way to start some process there, even though the actual debugging takes place in the remote OS under control of the VS Code Server. I have no idea if VS Code helps you with that. I am relatively new with the dev container way of working with VS Code, but I already prefer working in this way, due to the simplicity of maintaining a build environment that is specific to a project. You can also run the same container on a remote machine, for example your build server, rather than locally within WSL2, and you shouldn't notice much of a difference. |
Okay, that is a very different model. I was aware of that. I will look into it while I wait, but if you see the repo for it, it has 802 issues, no commits since 5/11/2021. It is a package containing 3 extensions. Last commit was 4 months ago in those repos. Some of it is the inverse model of what I was thinking. One thing that is important to me (selfishly) is how to debug this extension itself. Without that it would be horrible. I worked a bit on the MS C++ debug adapter and it was very difficult to do any cross-platform debugging of the extension. It was like a one-man circus show to juggle multiple VSCodes running on different machines. Both VSCode and Visual Studio were needed. I can't even explain. |
@haneefdm, I think @s13n is leading you down the correct path here. I'm not familiar enough with VS Code's internal workings to tell you what is technically possible to solve the problem, but I can offer my use case and viewpoint. I'm currently working on setting up a development environment at work for using Zephyr. Our build pipeline will be all Linux based tools, but our corporate issued computers are all Windows machines. The setup differences for Zephyr between Windows and Unix based systems is painful. Ideally, I could just define a Docker image that has all the necessary build and dev tools in it and use it everywhere instead of depending on other devs to properly set up a bunch of prerequisite software. If I need to have them install a couple things like probe drivers, I can live with that. It's better than maintaining documentation on installing an entire dev environment and manually setting path variables in a locked down Windows machine. Something to consider is that even though WSL2 and Windows are running on the same physical machine, for the purpose of this issue they are effectively two different systems. WSL2 is a lightweight VM and if it properly supported USB passthrough the technical implementation might not be so complex. However, WSL2 does not currently support USB passthrough. Microsofts docs on Remote Development and Codespaces might help explain remote workspaces better. |
Good input here! Indeed, the configuration I'm interested in is:
As @haneefdm mentioned you can debug from WSL2 even today but the limitations are:
This could be easily solved since, as @s13n mentions, you can start any windows process from within WSL2. From what I have checked this is a modification in the WSL2 kernel - when you try to execute a binary with *.exe the relevant syscall is captured and passed to the host. This mean that we can launch the gdb server on the host and configure the gdb to connect to the correct remote (host) port. The whole thing is essentially a workaround on the lack of USB passthrough that won't come soon, if ever. Since this can't be done with Docker perhaps we should tackle these issues separately? |
Thank you all. My new PC is finally here. Setting it up right now and then I will be able to try stuff out myself on what works well. I am sure I can figure it out but do you know, how the client (docker or WSL) env can know what the host IP is? I was told to look in /etc/resolve.conf but that doesn't look right at least for WSL2. Especially, if the client is in bridged mode or the host is using VPN |
When using Docker Desktop for Windows, you can have the host's IP address resolved from within the container by using |
Oh, that is super nice with Docker. Thanks @s13n |
@haneefdm I think looking into |
@wobe, Thanks. Does that work if the host Windows is using VPN. Don't you see many entries in the |
Don't see much of a difference, i.e., I have the same contents in the |
I "vote" against that constraint. Just allow setting source-path directly in the launch configuration and everything is fine. |
Technically it is not a hard constraint for me. Of course, you can use source paths just like you can today. It has to do with the client-server VSCode architecture. This extension and the GDB are attached at the hip. That is the true hard constraint for me. https://code.visualstudio.com/docs/remote/remote-overview. As things stand, in one incarnation, Cortex-Debug would be classified in the "Remote OS" box (WSL, Docker, etc.) while the GUI itself would be in the "Local OS" box. That picture is not totally applicable to what we are doing, btw. Especially for where the 'Application is running'. You can also see where the Source code box is. That little green box on the bottom right of the picture above is GDB. I don't even know if that arch. is feasible for me but it is a start as a lot of groundwork has already been laid out. |
That only applies if your use VS Code Server - and as those binaries are non-free I don't use that. That's likely the reason why I commonly think of "Local OS with source and GDB", attached to "GDB Server with the process". This "simple" scenario also works quite fine since years for most setups. |
Which binaries? The VSCode server(s)? And free as in Open Source or some other meaning (costs)? In VSCode's mind 'Local OS' means the host running the UI. To me, 'Local OS' also meant "Local OS with source and GDB" but I had to teach myself a different way of thinking. VSCode is my host so, playing by the host's rules and thus terminology. I have to back and edit all my comments to make sure. |
Yes, the vscode servers. It is all about freedom, not price. This actually leads to vscode server not running everywhere I'd like it to for remote debugging (I'm not sure if it actually works in every distro one can install in wsl). |
Note: in VSCode's mind "Local OS" is also something that run's vscode in a browser: it is actually the UI. |
My team and I have been using the mentioned setup* for ½ year now, and it's great. I'm on Segger JLink tools, so I can run the segger-jlink-gdb-server in linux, and I specify an ip (on my windows host) where I have a Jlink-remote-server running. This is NOT the same as running the gdb-server on windows.
Annoyances: This is really minor: /T |
@andyinno Can you try the tools from the command line and use gdb from the command line as well. You see the exact command-line options used in the Debug Console. Btw, I have to remove your comment as this thread is not for issue submissions or asking for help. Please re-open a new issue and someone might come along and help you. Once you submit a new issue, I will remove your comment from here. If you want to tell us how to implement the remote/WSL debug then this is the right place. You are doing something this tool was not designed for -- if it works, great. |
Maybe this: |
@lagerholm Thank you so much for the info. This is great. |
Hello,
|
People are using their own gdb-init scripts to add source maps. No help from extension needed. The bigger problem is how breakpoints are set and how stack traces are interpreted. Disassembly is affected as well.. How we look for static variables is also affected -- as in we have to implement what gdb does. VSCode manages breakpoints with paths (file/line) that it sees. It wasn't clear to me how gdb handled file/line breakpoints and if clients (us) have to do the reverse mapping. Yes, a separate issue would be good but also with details of what it all means. In fact, it is more useful in a non WSL setting. cpptools/cppdbg added support for source maps. We can check to see what all they do with that info. |
I've recently been trying to solve the same for a client project. I read this entire thread and did some experimentation and here's what I came up with. In my
In the
Then, I just need to make sure the JLink Remote Server is started in Windows and running in LAN mode before launching a debug session. This could probably also be triggered from Note, that |
As far as hard constraint 1 above
I haven't seen any discussion yet about |
@aaronf-at-d5 |
It may be possible to attach USB-based debuggers to WSL via cortex-debug, that does not require any of the following:
My thought is to leverage the fact that Windows executables, when invoked from WSL, execute within the context of Windows. This means that we can invoke a GDB server on the Windows host using the cortex-debug Then the GDB client could be invoked from within WSL and attached per usual, but with some of the tricks listed above to use the correct target IP address and port - either using something like Debugging would commence as usual, and any other clients of the GDB server that you wish to attach from Windows could also operate normally. Then at the end of the debug session, the GDB connection would be cleanly closed as usual from the GDB client. To achieve all of this, I was hoping to find a way to use both the I'm thinking that the simplest way to work around that limitation, would be the creation of an
Am I off my rocker? Is there a better way of achieving what I've described above with the existing functionality of cortex-debug, or should I open a PR? |
@sullivanmj, I like where you're going with this line of thinking. The reason using |
@aaronf-at-d5 Good point about the path being mapped into WSL. I agree, it would be great to have this way of doing it natively supported by Cortex Debug. I now that I wrote that post, it appears that I didn't actually discover this first, @askariz appears to have done this with openocd. But it looks like they were invoking that separately from the launch.json. |
That's what {
"type": "cortex-debug",
"name": "Launch",
"request": "launch",
"servertype": "theServerOfYourChoice",
"serverPath": "/mnt/c/path/to/theServerOfYourChoice.exe",
"serverArgs": ["--port", "61234"],
"gdbTarget": "${env:HOSTNAME}.mshome.net:61234"
} Additionally, if this is (or will be) required, the extension can check if
Without using USB-IP or tasks most likely no. |
Hi, folks! I'm setting WSL2 with Cortex-Debug for a course and I was wondering what is the approach you recommend at this point. Should I...?
I'm not expert in VSCode plugins nor WSL, but I can try to open a PR with this change |
I'm no export in anything of those but would suggest to connect to WSL2 first (with either the SSH or WSL2 extensions; either from https://github.com/jeanp413 or, if you prefer non-free "in preview" extensions with telemetry the matching one from Microsoft) and fully debug there, with the possible need to expose your board to WSL first. |
I am getting reports that WSL2 with USB-IP works very well. In this case, you would install OpenOCD/Jlink/whatever right on the Linux side and use the Linux versions. But, make sure that your USB is working first by using various command-line tools (lsusb). You may run into firewall issues but there are workarounds for those too. Let Google be your friend. Make sure you can launch the gdb-server (OpenOCD, JLink, etc.) from the command-line first and that it recognizes your adapter/probe. |
It does work pretty well! The only issue is that students need to handle the USB attachment etc., which might be a bit confusing for them. So far I'll use the usbipd approach. If I have time I'll try to do a PR with the required changes to skip all this process and leave openOCD run on Windows while GDB is on WSL. |
@romancardenas About making the PR, you also have to handle allocating/finding the TCP ports if you are running on the Windows side. I think running the server on the Linux side is still a better option. We want things like SWO, RTT, etc. to also work. Some instructions for your students may be beneficial. |
I managed to work around the problem of J-Link software not being able to resolve the IP address In order for this to work, you need to run docker with the following argument: {
"runArgs": ["--add-host=host.docker.internal:host-gateway"]
} This will ensure that you have The second step is to resolve this hostname to an IP so that we can pass it to This can be done with the following command: $ getent hosts host.docker.internal
172.17.0.1 host.docker.internal We can further clean this command up with the help of $ getent hosts host.docker.internal | awk '{ print $1 }'
172.17.0.1 Great, now we have the IP address and it is not hard-coded. Unfortunately there is obvious way to provide this IP to the debug configuration without hard-coding it so we need a different solution. I noticed that there is a #!/bin/sh
REMOTE_JLINK_IP=`getent hosts host.docker.internal | awk '{ print $1 }'`
JLinkGDBServer -select ip=$REMOTE_JLINK_IP "$@" What this will do is to get the IP address behind the I saved this script in my Don't forget to run This exact pattern can also be used in a REMOTE_JLINK_IP := $(shell getent hosts host.docker.internal | awk '{ print $$1 }') One word of caution however is that |
I wish someone volunteers to document what works in our Wiki. We could have sections for WSL, docker, etc. I can start a Wiki Page if you want but I am not good for the content. You all know way more than me. |
If you start a Wiki page, I could contribute my previous comment as an article about using J-Link from a Docker container. |
https://github.com/Marus/cortex-debug/wiki/Working-with-WSL2-or-Docker Feel free to re-organize the page. I just started something. Maybe we want two separate pages, we can decide later. Long time ago, I was playing with Codespaces and here was my Docker configuration https://github.com/haneefdm/psoc6hello/tree/master/.devcontainer Of course not everything I have is applicable to all. |
I think my comment would fit in better with the things in |
Make sections and sub-sections as you please. I would expect some setup differences for various gdb-servers. And, edit which ever page you like. |
I think I will be using my setup for a bit to iron out some kinks. Until then, if somebody needs help, hopefully they see my previous comment. |
I have had some success with the following scenario:
It works, but single stepping is painful, and I'm not sure I like the requirement to mess with USB-IP so I will check some of the comments above and rather start st-util on the host machine and connect to the gdb-server running on the host from the container where gdb is running. Is anyone interested in my progress on this? |
I'm following. I'd be more interested had I not given up and just switched to linux desktop for at LEAST until this is all solved for Windows, which may be never. |
I have a potential solution here: https://github.com/rhempel/docker-devcontainers/tree/main/adaptabuild-example The difference from my original scenario is that now we run stlink-util on the Windows host, and get the correct IP address into the container
In
Note, the container is based on Ubuntu 22.04 and pulls in everything needed to build a simple application, plus Shpinx for docs and gcov. The Note: you might need to change ownership on ~/projects to The adaptabuild-example project is here: https://github.com/rhempel/adaptabuild-example I'm still busy getting it polished and writing a tutorial, but please let me know if this works for you :-) |
https://devblogs.microsoft.com/commandline/windows-subsystem-for-linux-september-2023-update/
|
I believe wsl, cortex debug and openocd works well together now, at least for nucleo32 boards over usb. I tried it on a Windows 11, WSL2, ubuntu 23.10, 6.2.x kernel, usbipd nightly version. Before that I updated the ST-Link firmware to the latest version. I used the openocd, customised version by STMicroelectronics, the one in ubuntu repos would work? All possible from wsl side, only windows program I had to install was usbipd. |
@xpz24, I think that much of the discussion here has been concerned with how to bridge out of WSL for the debugger. A lot of that has focused on getting the gdb server launched on the Windows side and then getting a WSL-side gdb client connected to it. I now think the better approach is, as you say, to use usbipd. There is now even a GUI for managing this. Golioth has a good article about it. |
WSL2 is next on my list. I am trying to set up a Windows machine (my previous WSL2 seems like it got corrupted). I would like people to subscribe to this Issue and comment and help test it. There are several issues and workarounds already related to this and I would like to consolidate the discussion here.
First, comments are welcome on how it should work.
The text was updated successfully, but these errors were encountered: