Often times while analyzing more complicated crash or hang problems, one needs to take a survey of what the overall state of a particular program is in order to get a better handle on the problem. A typical way to do this is to grab a call stack of all threads, such as via “~*kv“, or similar commands. While this works, there is often a lot of noise in the output.
Part of the problem is that in most non-trivial programs, you’ll tend to find a lot of worker threads that are for the most part “uninteresting” as to the overall state of the program and whatever issue you are trying to diagnose. For example, RPC likes to create several worker threads, several of which might all be blocked waiting for a new work item to pick up. Or a program could use the thread pooling APIs, or even have its own from-scratch thread pool.
All of these extra worker threads sitting around doing nothing are a nuisance, because they clutter up a summary of all thread stacks unnecessarily and can make it more difficult to find the threads that we’re really interested in.
One useful debugger command that can help cut through the mess in cases like this is !uniqstack. It works similar to “~*k“, except that it filters the output to only include call stacks that are not exact duplicates of eachother (in terms of return addresses on the stack). After all thread stacks are listed, the extension displays a count of duplicate call stacks and enumerates each thread that had a duplicate stack.
Since most of these duplicate call stacks are not interesting to us anyway, this can often help gain some better visibility into a program with many worker threads.