-
Notifications
You must be signed in to change notification settings - Fork 8.4k
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
cmd.exe always hang if calling SetConsoleScreenBufferSize at bottom line #1976
Comments
I sent PR to vim/vim. vim/vim#4679 I cound avoid hang with moving cursor to top of window before calling SetConsoleScreenBufferSize. |
Now, I could reproduce this with the code above. But seems to depend on some conditions. |
I attached conhost.exe with gdb.
|
This is a line crashed. |
I guess that the cause of this bug is related on cursor location. If the cursor position is out of bounds of RESIZED size, cmdhost.exe crash. |
@DHowett-MSFT Did you get enough information to fix this issue? |
@mattn, I've tried to reproduce this today and cannot get it to happen. Does it still happen for you? Can you provide a crash dump from the conhost on your machine that is crashing? |
This is dump file of conhost.exe |
This dump file shows two normal-state threads inside What's odd here is that there's no input thread. I would expect at least 3. I would suspect that perhaps you've grabbed a dump of the wrong conhost.exe if there were multiple. Given it's a crash issue, I might be able to find your crash report if you submit feedback with the feedback hub. I'll trigger the bot to give you directions for that. |
/feedback |
Sorry, I mistaken. When this bug occur, conhost.exe is always exited so I can not get dump. But when I used gdb, I could get stacktrace above. |
I can reproduce this fairly easily in the debugger (or at least a very similar issue). The trick, in my case, is to have the Wrap test output on resize option unchecked in the Layout properties. Then the easiest way to trigger it is with a
The In the debugger I can see that it's crashing when trying to paint the cursor while out of bounds (the buffer width is 40, while the y pos is at 80). Here's the key part of my call stack (on commit 4b439cf):
I'm almost certain I've had this crash with a manual resize as well, although I haven't now been able to reproduce that. |
I found another easier to reproduce crash, which I think is different to the one I gave above, but possibly closer the OPs crash. It doesn't depend on the Wrap test output on resize option being unchecked, but it does seem necessary to fill the screen buffer to trigger it. Steps to reproduce:
This crashes for me every time in the current master build (32ea419), although not in the system conhost (ver 10.0.18362.535), so this may be a regression. |
Alright, @j4james, thanks. I'll get back around to this at some point. |
As @mattn hinted, the issue can be worked around by setting the cursor position to (0, 0) before resizing the buffer. It still crashes if the console is resized to the minimum allowed, but that is less likely to happen. Another workaround is to |
I've been doing some digging into this, and found there were two underlying issues: 1) the cursor position being out of range, and 2) the viewport being out of range. Issue 1 has largely been addressed by PR #4901, which added bounds checking on the cursor position. That fixed my first test case. Another partial "fix" came in commit eb480b6, which added exception checking on the It's also worth mentioning that this exception check doesn't catch all exceptions under the The main outstanding problem, though, is the viewport being out of range. That can be triggered from a number of different places: the The last of these is fairly easy to fix. The error is in the The other two only seem to fail when viewport wrapping is disabled. The problem comes from resizing the buffer in such a way that that viewport extends past the bottom or right. When the wrapping is enabled, the Now I don't want to mess with the I can't be certain this will fix every possible resize exception, but it should at least be a major improvement on the current state of affairs. |
After testing this some more, I found that fixing the viewport wasn't enough by itself. We also need to make sure the cursor position is clamped to the new buffer dimensions, otherwise there are still situations in which conhost can crash. I had hoped we were clamping the cursor to the viewport in enough places to make that unnecessary, but it seems not. So in addition to the changes discussed above, I'm also recommending we clamp the cursor position in I've already starting putting together a PR with these changes, but there's not a huge amount of work involved, so if you think this is the wrong approach, it's not a big deal to drop it and try something else. |
I'm alright with your proposals, @j4james. I think it's just a bunch of little things that slipped through the cracks here, so I'm happy to take the fixes. If you did want to tackle the My long term goal has always been to try to move everything to standard rectangle math (bottom and right are exclusive to match what everything else does instead of the crazypantsness that Console did forever with SMALL_RECTs being inclusive bottom/right) and I think this particular area is suffering from the mismatch pretty heavily. My first attempt was |
This fixes a number of exceptions that can cause conhost to crash when the buffer is resized in such a way that the viewport or cursor position end up out of bounds. Technically this is a fix for issue #256, although that has been closed as "needs-repro". The main fix was to add checks in the `SetConsoleScreenBufferSizeImpl` and `SetConsoleScreenBufferInfoExImpl` methods, to make sure the viewport doesn't extend past the bottom or right of the buffer after a resize. If it has overflowed, we move the viewport back up or left until it's back within the buffer boundaries. We also check if the cursor position has ended up out of bounds, and if so, clamp it back inside the buffer. The `SCREEN_INFORMATION::SetViewport` was also a source of viewport overflow problems, because it was mistakenly using inclusive coordinates in its range checks, which resulted in them being off by one. That has now been corrected to use exclusive coordinates. Finally, the `IsCursorDoubleWidth` method was incorrectly marked as `noexcept`, which was preventing its exceptions from being caught. Ideally it shouldn't be throwing exceptions at all any more, but I've removed the `noexcept` specifier, so if it does throw an exception, it'll at least have more chance of recovering without a crash. ## Validation Steps Performed I put together a few test cases (based on the reports in issues #276 and #1976) which consistently caused conhost to crash, or to generate an exception visible in the debug output. With this PR applied, those test cases are no longer crashing or triggering exceptions. Closes #1976
This fixes a number of exceptions that can cause conhost to crash when the buffer is resized in such a way that the viewport or cursor position end up out of bounds. Technically this is a fix for issue #256, although that has been closed as "needs-repro". The main fix was to add checks in the `SetConsoleScreenBufferSizeImpl` and `SetConsoleScreenBufferInfoExImpl` methods, to make sure the viewport doesn't extend past the bottom or right of the buffer after a resize. If it has overflowed, we move the viewport back up or left until it's back within the buffer boundaries. We also check if the cursor position has ended up out of bounds, and if so, clamp it back inside the buffer. The `SCREEN_INFORMATION::SetViewport` was also a source of viewport overflow problems, because it was mistakenly using inclusive coordinates in its range checks, which resulted in them being off by one. That has now been corrected to use exclusive coordinates. Finally, the `IsCursorDoubleWidth` method was incorrectly marked as `noexcept`, which was preventing its exceptions from being caught. Ideally it shouldn't be throwing exceptions at all any more, but I've removed the `noexcept` specifier, so if it does throw an exception, it'll at least have more chance of recovering without a crash. ## Validation Steps Performed I put together a few test cases (based on the reports in issues #276 and #1976) which consistently caused conhost to crash, or to generate an exception visible in the debug output. With this PR applied, those test cases are no longer crashing or triggering exceptions. Closes #1976 (cherry picked from commit 9a07049)
🎉This issue was addressed in #8309, which has now been successfully released as Handy links: |
🎉This issue was addressed in #8309, which has now been successfully released as Handy links: |
Environment
Steps to reproduce
Sorry, I don't figure out clearly but this step always make cmd.exe hang. At present, the method that can be reliably reproduced is to start vim.exe at the bottom line of cmd.exe.
Expected behavior
Do not hang.
Actual behavior
Hang.
FYI, I tried to run this code, but not reproduce.
The text was updated successfully, but these errors were encountered: