Explorer.exe hang analysis (credential prompt)
The problem
I was working on my notebook with some windows open and just tried to multitask several things at once. I usually end up opening things and if it takes me too long (>2 seconds) I then do something else (to waste no time). Sometimes I forget things or must look through untitled notepads to be reminded again. But at some point, I wanted to do something in an explorer.exe
instance and the application hung. I tried a few seconds later, but it was still hanging. So I did what everyone should do, a memory dump.
procdump — to take the memory dump
If I have procdump available, I do my memory dumps with it. It takes a lot of work off my hands.
procdump -ma -h explorer.exe
Short explanation:
The option -ma
takes a full memory dump.
The option -h
writes only the dump if the process has a hung window.
explorer.exe
is the name of the affected process. The name thing works as long as it is unique (partial match). Otherwise, you could also work with the PID.
Analyzing the memory dump
Preparation
- First of all, you need WinDbg (Windows Debugger). The easiest way is to download WinDbg Preview via Microsoft Store.
- You also need to set up the symbol server. A very easy way is to define the environment variable:
_NT_SYMBOL_PATH=SRV*C:\symbols*http://msdl.microsoft.com/download/symbols
. The good thing is that other tools use also that environment variable. - We want to use the handy WinDbg Extension: PDE. It’s written by Andrew Richards. Just download the .zip file and extract it.
Action
We open the memory dump file (explorer.exe_211122_202839.dmp
) with WinDbg. After some symbol loading we can load the WinDbg extension with:
.load PDE v11.3\PDE v11.3\x64\winext\pde.dll
(You have to adjust the path).
Because it is explorer.exe
we can expect many threads. We can also expect many waiting threads. There is this good chance that long-call stacks are usually the interesting ones. To get them we use the PDE extension:
!busy 20
Short excursion: To get help for the WinDbg extension we have to enter !PDE.help
. After that, you can see all available commands.
The help manual is much more detailed (and !busy
is just one out of many commands). I have shown the part that is interesting for us now. With the command !busy 20
we say, please show us all stacks that are at least 20 frames deep (but excluding the waits mentioned above).
In my memory dump, I had four threads that matched this. I took a look at the first one.
I highlighted the parts where I thought “oh… that’s interesting.” while reading over it (most things I don’t even have a clue what they could be).
What do we see here?
- TryValidateUNC Most people know UNC paths when they try to connect network drives. Usually, these start with \\.
- WNetUseConnectionW Most sysadmins probably also know net use command to connect network drives.
- CredUIInternalPromptForWindowsCredentialsW And that basically tells you everything now, apparently, there is a prompt for my credentials somewhere. When I read that, I realized that I was trying to access a network drive earlier. But that did not work fast enough, I did something else and then apparently forgot about it.
Now we know what the problem is, we can find the window and either enter our credentials or close the window. After that, the explorer worked again.
But — just for fun — I might like to find out which network drive this prompt is actually for.
For this, we can use the WinDbg command db. Briefly summarized/quoted what can be found in the article:
With this command, we can view the contents of the memory. The db command shows us the byte values as well as the ASCII characters. All non-printable characters are displayed as . (periods). The default count is 128 bytes.
I now want to read the memory between the locations I highlighted above.
db 00000000`079faf30 00000000`079fdd10
I get some back (you could narrow it down further if it would be too much) but with a little scrolling through I see the following parts:
You can see both the credential prompt and the actual UNC path (\\ubuntu\data
).
I hope the article was helpful. There are pretty sure better ways to solve the problem, but this is how I did it. Please let me know if you have any comments, tips, or similar for me.
Happy troubleshooting.