TL;DR:
- application is built with WPF, running on .Net 3.5
- newest and older versions of the app work properly on many different machines
- on one specific machine it malfunctions in a strange way:
- either does not start, displays black screen instead of "welcome" screen; can't do anything on that black screen
- or does start and works properly, until a TextBox is presented and until the user starts entering the text into it; then application immediatelly hangs
Background:
I have built a WPF application on .Net 3.5. I've checked the application on various machines with different OS, ranging from Windows XP up to Windows 7 - and it runs fine, no bugs, etc. It also works fine on my client's several target machines, XP and W7 included again.
However, on one machine, it suddenly ceased to work. My client sent me the machine so I can investigate. From the files on its drives, I can see there were older versions, and they were used by the client for a few months. I also see that the newest version is not installed yet on this machine. So, I tried running the old versions first, to see what's the problem.
What user sees:
- oldest versions (say, v1, v2) of the application does not work at all. When they start up, the only thing the application displays is ... absolutely completely black window. There should be a "welcome" screen, composed of few images and labels and a button. The app is not frozen it is "responsive" (Win7 can communicate with it, the window is not dimmed).
- last (but not newest, let's name it v3) application runs fine, everything is clickable, features work OK, except one. When user is asked to provide a password, the user is presented with single
TextBox
in a popup. When the user enters at least one character in that textbox, the application freezes. It freezes even before having rendered the masked '*' of the password. The freezing is total, the application stops responding (the window is dimmed and the OS wants to close it), CPU goes to 100% (actually 50%, two-core system) and the only way to stop is kill it via task manager. then I installed and tried running the newest version (v4) - it behaves just like v3 above
I've also tried reinstalling all the versions, just to be ensure the .EXE/.DLL files are not damaged - no changes (v1/2 - black, v3/4 - freeze on text)
Technical bits, just FYI:
- The app is very simple, one executable with no shared libraries and no shared configuration. There is just no way the newest version could interact with old versions. Seriously, I intentionally made the app in a way it can be "just copied" and several instances can be safely kept in separate folders.
- All versions of the app (v4, v3, v2, v1) work properly on all other machines, with various versions of Windows
The problem can't be related to user files or configuration, I tried copying them from problematic machine to healthy ones, and the problem does not repeat
Related to password box: There are absolutely no event handlers in the code that could produce a deadlock or freezing. The password textbox has no text-changed handlers. My code reads the text only after an "OK" button is pressed. The app freezes immediatelly when user enters first character, the user does not even get a chance to press "OK"
- Related to startup: The app does almost nothing on startup. It merely displays some form of a splash/welcome screen. There is no logic there except for a nice UI and one button. The user has no chance of pressing that button. When the app starts, the screen is black and has no contents, not even the splash/welcome image.
Tracing and observations:
I've focused on the TextBox part, since it's more granular.
I've got the app to freeze again, and checked the threads with ProcessHacker.
Except for typical threads, one thread that was sitting and busy-spinning at:
wpfgfx_v0300.dll MilGlyphRun SetGeometryAtRenderTime
wpfgfx_v0300.dll MilGlyphRun SetGeometryAtRenderTime
...
wpfgfx_v0300.dll MilContent DetachFromHWND
That's certainly problem with the WPF layer itself. The DetachFromHWND
tells me close to nothing, but MilGlyphRun
is surely about the text rendering. It freezes while trying to render the text. I've checked the black-screens on older versions of the applications, but I couldn't catch it, since the apps were not frozen, just black.
So..
- I've applied literally all pending updates (like, 150 of them, ~800 Mb, most of them were to the OS and .Net framework)
- I've tried reinstalling all video drivers
No changes, still black screen, still freezing.
So, focusing back to the problem. It failed to render a text. Sounds obvious, since it deadlocked when user entered a character into a textbox, but it's damn not obvious! The user was presented with tons of different TextBoxes
until he finally got to the PasswordBox
. All TextBoxes
worked OK, only this one fails. And why old verions of the app display black screen and the new version displays the "welcome" screen properly? How can be those issues related?
The connection is: Windows Presentation Foundation Font Cache service.
Sources:
WPF uses a Font-Cache service, running as a separate process, for, well, caching fonts. Whenever your WPF app needs to draw some text, it might ask the cache service for fonts. Once in a while the font cache might get corrupted and it then will/may randomly impact any WPF application.
Unfortunatelly, restarting the service is not enough. When this happens, you must delete all
FontCache
files that this service keeps on the disk. Before deleting them, you must stop the"Windows Presentation Foundation Font Cache
service (or whatever it's called in your languge, for exampleUsługa buforowania czcionek platformy Windows Presentation Foundation
in Polish..). Then, go to%systemdrive%\Windows\ServiceProfiles\LocalService\AppData\Local\
%systemdrive%\Windows\ServiceProfiles\LocalService\AppData\Local\
%systemdrive%\Documents and Settings\LocalService\Local Settings\Application Data
and remove all files looking like
FontCache.dat
. The source articles mentioned only one file (FontCache3.0.0.0.dat, but in my case there were around 8 files with similar naming convention).After deleing them and restarting the service, all versions of my application were running properly again. No black screens, no freezing on textbox.