The curious case of a Windows Explorer hang

3 minute read,

I’ve had my main development PC for about 7 years now and it’s still going strong. Sure, it’s old but holy-smokes think of it as a finely-tuned and well-oiled machine. Every setting on this machine has some kind of thought geared toward developer productivity. For example, emacs key-bindings for all windows in the Windows OS. You name it.

But I had this one nagging problem with Google Chrome: When I clicked on an HTML button to upload a file the USER32 “Open Dialog” box would come up. I would select the file to upload and soon as the “Open Dialog” box closed, Chrome would freeze for a good 10 to 15 seconds. Clicking anywhere in Chrome during this hang would produce a Windows OS “ding” sound for each click made anywhere on the browser.

The same issue would happen when I downloaded a small file. The USER32 “Save as…” dialog box would come up. I would select the folder to save the file. Soon as the save dialog box closed I would not be able to open the file for a good 10 to 15 seconds because Chrome would be non-responsive for that brief period of time.

The issue wasn’t 100% reproducible either; maybe 1 out of 8 times Chrome would lock up. The issue Drove. Me. Nuts. I’ve lived with this annoying bug for a very long time and it was time to put in some effort into tracking this issue down.

So, I started with the usual System Internals tools to try to track the issue down. At first, not much luck…

  • Process Explorer - I didn’t see any abnormal activity during the “hang” event in Chrome or any other system processes.
  • Process Monitor - Didn’t help much either. A few obscure registry accesses, but again, not much to go on.

Then, one day, I started DebugView which logs Kernel-mode DbgPrint calls. And by golly, right at the EXACT moment the freeze happened, the following output printed to DebugView:

[FFFFFA8041F3F3A0] WskProIRPGetAddrInfo is called.
[bind=FFFFFA803B923C10] Binding reference count++ = 2 (status = 00000000, impersonation= 2).
[FFFFFA8040AA4360] Request reference count++ = 3.
[FFFFFA8040AA4360] RPC method type = 1: rpc-method succeeded, queue to rpc-pending-list.
[FFFFFA8040AA4360] Request reference count-- = 2.
[FFFFFA803FBB2EE0] WskProIRPGetAddrInfo is called.
[bind=FFFFFA803B923C10] Binding reference count++ = 3 (status = 00000000, impersonation= 2).
[FFFFFA8030B03EB0] Request reference count++ = 3.
[FFFFFA8030B03EB0] RPC method type = 1: rpc-method succeeded, queue to rpc-pending-list.
[FFFFFA8030B03EB0] Request reference count-- = 2.
[FFFFFA8030B03EB0] WskKnrRpcComplete: rpc calls back for completion.
[FFFFFA8030B03EB0] WskKnrCompletePending: complete pending request (rpc=1).
[FFFFFA8030B03EB0] Request reference count-- = 1.
[FFFFFA8030B03EB0] Request reference count-- = 0.
[FFFFFA8030B03EB0] WskKnrCompleteRequest: rpc completion return status = 00000000 (reply=00000000).
[FFFFFA8030B03EB0] WskProAPIGetAddressInfo returned addrinfo: [addr=FFFFF8A0366AC6C0].
[bind=FFFFFA803B923C10] Binding reference count-- = 2.
[FFFFFA8030B03EB0] WskKnrCompleteRequest: complete irp with IO status = 00000000.
[addr=FFFFF8A0366AC6C0] WskProAPIFreeAddressInfo freed addrinfo.
[FFFFFA8040AA4360] WskKnrRpcComplete: rpc calls back for completion.
[FFFFFA8040AA4360] WskKnrCompletePending: complete pending request (rpc=1).
[FFFFFA8040AA4360] Request reference count-- = 1.
[FFFFFA8040AA4360] Request reference count-- = 0.
[FFFFFA8040AA4360] WskKnrCompleteRequest: rpc completion return status = 00000000 (reply=c0000272).
[FFFFFA8040AA4360] WskProAPIGetAddressInfo returned addrinfo: [addr=0000000000000000].
[bind=FFFFFA803B923C10] Binding reference count-- = 1.
[FFFFFA8040AA4360] WskKnrCompleteRequest: complete irp with IO status = c0000272.
[FFFFFA8040C4CD80] WskProIRPGetAddrInfo is called.
[bind=FFFFFA803B923C10] Binding reference count++ = 2 (status = 00000000, impersonation= 2).
[FFFFFA8030C7B660] Request reference count++ = 3.
[FFFFFA8030C7B660] RPC method type = 1: rpc-method succeeded, queue to rpc-pending-list.
[FFFFFA8030C7B660] Request reference count-- = 2.

Very nice. Very very nice. The output is virtually the same every time the freeze occurs. But what does all this mean? Let’s try decoding it.

  • WskProIRPGetAddrInfo
    • Wsk - probably relates to Winsock Kernel-mode network APIs.
    • IRP - probably relates to processing a Windows I/O request packet.

      An IRP structure is a partially opaque structure that represents an I/O request packet.

      https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/ns-wdm-_irp

    • GetAddrInfo - probably relates to getting network Address Infomation.
  • RPC method type = 1 - some kind of Remote Procedure Call (RPC).

Definitely getting a strong sense that the issue is something network related. Maybe a timeout of some kind.

After endless livekd kernel-debug sessions I finally opened WireShark on a low-traffic NIC and sure enough I found the culprit:

Turns out, every time I open a “Save as…” or “Open File” dialog box in Chrome my PC is sending NetBIOS broadcasts on all NIC interfaces. The NetBIOS names attempting to be resolved are related to Network Shortcuts in my Windows Explorer that I only use when my Virtual Private Network (VPN) is connected as shown in the picture below:

To remove Network Shortcuts, simply right-click the network shortcut you want to remove and click “Delete”. You can also delete Network Shortcuts stored in the following location:

C:\Users\ACCOUNT\AppData\Roaming\Microsoft\Windows\Network Shortcuts

After I deleted the Network Shortcuts in Windows Explorer the momentary hangs in Google Chrome disappeared.

Case closed. :smile: :clap: :tada:

Tags:

Updated:

Leave a comment

Your email address will not be published. Required fields are marked *

Loading...