1

I have an application in active use with a rarely occurring 'freeze' of the UI thread. This of course results in the application becoming unresponsive and requires the user to terminate it manually.

Due to how difficult this issue is to reproduce, I'd like to develop some tools to help gather data on when it's happening in the field and what's occurring at the time. What I'm thinking about is some sort of background watchdog task that would monitor a 'heartbeat' from a periodically scheduled UI thread task. If it goes quiet for too long, I can say that the UI is effectively locked up (or at least stalled for way longer than I'd ever want) and hence gather data.

So, in preparation for this, a few questions:

  1. Does something like this already exist? This seems like a reasonably common problem, so if there are existing tools to help diagnose this, it might be worth using those rather than rolling my own solution.

  2. I'm still debating what information I should try to gather when the freeze is detected. Is there some way for me to easily grab the stack trace of the UI thread so that it can be logged? Possibly grab stack traces from all active threads? Is there some way I can capture a complete debug dump?

Dan Bryant
  • 27,329
  • 4
  • 56
  • 102

1 Answers1

3

Does something like this already exist?

Yes. It is imperative to do this outside of the process since a deadlocked one makes it very likely that the diagnostic code is going to deadlock as well. The DebugDiag utility has explicit support for hung apps.

I'm still debating what information I should try to gather

The minidump you get out of DebugDiag should be enough to give you a shot a diagnosing the cause. A sample debug session that demonstrates tackling a deadlock is shown here.

And of course a good hard look at your code never hurts. UI thread deadlocks are frequently caused by:

  • Displaying a window on a worker thread. The SystemEvents class is a very significant troublemaker when you do this. It needs to fire its events on the UI thread but that requires it to guess which specific thread in your program is actually the UI thread. Once it guesses wrong, you are set for a spontaneous deadlock any time later. Do note that this doesn't require you using the SystemEvents class in your own code, many controls subscribe the ThemeChanged event to repaint themselves. Fwiw, that debug session I linked to demonstrates such a deadlock. Beware of home-spun splash screens, "progress" windows that are created on the worker thread instead of the UI thread and of course any worker thread that displays UI.

  • Data bound controls whose underlying binding source is updated on a worker thread. Very common of course since dbase queries tend to be slow. Such controls have to be unbound explicitly first.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Thanks, this looks like an interesting tool. There may be some logistical/political problems with finding customers willing to run third-party debug diagnostics tools to capture the information, though. Integrated logging and voluntary sending of log files is more commonly accepted, I think. – Dan Bryant Feb 07 '14 at 17:20
  • That's rather backwards, at least with a well publicized and documented tool they'll know what it does and what might get exposed. The only advantage of adding it yourself is that they don't know, so won't think to block it, which isn't exactly a great way to inspire confidence that you take their concerns serious. But it is up to you. – Hans Passant Feb 07 '14 at 17:25
  • Regarding problems caused by SystemEvents class see the CheckSystemEventsHandlersForFreeze() function in [this answer](https://stackoverflow.com/a/52721562/901333) which can help to find root cause, i.e. exact controls causing freeze. – Vlad Rudenko Oct 10 '18 at 13:31