sdk
sdk copied to clipboard
stdin stream closes unexpectedly when Dart program is spawned from a bat file (which is spawned by a NodeJS process) and an msys2 program has been run earlier in the bat file
This might not be a Dart issue, but since changing the Dart script for a NodeJS script seems to cause the issue to go away I wonder if there might at least be someone who might have a better grasp of what's happening here (I feel I've hit the limits of what I can debug).
While the title sounds quite specific, those variables all appear to be required. Some background:
- The Dart VS Code extension runs in a Node JS process
- The extension runs
flutter daemonto start the Flutter daemon device daemon, which it communicates with overstdin/stdoutto get notifications of devices being connected/disconnected (plus some other stuff useful to the editor that is implemented in thefluttertool) - The
fluttershell script runsgitas part of setting up the Dart SDK before it can run theflutter_toolsDart program
The issue we're seeing is when the version of git the user has on PATH comes from msys2. In this case, when the flutter_tools daemon starts, it gets some input from stdin from the client, but then stdin appears to close and no more input is received. The VS Code extension (NodeJS script) does not see anything change, and continues to send messages over the daemon's stdin but they are never received (and never responded to).
The issue only occurs when:
- The original client script is NodeJS (if I change this to Dart, the problem goes away)
- The daemon script is Dart (if I change this to NodeJS, the problem goes away)
- The
.batfile runs any program frommsys2prior to running the Dart script
I've created a repro with some steps here:
https://github.com/DanTup/repro-dart-code-4840
To reproduce, you'll need to be on Windows and have NodeJS and a copy of msys2 (which you can download as a self-extracting archive, it doesn't need installing - you just need to be able to run any of the .exe files from it in the fake_flutter.bat script).
The odd behaviour is almost certainly coming from msys2, but it's odd that when the daemon script is NodeJS this issue doesn't occur. This makes me wonder what Dart is seeing happen that causes it to fire the done handler for stdin (and not get any further input).
Related issues:
- https://github.com/Dart-Code/Dart-Code/issues/4840
- https://github.com/flutter/flutter/issues/143625
/cc @brianquinlan
@brianquinlan please let me know if there's anything I can to help get any more info to help track this down. It's affecting quite a lot of users according to my (admittedly limited) stats so I'm keen to try and fix, but right now I don't have any ideas for either debugging further or trying to workaround/avoid it.
I can repro the issue but I don't understand it yet.
One thing that I noticed is that the NodeJS implementation has { shell: true } while the Dart version has runInShell=false.
Setting the runInShell=true, does not change the result.
Thanks for looking, it had me scratching my head for a while but I didn't know where to go next with it and hoped someone else would be able to dig a bit deeper 😄
while the Dart version has
runInShell=false.
I probably didn't specify it explicitly because runInShell is implied when the script being run is .bat:
https://api.dart.dev/stable/3.5.4/dart-io/Process/run.html
NOTE: On Windows, if executable is a batch file ('.bat' or '.cmd'), it may be launched by the operating system in a system shell regardless of the value of runInShell. This could result in arguments being parsed according to shell rules.
@brianquinlan I don't supposed you had chance to look at this any deeper? While it's easy to work around for Flutter users (have an official Windows git on PATH before any msys2/devkitpro version), it's difficult to understand and track down the issue to know where to look.