Scrolling optimization for SW rendering is wrong - crashes in debug build
- Dominant language
- C#
- Stars
- 7.7k
- Forks
- 1.3k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 61
Description
* .NET Core Version: (e.g. 3.0 Preview1, or daily build number, use `dotnet --info`) all
* Windows version: (`winver`) all
* Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes
* Is this bug related specifically to tooling in Visual Studio (e.g. XAML Designer, Code editing, etc...)? If yes, please file the issue via the instructions [here](https://docs.microsoft.com/visualstudio/ide/how-to-report-a-problem-with-visual-studio?view=vs-2019). no
* Security issues and bugs should be reported privately, learn more via our [responsible disclosure guidelines](https://github.com/dotnet/wpf/blob/master/README.md#reporting-security-issues-and-security-bugs).
**Problem description:**
The method ``CPreComputeContext::ScrollableAreaHandling`` applies an optimization for scrolling when using SW rendering (e.g. over RDP). [Part of it](https://github.com/dotnet/wpf/blob/main/src/Microsoft.DotNet.Wpf/src/WpfGfx/core/uce/precompctx.cpp#L1184-L1196) is wrong:
```
// trim horizontalScrollRect so it doesn't overlap verticalScrollRect
if (offsetY != 0)
{
if (offsetY > 0)
{
// scrolling up. Strip is along the top of the clip area
horizontalScrollRect.top += offsetY;
}
else
{
// scrolling down
horizontalScrollRect.bottom += offsetY;
}
}
```
When `offsetY` exceeds the height of the `scrollClipRectFinal`, this makes `horizontalScrollRect` invalid because ``top > bottom``.
**Actual behavior:**
In debug builds, this fails ``Assert(horizontalScrollRect.IsWellOrdered());`` a few lines farther down, and crashes.
In retail builds the bad rect is detected in [`CDirtyRegion2::Add`](https://github.com/dotnet/wpf/blob/main/src/Microsoft.DotNet.Wpf/src/WpfGfx/core/uce/dirtyregion.cpp#L283-L305), which applies a fallback that "could cause a serious perf regression".
**Expected behavior:**
No crash, no fallback, no "serious perf regression".
**Minimal repro:**
N/A. I've seen this in Visual Studio (using debug WPF bits, and RDP connection). While debugging an app, single-stepping occasionally hits the problem - it's deep in the low-level rendering code, so I don't know what VS is doing to request the problematic scroll. VS crashes without warning - it just disappears. By attaching WinDbgX to the VS process, I was able to catch the assert:
```
*** Assertion failed: horizontalScrollRect.IsWellOrdered()
*** Function: CPreComputeContext::ScrollableAreaHandling, Source: `e:\dd\netfxdev1\src\wpf\src\graphics\core\uce\precompctx.cpp:1198`
(No kernel debugger is present.) Respond with:
g -- Go (continue)
eb 0x095CEEC8 'i';g -- Ignore all future hits
eb 0x095CEEC8 'p';g -- terminate Process
eb 0x095CEEC8 't';g -- terminate Thread
or regular debugging.
(3124.6390): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=08b47df0 ecx=00000065 edx=095cec91 esi=095cee84 edi=095ceef4
eip=76f64ef0 esp=095cee80 ebp=095ceef4 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
ntdll!DbgBreakPoint:
76f64ef0 cc int 3
0:011> k5
# ChildEBP RetAddr
00 095ceef4 62c0ad8f ntdll!DbgBreakPoint [minkernel\ntos\rtl\i386\debug2.asm @ 61]
01 095ceef4 62cc5567 wpfgfx_v0400!AssertW+0x27f [e:\dd\netfxdev1\src\wpf\src\graphics\shared\util\utillib\assert.inl @ 635]
02 095cf1d8 62cc382c wpfgfx_v0400!CPreComputeContext::ScrollableAreaHandling+0x877 [e:\dd\netfxdev1\src\wpf\src\graphics\core\uce\precompctx.cpp @ 1198]
03 095cf288 62d03f21 wpfgfx_v0400!CPreComputeContext::PreSubgraph+0x1ec [e:\dd\netfxdev1\src\wpf\src\graphics\core\uce\precompctx.cpp @ 219]
04 095cf320 62cc33fb wpfgfx_v0400!CGraphIterator::Walk+0x141 [e:\dd\netfxdev1\src\wpf\src\graphics\core\uce\graphwalker.cpp @ 303]
```
Contributor guide
Assessment
This issue has not been assessed yet.