Crash in TextBufferCellIterator::TextBufferCellIterator() when moving cursor #4174

Closed
opened 2026-01-30 23:40:06 +00:00 by claunia · 3 comments
Owner

Originally created by @pingzing on GitHub (Sep 30, 2019).

Environment

Windows 10.0.18362.0,
Windows Terminal running in Debug mode, off commit 1caece74ab

Any other software?

The micro terminal text editor, with a few custom keybinds, as follows:

{
        "CtrlRight": "WordRight",
        "CtrlLeft": "WordLeft",
        "CtrlShiftRight": "SelectWordRight",
        "CtrlShiftLeft": "SelectWordLeft"
}

Steps to reproduce

I can easily reproduce this in micro, but I've had crashes from what miiiight be this issue in non-interactive-mode apps as well. The steps that tend to trigger this are as follows:

  1. Open micro. The shell doesn't seem to matter.
  2. Type at least one word.
  3. Move the cursor to the end of the line.
  4. With the above keybinds in place, press Ctrl+Shift+LeftArrow.
  5. Crash!

Expected behavior

The text is highlighted one word to the left. Old Conhost seems to be able to handle this.

Actual behavior

Crashiness.

Additional Information

I ran this in Visual Studio to capture some debug output. Here's the stack trace:

ucrtbased.dll!__threadid() + 101 bytes	Unknown
ucrtbased.dll!__threadid() + 515 bytes	Unknown
ucrtbased.dll!abort() + 29 bytes	Unknown
ucrtbased.dll!terminate() + 54 bytes	Unknown
vcruntime140_1d.dll!00007fff96842174()	Unknown
vcruntime140_1d.dll!00007fff96842e72()	Unknown
vcruntime140_1d.dll!__CxxFrameHandler4() + 251 bytes	Unknown
TerminalControl.dll!__GSHandlerCheck_EH4(_EXCEPTION_RECORD * ExceptionRecord, void * EstablisherFrame, _CONTEXT * ContextRecord, _DISPATCHER_CONTEXT * DispatcherContext) Line 73	C++
ntdll.dll!__chkstk() + 287 bytes	Unknown
ntdll.dll!RtlRaiseException() + 921 bytes	Unknown
ntdll.dll!KiUserExceptionDispatcher() + 46 bytes	Unknown
KernelBase.dll!RaiseException() + 105 bytes	Unknown
vcruntime140d.dll!_CxxThrowException() + 311 bytes	Unknown
TerminalControl.dll!wil::details::ThrowResultExceptionInternal(const wil::FailureInfo & failure) Line 2787	C++
TerminalControl.dll!wil::ThrowResultException(const wil::FailureInfo & failure) Line 2449	C++
TerminalControl.dll!wil::details::ReportFailure(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, void * returnAddress, wil::FailureType type, HRESULT hr, const wchar_t * message, wil::details::ReportFailureOptions options) Line 3390	C++
TerminalControl.dll!wil::details::ReportFailure_Hr(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, void * returnAddress, wil::FailureType type, HRESULT hr) Line 3451	C++
TerminalControl.dll!wil::details::in1diag5::_Throw_Hr(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, HRESULT hr) Line 4970	C++
TerminalControl.dll!wil::details::in1diag5::Throw_HrIf(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, HRESULT hr, bool condition) Line 5074	C++
--> TerminalControl.dll!TextBufferCellIterator::TextBufferCellIterator(const TextBuffer & buffer, _COORD pos, const Microsoft::Console::Types::Viewport limits) Line 48	C++
TerminalControl.dll!TextBufferCellIterator::TextBufferCellIterator(const TextBuffer & buffer, _COORD pos) Line 25	C++
TerminalControl.dll!Microsoft::Terminal::Core::Terminal::IsCursorDoubleWidth() Line 96	C++
TerminalControl.dll!Microsoft::Console::Render::Renderer::_PaintCursor(Microsoft::Console::Render::IRenderEngine * const pEngine) Line 749	C++
TerminalControl.dll!Microsoft::Console::Render::Renderer::_PaintFrameForEngine(Microsoft::Console::Render::IRenderEngine * const pEngine) Line 137	C++
TerminalControl.dll!Microsoft::Console::Render::Renderer::PaintFrame() Line 70	C++
TerminalControl.dll!Microsoft::Console::Render::RenderThread::_ThreadProc() Line 165	C++
TerminalControl.dll!Microsoft::Console::Render::RenderThread::s_ThreadProc(void * lpParameter) Line 148	C++
[External Code]	

At the time of this particular crash, TextBufferCellIterator::TextBufferCellIterator() received a pos argument with with dimensions 120x26, and a limits arg with an LT of 0,0 and a RB of 119, 9028, so altogether a [120x9029]-sized viewport.

Judging by the failure object up in WIL's ThrowExceptionInternal, the issue seems to be line 46 of textBufferCellIterator.cpp, THROW_HR_IF(E_INVALIDARG, !limits.IsInBounds(pos));.

Some further digging reveals that Viewport::IsInBounds(const COORD& pos) is violating the "pos.X < RightExclusive()" constraint. pos.X is _exactly 120, while RightExclusive() also returns exactly 120.

Just Ctrl+Arrowing around in Micro doesn't usually trigger this, although I can occasionally get crashes to occur when I'm at the extreme left edge of a line while navigating leftward. Ctrl+Shift+Arrow is extremely reliable at triggering crashes, however.

Originally created by @pingzing on GitHub (Sep 30, 2019). <!-- This bug tracker is monitored by Windows Terminal development team and other technical folks. **Important: When reporting BSODs or security issues, DO NOT attach memory dumps, logs, or traces to Github issues**. Instead, send dumps/traces to secure@microsoft.com, referencing this GitHub issue. If this is an application crash, please also provide a Feedback Hub submission link so we can find your diagnostic data on the backend. Use the category "Apps > Windows Terminal (Preview)" and choose "Share My Feedback" after submission to get the link. Please use this form and describe your issue, concisely but precisely, with as much detail as possible. --> # Environment Windows 10.0.18362.0, Windows Terminal running in Debug mode, off commit 1caece74abdae9e57642fdc3761bb432238c75f8 ## Any other software? The [micro](https://github.com/zyedidia/micro) terminal text editor, with a few custom keybinds, as follows: ```json { "CtrlRight": "WordRight", "CtrlLeft": "WordLeft", "CtrlShiftRight": "SelectWordRight", "CtrlShiftLeft": "SelectWordLeft" } ``` # Steps to reproduce I can easily reproduce this in `micro`, but I've had crashes from what miiiight be this issue in non-interactive-mode apps as well. The steps that tend to trigger this are as follows: 1) Open `micro`. The shell doesn't seem to matter. 2) Type at least one word. 3) Move the cursor to the end of the line. 4) With the above keybinds in place, press <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>LeftArrow</kbd>. 5) Crash! # Expected behavior The text is highlighted one word to the left. Old Conhost seems to be able to handle this. # Actual behavior Crashiness. # Additional Information I ran this in Visual Studio to capture some debug output. Here's the stack trace: ```none ucrtbased.dll!__threadid() + 101 bytes Unknown ucrtbased.dll!__threadid() + 515 bytes Unknown ucrtbased.dll!abort() + 29 bytes Unknown ucrtbased.dll!terminate() + 54 bytes Unknown vcruntime140_1d.dll!00007fff96842174() Unknown vcruntime140_1d.dll!00007fff96842e72() Unknown vcruntime140_1d.dll!__CxxFrameHandler4() + 251 bytes Unknown TerminalControl.dll!__GSHandlerCheck_EH4(_EXCEPTION_RECORD * ExceptionRecord, void * EstablisherFrame, _CONTEXT * ContextRecord, _DISPATCHER_CONTEXT * DispatcherContext) Line 73 C++ ntdll.dll!__chkstk() + 287 bytes Unknown ntdll.dll!RtlRaiseException() + 921 bytes Unknown ntdll.dll!KiUserExceptionDispatcher() + 46 bytes Unknown KernelBase.dll!RaiseException() + 105 bytes Unknown vcruntime140d.dll!_CxxThrowException() + 311 bytes Unknown TerminalControl.dll!wil::details::ThrowResultExceptionInternal(const wil::FailureInfo & failure) Line 2787 C++ TerminalControl.dll!wil::ThrowResultException(const wil::FailureInfo & failure) Line 2449 C++ TerminalControl.dll!wil::details::ReportFailure(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, void * returnAddress, wil::FailureType type, HRESULT hr, const wchar_t * message, wil::details::ReportFailureOptions options) Line 3390 C++ TerminalControl.dll!wil::details::ReportFailure_Hr(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, void * returnAddress, wil::FailureType type, HRESULT hr) Line 3451 C++ TerminalControl.dll!wil::details::in1diag5::_Throw_Hr(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, HRESULT hr) Line 4970 C++ TerminalControl.dll!wil::details::in1diag5::Throw_HrIf(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, HRESULT hr, bool condition) Line 5074 C++ --> TerminalControl.dll!TextBufferCellIterator::TextBufferCellIterator(const TextBuffer & buffer, _COORD pos, const Microsoft::Console::Types::Viewport limits) Line 48 C++ TerminalControl.dll!TextBufferCellIterator::TextBufferCellIterator(const TextBuffer & buffer, _COORD pos) Line 25 C++ TerminalControl.dll!Microsoft::Terminal::Core::Terminal::IsCursorDoubleWidth() Line 96 C++ TerminalControl.dll!Microsoft::Console::Render::Renderer::_PaintCursor(Microsoft::Console::Render::IRenderEngine * const pEngine) Line 749 C++ TerminalControl.dll!Microsoft::Console::Render::Renderer::_PaintFrameForEngine(Microsoft::Console::Render::IRenderEngine * const pEngine) Line 137 C++ TerminalControl.dll!Microsoft::Console::Render::Renderer::PaintFrame() Line 70 C++ TerminalControl.dll!Microsoft::Console::Render::RenderThread::_ThreadProc() Line 165 C++ TerminalControl.dll!Microsoft::Console::Render::RenderThread::s_ThreadProc(void * lpParameter) Line 148 C++ [External Code] ``` At the time of this particular crash, `TextBufferCellIterator::TextBufferCellIterator()` received a `pos` argument with with dimensions `120x26`, and a `limits` arg with an LT of `0,0` and a RB of `119, 9028`, so altogether a `[120x9029]`-sized viewport. Judging by the `failure` object up in WIL's `ThrowExceptionInternal`, the issue seems to be line 46 of `textBufferCellIterator.cpp`, `THROW_HR_IF(E_INVALIDARG, !limits.IsInBounds(pos));`. Some further digging reveals that `Viewport::IsInBounds(const COORD& pos)` is violating the "`pos.X < RightExclusive()`" constraint. `pos.X` is _exactly `120`, while `RightExclusive()` also returns exactly `120`. Just <kbd>Ctrl</kbd>+<kbd>Arrow</kbd>ing around in Micro doesn't usually trigger this, although I can occasionally get crashes to occur when I'm at the extreme left edge of a line while navigating leftward. <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Arrow</kbd> is extremely reliable at triggering crashes, however.
Author
Owner

@HBelusca commented on GitHub (Sep 30, 2019):

I've got the same crash (according to your stacktrace, but see also this one below) with different repro steps:

  1. Open Windows Terminal, and a new Linux shell "Legacy" inside,
  2. Within, open the htop (or just top) tool.
  3. Gently reduce the width of the console. You will hit this assertion:
    image

with the stacktrace below.

For me this crash is 100% reproducible with the steps described above.

ucrtbased.dll!issue_debug_notification(const wchar_t * const message) Line 28	C++
ucrtbased.dll!__acrt_report_runtime_error(const wchar_t * message) Line 154	C++
ucrtbased.dll!abort() Line 61	C++
ucrtbased.dll!terminate() Line 59	C++
vcruntime140_1d.dll!FindHandler<__FrameHandler4>()	Unknown
vcruntime140_1d.dll!__InternalCxxFrameHandler<class __FrameHandler4>(struct EHExceptionRecord *,unsigned __int64 *,struct _CONTEXT *,struct _xDISPATCHER_CONTEXT *,struct FH4::FuncInfo4 *,int,unsigned __int64 *,unsigned char)	Unknown
vcruntime140_1d.dll!__CxxFrameHandler4()	Unknown
TerminalControl.dll!__GSHandlerCheck_EH4(_EXCEPTION_RECORD * ExceptionRecord, void * EstablisherFrame, _CONTEXT * ContextRecord, _DISPATCHER_CONTEXT * DispatcherContext) Line 73	C++
ntdll.dll!RtlpExecuteHandlerForException()	Unknown
ntdll.dll!RtlDispatchException()	Unknown
ntdll.dll!KiUserExceptionDispatch()	Unknown
KernelBase.dll!RaiseException()	Unknown
vcruntime140d.dll!_CxxThrowException(void * pExceptionObject, const _s__ThrowInfo * pThrowInfo) Line 133	C++
TerminalControl.dll!wil::details::ThrowResultExceptionInternal(const wil::FailureInfo & failure) Line 2787	C++
TerminalControl.dll!wil::ThrowResultException(const wil::FailureInfo & failure) Line 2449	C++
TerminalControl.dll!wil::details::ReportFailure(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, void * returnAddress, wil::FailureType type, HRESULT hr, const wchar_t * message, wil::details::ReportFailureOptions options) Line 3390	C++
TerminalControl.dll!wil::details::ReportFailure_Hr(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, void * returnAddress, wil::FailureType type, HRESULT hr) Line 3451	C++
TerminalControl.dll!wil::details::in1diag5::_Throw_Hr(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, HRESULT hr) Line 4970	C++
TerminalControl.dll!wil::details::in1diag5::Throw_HrIf(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, HRESULT hr, bool condition) Line 5074	C++
TerminalControl.dll!TextBufferCellIterator::TextBufferCellIterator(const TextBuffer & buffer, _COORD pos, const Microsoft::Console::Types::Viewport limits) Line 48	C++
TerminalControl.dll!TextBufferCellIterator::TextBufferCellIterator(const TextBuffer & buffer, _COORD pos) Line 25	C++
TerminalControl.dll!Microsoft::Terminal::Core::Terminal::IsCursorDoubleWidth() Line 96	C++
TerminalControl.dll!Microsoft::Console::Render::Renderer::_PaintCursor(Microsoft::Console::Render::IRenderEngine * const pEngine) Line 749	C++
TerminalControl.dll!Microsoft::Console::Render::Renderer::_PaintFrameForEngine(Microsoft::Console::Render::IRenderEngine * const pEngine) Line 137	C++
TerminalControl.dll!Microsoft::Console::Render::Renderer::PaintFrame() Line 70	C++
TerminalControl.dll!Microsoft::Console::Render::RenderThread::_ThreadProc() Line 165	C++
TerminalControl.dll!Microsoft::Console::Render::RenderThread::s_ThreadProc(void * lpParameter) Line 148	C++
[External Code]
@HBelusca commented on GitHub (Sep 30, 2019): I've got the same crash (according to your stacktrace, but see also this one below) with different repro steps: 1. Open Windows Terminal, and a new Linux shell "Legacy" inside, 2. Within, open the `htop` (or just `top`) tool. 3. Gently reduce the width of the console. You will hit this assertion: ![image](https://user-images.githubusercontent.com/1969829/65902154-05120500-e3ba-11e9-88b8-79e2c7ad3378.png) with the stacktrace below. For me this crash is 100% reproducible with the steps described above. ``` ucrtbased.dll!issue_debug_notification(const wchar_t * const message) Line 28 C++ ucrtbased.dll!__acrt_report_runtime_error(const wchar_t * message) Line 154 C++ ucrtbased.dll!abort() Line 61 C++ ucrtbased.dll!terminate() Line 59 C++ vcruntime140_1d.dll!FindHandler<__FrameHandler4>() Unknown vcruntime140_1d.dll!__InternalCxxFrameHandler<class __FrameHandler4>(struct EHExceptionRecord *,unsigned __int64 *,struct _CONTEXT *,struct _xDISPATCHER_CONTEXT *,struct FH4::FuncInfo4 *,int,unsigned __int64 *,unsigned char) Unknown vcruntime140_1d.dll!__CxxFrameHandler4() Unknown TerminalControl.dll!__GSHandlerCheck_EH4(_EXCEPTION_RECORD * ExceptionRecord, void * EstablisherFrame, _CONTEXT * ContextRecord, _DISPATCHER_CONTEXT * DispatcherContext) Line 73 C++ ntdll.dll!RtlpExecuteHandlerForException() Unknown ntdll.dll!RtlDispatchException() Unknown ntdll.dll!KiUserExceptionDispatch() Unknown KernelBase.dll!RaiseException() Unknown vcruntime140d.dll!_CxxThrowException(void * pExceptionObject, const _s__ThrowInfo * pThrowInfo) Line 133 C++ TerminalControl.dll!wil::details::ThrowResultExceptionInternal(const wil::FailureInfo & failure) Line 2787 C++ TerminalControl.dll!wil::ThrowResultException(const wil::FailureInfo & failure) Line 2449 C++ TerminalControl.dll!wil::details::ReportFailure(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, void * returnAddress, wil::FailureType type, HRESULT hr, const wchar_t * message, wil::details::ReportFailureOptions options) Line 3390 C++ TerminalControl.dll!wil::details::ReportFailure_Hr(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, void * returnAddress, wil::FailureType type, HRESULT hr) Line 3451 C++ TerminalControl.dll!wil::details::in1diag5::_Throw_Hr(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, HRESULT hr) Line 4970 C++ TerminalControl.dll!wil::details::in1diag5::Throw_HrIf(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, HRESULT hr, bool condition) Line 5074 C++ TerminalControl.dll!TextBufferCellIterator::TextBufferCellIterator(const TextBuffer & buffer, _COORD pos, const Microsoft::Console::Types::Viewport limits) Line 48 C++ TerminalControl.dll!TextBufferCellIterator::TextBufferCellIterator(const TextBuffer & buffer, _COORD pos) Line 25 C++ TerminalControl.dll!Microsoft::Terminal::Core::Terminal::IsCursorDoubleWidth() Line 96 C++ TerminalControl.dll!Microsoft::Console::Render::Renderer::_PaintCursor(Microsoft::Console::Render::IRenderEngine * const pEngine) Line 749 C++ TerminalControl.dll!Microsoft::Console::Render::Renderer::_PaintFrameForEngine(Microsoft::Console::Render::IRenderEngine * const pEngine) Line 137 C++ TerminalControl.dll!Microsoft::Console::Render::Renderer::PaintFrame() Line 70 C++ TerminalControl.dll!Microsoft::Console::Render::RenderThread::_ThreadProc() Line 165 C++ TerminalControl.dll!Microsoft::Console::Render::RenderThread::s_ThreadProc(void * lpParameter) Line 148 C++ [External Code] ```
Author
Owner

@DHowett-MSFT commented on GitHub (Sep 30, 2019):

This'll be fixed by #2965

@DHowett-MSFT commented on GitHub (Sep 30, 2019): This'll be fixed by #2965
Author
Owner

@skyline75489 commented on GitHub (Oct 15, 2019):

@DHowett-MSFT Should this issue be added to milestone 1910? This is definitely a release-blocker.

@skyline75489 commented on GitHub (Oct 15, 2019): @DHowett-MSFT Should this issue be added to milestone [1910](https://github.com/microsoft/terminal/milestone/15)? This is definitely a release-blocker.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#4174