devtools icon indicating copy to clipboard operation
devtools copied to clipboard

Cannot access DevTools when running debug executable on Windows

Open Markus43 opened this issue 2 years ago • 15 comments

I would like to use DevTools to debug on a remote device. Both my development host and my remote device are running on Windows.

I want to do this because my remote device is a low end device with very limited resources, so installing both Visual Studio toolchains and a flutter SDK on that device is not likely to work properly, given a low amount of RAM (4GB) and only a few GB of free disk space.

In order to do that, I would like to start a debug build of my application on the remote device, watch the output to catch the URL to connect to, and then connect to devtools via a web browser.

When opening this url, I get the following message as pure text in my web browser:

This VM does not have a registered Dart Development Service (DDS) instance and is not currently serving Dart DevTools.

Shouldn't DevTools always be available when running debug builds of an app?

To reproduce the error message, here are my steps. This is easily reproducible on the development host PC alone:

flutter create simple_app
cd simple_app
flutter build windows --debug
cd build\windows\runner\Debug
# start app, and redirect stdout so we can see the output URL
simple_app.exe > out.txt
cat out.txt
# stdout returns e.g. flutter: The Dart VM service is listening on http://127.0.0.1:61158/yiUohRyBvjQ=/
# now, open the given url in a browser to see the message from above

Flutter doctor output for reference:

Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel stable, 3.13.8, on Microsoft Windows [Version 10.0.19045.3448], locale de-DE) [✓] Windows Version (Installed version of Windows is version 10 or higher) [✓] Visual Studio - develop Windows apps (Visual Studio Professional 2022 17.7.6) [✓] VS Code (version 1.83.1) [✓] Connected device (1 available) [✓] Network resources

• No issues found!

Markus43 avatar Oct 27 '23 12:10 Markus43

Hey Markus when you are trying to access Devtools on your remote device, are you portforwarding the resulting port and then accessing the remote device's ip address and forwarded port from your development device?

CoderDake avatar Oct 27 '23 13:10 CoderDake

@CoderDake I don't even get that far, as I tried to demonstrate with the steps above ;-)

The steps that I listed above are all being done on my development host PC: As soon as I simply start the Debug .exe instead of doing a full "flutter run", I can't connect to DevTools anymore and get that error message that I quoted instead.

Markus43 avatar Oct 27 '23 13:10 Markus43

Hmm I don't know enough about how these are built to know whether this is possible outright then. @kenzieschmoll @bkonyi do you know enough to know whether there is a way to accomplish this by just running the built executable? My gut tells me that the flutter run might be doing a part of the plumbing to facilitate DDS being there etc.

CoderDake avatar Oct 27 '23 13:10 CoderDake

CC @DanTup in case you are aware of Windows-specific caveats here.

kenzieschmoll avatar Oct 27 '23 17:10 kenzieschmoll

I'm not sure what the expected behaviour is here, but I think there's some confusion between a VM Service URL and the DevTools app and I suspect what's reported above is the same on any platform.

Following the instructions above, the output given is a VM Service URL:

flutter: The Dart VM service is listening on http://127.0.0.1:53205/VhT4x_nJFeM=/

Accessing this in my browser gives the same message:

This VM does not have a registered Dart Development Service (DDS) instance and is not currently serving Dart DevTools.

I think this is expected. DevTools is not bundled inside the running application, so there's no instance of the DevTools app here. The URL provided is just the API for accessing the VM Service.

However, if I run dart devtools in a terminal to start DevTools and then paste that VM Service URI into it, I end up with this:

image

I'm not sure what the expectation is here - what screens should be available to a pre-built (debug) Windows desktop app?

DanTup avatar Oct 28 '23 11:10 DanTup

I think this is expected. DevTools is not bundled inside the running application, so there's no instance of the DevTools app here. The URL provided is just the API for accessing the VM Service.

@DanTup Thanks for the feedback! I did not know that, the error message makes much more sense that way. I could not find anything via google about the error message, so I thought it might make sense to open an issue at least for that ;-)

Did I understand currectly that DevTools always run on the development host, even when the debugged device is connected remotely like e.g. an android device? I'd love to read any documentation that explains how these things are working together, can you point me to any kind of documentation here? Or if such things don't exist can you point me to the source code that implements the plumbing between devtools and the application?

For my use case, I am wondering what might be the easiest approach to get it running. I even tried to configure my remote device as a"custom device". I got my app to start this way, including forwarded output of the app, but then it failed to create the GUI :-( I found out that OpenSSH Servers on Windows only work as a SYSTEM user, and a SYSTEM user is not allowed to start a GUI and not connected to a user session. I finally gave up on that because I did not find a way to work around it ...

Markus43 avatar Oct 28 '23 17:10 Markus43

Did I understand currectly that DevTools always run on the development host, even when the debugged device is connected remotely like e.g. an android device?

That's correct. Dev Tools is a standalone application that (for much of its functionality) communicates with a running Dart program's VM Service. The spec for the VM Service is at https://github.com/dart-lang/sdk/blob/master/runtime/vm/service/service.md (although it's possible for extensions to be registered - for example the Widget Inspector relies on additional services registered by Flutter that won't appear in that doc). This is the same mechanism the IDE debuggers use to communicate with the runtime (for example to add breakpoints, listen to pause events, etc.).

For my use case, I am wondering what might be the easiest approach to get it running.

Probably the first thing I would try is what you're already doing, but instead of trying to load the URI you're getting from the remote machine directly in the browser, try attaching to it from VS Code (using the Debug: Attach to Flutter... commands and pasting in the VM Service URI). That should give you a flutter tool (which is probably required for functionality like the Inspector) as well as debugging support.

I'm not certain this will work (because I don't really know what flutter build --debug is actually building) - perhaps others in this thread will know whether it should. It's probably worth a quick test though.

DanTup avatar Oct 28 '23 18:10 DanTup

For my use case, I am wondering what might be the easiest approach to get it running.

Probably the first thing I would try is what you're already doing, but instead of trying to load the URI you're getting from the remote machine directly in the browser, try attaching to it from VS Code (using the Debug: Attach to Flutter... commands and pasting in the VM Service URI). That should give you a flutter tool (which is probably required for functionality like the Inspector) as well as debugging support.

I'm not certain this will work (because I don't really know what flutter build --debug is actually building) - perhaps others in this thread will know whether it should. It's probably worth a quick test though.

I did that quick test today.

As long as I start my app from the exe on the development host, I can connect a debugger to it that way.

But things are not as easy on my remote target. I just found out that I cannot connect to the vm service url from my development PC. I just took the URL from the app output and replaced the localhost IP with the target IP. That way, I only get "connection refused" whenever I try to connect from the development host, both from "Attach to flutter ..." and from a normal webbrowser where I paste that URL. I disabled Windows Firewall on the target, so I believe the Firewall cannot be the problem.

Could it be that the VM Service access is somehow restricted to localhost on Windows?

Markus43 avatar Nov 02 '23 15:11 Markus43

I just took the URL from the app output and replaced the localhost IP with the target IP. That way, I only get "connection refused" whenever I try to connect from the development host, both from "Attach to flutter ..." and from a normal webbrowser where I paste that URL.

My guess is that the VM Service/dds is binding only to the loopback address and not the IP address you'd using from the other machine. This raises two questions... 1) can you get VM Service/DDS to bind to another port?, and 2) can you do it from a debug exe build (eg. without running via dart or flutter? Perhaps @bkonyi knows the answer?

If you have SSH set up, you could possibly tunnel the port through that, but it's a bit messier.

DanTup avatar Nov 02 '23 15:11 DanTup

Yeah, you'll need to bind to the IP of the development machine, not localhost (I think this is the default) to make it available without SSH tunnelling. I'm not sure if that's possible with the flutter tool, but for standalone Dart I think you can do something like dart run --enable-vm-service=127.0.0.1:8181 foo.dart. @christopherfujino might have a better idea of what's possible on the Flutter side of things.

bkonyi avatar Nov 02 '23 15:11 bkonyi

In this case neither the dart or flutter tools are being used, this is running the pre-built debug executable that was produced with flutter build -d win --debug. Is it possible to pass these kinds of flags to the executable (assuming it's supported in flutter)?

DanTup avatar Nov 02 '23 17:11 DanTup

@jason-simmons I saw you replying to a similar thread on Discord, so I hope it's OK to tag you here?

To sum up my remaining issue (and hopefully save everybody coming here only now some reading):

  • I want to debug on a remote, low-end Desktop Device (platform:windows, not sure if it matters ...) with no Flutter or Dart tooling installed.
  • The remote device is in a local network that I have access to. Firewall on the remote device is disabled, so port forwarding should not be needed.
  • Thanks to the very helpful replies here, I figured out that this should be possible using Debug: Attach to Flutter... in VS Code on my development machine. I verified that this works when I start a Debug executable without flutter/dart tooling on my development machine.
  • But this unfortunately doesn't work when I start the debug-built executable on a remote machine. For this, I used the vm url that I got from the app that I started, and I simply replaced the localhost IP in that URL with the IP of the remote device that I can access from my development machine.
  • I get timeouts whenever I want to connect to the remote VM service URL with the replaced IP using "Attach to Flutter" from VS Code.
  • I get the same timeouts when I simply try to load that url in a web browser.

Markus43 avatar Nov 29 '23 10:11 Markus43

I think the question boils down to how you can change the IP address that the VM Service is bound to for these builds.

@Markus43 it's not an ideal fix, but it turns out Windows can forward ports without any additional utilities, so you could try the following (it won't be convenient if the port number changes on each run, but it could at least confirm that the IP binding is the only issue).

Run these commands on the remote box that is running the app:

Replace the 192.168.0.89 with the network IP of that machine (the one you'll be using to attach to from VS Code) and both instances of 9101 with the actual port the VM Service is listening on:

netsh interface portproxy add v4tov4 listenaddress=192.168.0.89 listenport=9101 connectaddress=127.0.0.1 connectport=9101

To remove the port forwarding, again replace the IP/port to match the above:

netsh interface portproxy delete v4tov4 listenaddress=192.168.0.89 listenport=9101

Note: It'll require elevated permissions to run these commands.

DanTup avatar Nov 29 '23 13:11 DanTup

Oh, and in case it wasn't clear, forwarding the port like this allows anyone on your network to connect to the VM Service of that machine. This means anyone on your network that can connect to that IP can perform any actions the VM Service allows. If there may be untrusted actors on the network, you may want to restrict access to your own IP with a firewall :-)

DanTup avatar Nov 29 '23 14:11 DanTup

@Markus43 Sometimes If you have set up a global proxy, such as vpn, please disable the global proxy first. Then restart the IDE and try again. It works for me.

Static1014 avatar Jan 23 '24 14:01 Static1014

I'm going to close this since there hasn't been any new activity in a while and the previous comment indicates that this should be possible. Please re-open or file a new bug if you are still running into this. Thanks!

elliette avatar Jul 17 '24 20:07 elliette