-
Notifications
You must be signed in to change notification settings - Fork 47
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
On Windows 10, at launch of LLDB, program is unable to access stdout or stdin #309
Comments
|
argg, @adam-fowler , I just saw your comment of yesterday. I did check for any follow-up from you or @compnerd on #301 just before creating this issue 309, but alas, I was looking at a stale view. So, for good or bad, I've already created this issue, so I am going to paste your reply here, and then let's continue any discussion of this issue here, in 309.
|
|
Hmm, I don't see how lldb would create a new console for the application, it does a standard process creation AFAIK. What is standard lldb here for context? Is it the lldb from llvm.org? Built at what revision? |
|
I am trying to reproduce Adam's case:
but I get different results. when I put the standard lldb foremost in my PATH, I get: my standard lldb is installed in: and that is the same lldb.exe that Run > Start Debugging calls (per Process Explorer). This was installed by the LLDB extension for VS Code. That lldb\bin dir also contains its own copies of these python files: python3.dll and python39.dll. These are pulling io.py from my python 3.10 install (even when I remove that from the PATH). I won't be able to shed any light on standard lldb's behavior on my machine unless I can get it to ignore python310 folders. |
|
also, Adam said
but that differs from what I see - no output is directed to the newly opened window. |
|
A thought: since commenting out the "lldb.library" entry in settings.json makes things work as expected (stdout and stdin are in VS Code's 'Terminal' pane), could we assume that whoever is processing that setting is messing up the redirecting of stdout and stdin to the Terminal pane? And would that be some component of the LLDB extension? |
When I say standard LLDB I mean the one that is packaged with vscode-lldb. Looking at the commit comments from vscode-lldb this would be from https://github.com/llvm/llvm-project, build id 1927 (not totally sure what build id indicates though).
Sorry you are right when run via vscode-lldb no output is display to the window.
You need to resolve your python issues before you can compare the results. As I said above the two versions of lldb when run from the command line react differently. We need to resolve this before looking at vscode-swift/lldb. |
|
Thinking about this a bit: the new window might be the result of I think that we should look at how the inferior is launched. I suspect that this might be a bug in lldb-server. One quick test would be to try a “remote” (it can be run on the same host) debug session with ds2 (https://github.com/compnerd/ds2). |
yes, agreed, and I believe that is a valid technique to achieve clarity, i.e., when lldb is run as a CL tool, it would want the debugger commands and cmd outputs to be segregated from the program's interactions with the user, so 2 consoles is a good way to accomplish that.
yes, agreed. I had updated my notes, perhaps after you read the initial notes, to indicate the same. I have a couple ideas and will report back. |
|
I was able to get the standard LLDB to ignore my python310 folders, by doing: This is in addition to the previous change to add the standard lldb foremost in my PATH, so that the one under C:\Library is not seen. With all that, the standard LLDB had the identical behavior described by Adam:
I.e., the program output and input are intermingled with the LLDB command output and input: So, clearly the Swift custom LLDB was changed to enable 2 separate consoles, one for LLDB and one for the program. I hope this helps. Possibly that may have to be undone in order to get Swift custom LLDB working under VS Code. However, my own 2 cents would be that the optimal solution would be to fix the stdout/stdin redirecting while retaining the 2 separate consoles. Otherwise we are left with choosing between (A) cmd line LLDB working great with 2 consoles and VS Code-based debugging not working, or (B) the latter working and the former being degraded somewhat to 1 intermingled console. Thanks for considering. |
I will try this next. |
|
@compnerd, I see on your ds2 page that I do not have any of the many build tools listed there, and I would really prefer not to install a bunch of things and then uninstall them later, because of all the remnants that will leave. Might you have a build that I could download and run on my Windows 10 machine? Thanks. |
|
The only bits that you should need to install is Visual Studio; Visual Studio already provides CMake + Ninja. The only other dependency is flex and bison which is part of WinFixBison (which is why it is referenced), which doesn't need any installation. That said ... https://github.com/compnerd/ds2/suites/5881671150/artifacts/198772803 or https://github.com/compnerd/ds2/suites/5881671150/artifacts/198772802 from a recent CI run should foot the bill |
|
Thank you for that prebuilt 64-bit binary! That save a lot of time and avoided the post-uninstall crud. I ran ds2 per the ds2 github page, and have some partial results. You didn't say exactly what you were looking for, so I'll just describe the whole session: I ran the ds2 server in one command prompt and the lldb client in another. I had server prog crashes at first, suspected the port number, relearned about that, and found that 50000 worked. At repeated trial runs, the failed ones usually caused the port number to be made unavailable and on a subsequent re-use of that port, it caused server ds2 to crash at connection to client time. Going to the next port number worked for a while, but eventually no port number was workable (server always crashed). But one or two tries had some success, shown below. server window - ds2-> ds2 gdbserver localhost:50002 "K:\Kim Shared\CodeLab\SwiftTests\hello.build\debug\hello.exe" Notes:
client window - lldb-> lldb "K:\Kim Shared\CodeLab\SwiftTests\hello.build\debug\hello.exe" Notes:
So, even though I never got remote debugging fully working, was this informative enough to give you clues? If not, I can retry - would you have any thoughts on likely causes for the client error? |
|
@compnerd and @adam-fowler, Was there anything more I can do to help gather information on this? Or, are we thinking that we can't yet identify which project this should be submitted to? e.g.:
If we don't know, should I submit it to vadimcn/vscode-lldb because that component is issuing the errors above, in 'Actual Behavior'? it would at least be a place to start. Any guidance would be much appreciated. |
|
Hmm, that is interesting. It sounds like even without lldb in the picture, the standard input is ignored? I think that this is sounding more like a Swift runtime issue rather than lldb - it seems like the stream isn't being setup. It may be interesting to a) set a breakpoint on main and see what the stdin handle is setup to b) possibly see if procmon helps see what is going on in the setup? |
|
BTW, the re-start issue is related to sockets - there is a small timeout associated with sockets that needs to elapse. You can use the |
actually, in that case, std in and std out are handled just fine by the program on its own. noted above in "Variations":
Sure, I will try these. |
|
I added these statements to the top of program: Running at the cmd prompt (no LLDB) gives this output: Running via VS Code > Run > Start Debugging, and stepping through the 3 initializations, gives this, using 'v myStdIn' (gives same results as hovering over myStdIn): and 'v myStdOut' gives: |
|
It seems reasonable - perhaps compare the value to the handle from C ( |
|
Will do. Meanwhile, I ran ProcMon and after filtering out all unrelated processes, during the 9 seconds after Start Debugging, I have 15,000 lines, all from swiftc (starting the debug kicks off a quick build to ensure bld is uptodate), swift-build.exe, swift-frontend.exc, codelldb.exe, code.exe, swift.exe, conhost.exe, cmd.exe. A bit of a jungle, not sure which of them is safe to filter out. |
|
In short, the Swift handles are equal to the C handles. I added a C DLL to the Swift main prog. Code: Running the program in the debugger: I also ran the program at the cmd prompt (no LLDB), but that output was not helpful - all values were nonzero (good), but no handle values are shown in the Swift print stmt. But the above at least shows us the handles are identical in the debug environment. |
|
Ugh, wait, I wonder if you are running into a "feature" of lldb. One thing that is really annoying about lldb is that it will screw up sometimes with redirection. I've noticed that on Windows, when running with lldb, you will need to switch windows to the lldb input and press the enter key before the inferior will accept any input. I think that should actually make this function properly. If that works, I don't really know how to replicate that with the VSCode setup, but that is likely something to do be done in vscode-lldb. Note that in my experience, you will also need to do this trick after triggering a breakpoint. |
|
OK thanks, I will experiment with that tomorrow morning. But if I remember correctly, when I remove the setting that points to the custom LLDB, the normal LLDB has correct behavior in terms of stdin/stdout. I'll reverify that as well. Have a good night! (if you're in the US) |
|
@Kim4444 when you run your application in lldb can you redirect stdout to a file using |
Ok I have verified this works as expected |
|
@adam-fowler I believe that the issue is the input rather than the output. The input is blocked by the lldb instance (which is unblocked by the return), and the inferior will accept input subsequently. I think that the descriptor might be shared? |
|
I've had a look through the vscode-lldb code and it looks like the stdio is setup here |
I have been searching for a windows build, but no luck. I'd really prefer not to get all the needed tools to build it from source (due to time, not much free disk space). Questions: Q2. Alternatively, (and I don't know git) is it feasible to compare the source code for the custom lldb vs the source code for vscode-lldb's version? or is that likely to produce volumes of differences with little chance of finding any stdin code changes? |
|
Another thought: Q3. Am I the only Windows/VS Code/CodeLLDB/custom LLDB developer to have this debugging issue? Or is this broken for all such users? Q4. Have either of you, if you've tried to reproduce the issue, had success or failure? If this scenario does work for either of you, that shines a whole different light on it. |
|
I thought I'd look on YouTube for uses of LLDB from the command line, to see if LLDB and the user program shared a window for stdio (like CodeLLDB's LLDB), or if they each had their own window (like the custom LLDB): In 2 demos, one for a Mac and one for Linux, both processes shared 1 window. Q5. Is it possible that the custom LLDB would work better under VS Code if it too allowed lldb i/o and user program i/o to share one window? |
|
@compnerd, @adam-fowler, any thoughts on Questions 1-5 above? And I'll add: Q6. Does it seem reasonable to move this issue to the custom LLDB? Thanks! |
I’m not convinced that this has anything on the lldb side and it’s more likely that the plugin has some assumptions. IIRC the Swift extensions are for the language support (integration of the compiler in the interpreter, expression evaluation) which wouldn’t impact the shell itself. Diffing the code bases might find what the difference is in the shell. |
Interesting. How well does WinDbg handle the display of Swift variables (Int, String, objects)? I recall that the LLDB shipped with the CodeLLDB extension did not handle them, it displays "Unable to determine byte size". |
Sadly, it's about the same. However, that is due to the quality of the debug info we current generate. I think that we should be able to handle this appropriately and emit the needed debug info which would allow us to see the values rendered properly. |
In BriefFirst I tried to look at the uses of 'lldb.library' in the source for CodeLLDB extension. After a fairly quick look, nothing jumped out at me that would suggest it was handling a custom LLDB differently than the default LLDB in terms of stdio, but it was not thorough by any means. Next, I tried to identify the source for the LLDB packaged with CodeLLDB, and the source in the Swift custom LLDB. I downloaded both, and diff'ed them, recursively. There were 29,000 lines in the diff output (wow!); 68 lines contain either stdin or stdout. Details1. CodeLLDBThe source I used for looking at uses of 'lldb.library'...
2a. version of LLDB used by CodeLLDBThe source I used in the comparison...
2b. Swift Custom LLDBThe source I used in the comparison...
2c. diffingdiff -r lldb-14.0.0rc2.src\source lldb-llvm-project-swift-5.7-DEVELOPMENT-SNAPSHOT-2022-05-04-a\source > lldb-14.0-CodeLLDB--lldb-5.7-SwiftCustom.txt Final ThoughtsThe 68 lines of stdio diffs are perhaps due to changes made to LLVM's LLDB at some point after the Swift custom version was branched off. Or they were made to the Swift custom branch after branching from the LLVM source (and I understand you think this very unlikely). Or, undetected here, there were other changes made to CodeLLDB's copy after getting a snapshot from LLVM (is this at all likely?). Or a combination. At any rate, to me, even without understanding the 68 lines or the context, their presence itself seems enough to warrant moving the focus to these LLDB diffs, before looking further into the CodeLLDB extension. With any luck, it might mean that the fix will be to merge some/all recent LLVM LLDB changes into the Swift custom LLDB. @compnerd, thoughts on that? I can make my diff file available, just LMK if you want that. |
|
The 14.0.0 RC release is significantly further ahead. We really should take a look at the branch point and ensure that the LLDB build at the branch point works identically from llvm.org and swift.org (that will require building LLDB at both points - a prebuilt binary won't exist for the llvm.org version). If you really think that this was fixed recently, testing with the rebranch snapshot is a good way to get a newer LLDB (https://ci-external.swift.org/job/oss-swift-rebranch-windows-toolchain-x86_64-vs2019/353/artifact/build/artifacts/installer.exe is pretty recent). If the diff is just 68 lines, that seems tractable to go through and figure out if it may be responsible. If there is no dependency on clang or LLVM APIs, it might even be possible to backport. |
|
Sure, I can test with that snapshot! I was too late to grab that, so I got #374. To clarify: does 'rebranch' mean this snapshot has all changes that were committed to LLVM's LLDB since the original branch point that created the custom LLDB? |
|
"rebranch" is just a name, the Swift toolchain is a fork of LLVM and will merge changes periodically. This is one of this point, where it syncs up with upstream at a point and is stabilized again. |
I have finally tested with the rebranch snapshot (version 5.8-dev, number 374), and that failed:
Thus, no improvement on case 1. Note: if anyone retries this, an install of Python 3.7 is required. Sigh. |
|
@adam-fowler I think that is a bad choice. Overall, the debugger currently at least provides local variables and does provide stack traces. I don't think that the stdio access issue warrants the removal of getting useful stack traces. |
|
@adam-fowler I agree with @compnerd. I have been rotating between the swift custom lldb, the lldb packaged with CodeLLDB, and using the swift custom lldb from the command prompt, all depending on the needs of whatever program I am debugging. Some progs for example do not use stdio much and in that case having good local variable display is a good thing. Meanwhile, my next step is to contact the CodeLLDB folks to see if they had removed/modified the handling of stdio in their local fork, due to something I saw in that fork. |
|
Does the broken stdio break the test explorer? |
|
@adam-fowler I don't believe it does. I was able to report the failure with 5.8 and the test explorer because it stopped working, which was rather unfortunate. I had been able to use that to debug individual tests, which was rather convenient. |
|
Yeah that was because of a change to SwiftPM that broke listing tests without building. I was hoping that could get fixed quickly. I'll chase it up. |
|
@compnerd and @adam-fowler, one year later: some good news! I have upgraded to Swift 5.9 and confirmed the problem still exists, i.e.: The good news is that I just found a tolerable workaround using attach:
launch.json: (note that request = attach) Note that this workaround might well have worked on the versions of a year ago - I did not restore them and check. I.e., it may be that no fixes were made in the last year to get this workaround to work. So, I just wanted to report this to help any users of Swift on Windows, and for maintainers in case it sheds any new light. I am still hopeful someone might be able to isolate the problem to the Swift extension, the CodeLLDB extension, or the custom LLDB, and then to fix things so that the initial readline() and attach will not be necessary - i.e. that a launch will work. If/when anyone thinks this should be moved to a different github repo, please LMK. Thanks! Environment (differs from Env at original posting)Swift 5.9 on Windows 10 |
|
@gandalfas I'm now thinking that this is actually related to CodeLLDB. Fortunately, this is easy to resolve: stop using CodeLLDB. We are looking to migrate to a new DAP on Windows, which is already available in the preview release. There is a bug in LLDB that will hopefully be resolved soon. There are other issues with CodeLLDB that have been noticed (e.g. |
|
Hi @gandalfas The LLVM codebase actually has a debug adapter (DAP) for VSCode. This is not included in the macOS or Linux toolchains, but is in the Windows Swift toolchain. I have done a pre-release of the Swift extension that uses this DAP. You can use this by installing the swift extension pre-release and then go to the settings and select I would be interested in your experiences with running this instead of CodeLLDB |
|
haha @compnerd beat me to it |
|
Thanks for your work on this!! I'm not seeing any improvement. From ProcessExplorer I can see that codelldb.exe from my vscode\extensions\vadmcn.vscode folder is still invoked when I hit F5 (and that is bad, right?). Details: I must be missing a step? |
|
Did you set the settings? Have you got custom launch.json entries? Open launch.json and change |
|
Yes, I have a launch entry. I made the change you gave, but I still have been unsuccessful. I've deleted the swift extension and codelldb extension subfolders after uninstalling them in VSCode. Then installed the preview swift extension. Then at start-debugger time, still getting no output in the blank cmd prompt. Here is my launch config: I suspect that since I did not initially have "type" set to "swift-lldb", there may be other entries that I am missing? I noticed many other debugger-oriented settings are displayed by a dropdown when I am editing the launch.json file. Perhaps their default values are not working? |
|
No, I don't know off hand why it would do that. |
Issue Description
On Windows 10, at the launch of Swift's custom LLDB by the Swift extension for VS Code (vscode-swift), the user program's output from the 'print()' statement is nowhere to be seen, and the attempt to do 'readline()' gets an EOF result.
The issue seems most likely to be in the Swift extension for VS Code, or possibly in the CodeLLDB extension. This is based on the 'Variations' section, below.
This is in the global settings.json file, which correctly points to the Swift custom LLDB:
Discovered during work on #301.
Let me know if you need me to provide any additional information.
Environment
OS: Windows 10
VSCode version: 1.67.1
Swift extension version: 0.5.2
CodeLLDB version: 1.7.0
Compiler: Swift 5/04/22 'latest snapshot of main': swift-DEVELOPMENT-SNAPSHOT-2022-05-04-a-windows10.exe
Test Case
md hello
cd hello
swift package init --type=executable
place these lines into main.swift:
open folder with VS Code
compile with: Terminal > Build Debug hello
hello.exe is built.
set a breakpoint on 'Hello,world' line.
click Run > Start Debugging, and then step through the program.
Expected Behavior
This expectation is based on one of the 'Variations' - see below. At this point you should see the following in VS Code's lower pane > Terminal tab. When the prompt "enter something" appears, you should be able to enter text, for example "abc". Control should skip over the 'else' to the print statement at the bottom of the program. At the end of execution, the Terminal tab should show:
Actual Behavior
A new command prompt window is created, titled with 'hello.exe'. It remains empty throughout program execution.
The output of the print statements is nowhere to be seen - neither in the VS Code lower pane in tab 'Terminal', nor in the new empty command prompt window.
As you step over the 'readline()' statement, the program fails to wait for you to enter text, control simply falls into the 'else' part of the guard, where EOF is handled.
This output appears in the lower pane, tab 'Output', channel LLDB:
There seems to be some variability in this error log - in another similar case, shown in #301, in the comments by me starting with "Alrighty", I had this instead:
Variations
When I comment out the "lldb.library" entry in settings.json, thus forcing the standard LLDB (poorly named, I meant the LLDB packaged with the CodeLLDB extension) to be used instead of the Swift custom LLDB, then do Run > Start Debugging, the print() statement output appears in the lower pane of VS Code, in the Terminal tab; likewise, for readline(), the user enters text in the same Terminal tab. That feels like the correct behavior to me, for VSCode-based debugging. This is the basis of my expected behavior, above.
When I run the Swift LLDB from the command prompt, the program uses stdin/stdout just fine, and that occurs in a command prompt window that lldb launches for the program.
Likewise when I run the program directly from the command prompt (no LLDB), the prog uses stdin/stdout just fine in that same command prompt window.
Taking all these variations together, these indicate that the source of the problem must be in the setup done in the Swift extension as it prepares to invoke the LLDB debug adapter, or possibly the debug adapter is mishandling something when the lldb.library is set. If no objections, we propose that we begin the investigation in the Swift extension (see #301 at the bottom).
The text was updated successfully, but these errors were encountered: