Why would a process hang within RtlExitUserProcess/LdrpDrainWorkQueue?

To debug a locked file problem, we're calling SysInternal's Handle64.exe 4.11 from a .NET process (via Process.Start with asynchronous output redirection). The calling process hangs on Process.WaitForExit because the Handle64 process doesn't exit (for more than two hours).

We took a dump of the corresponding Handle64 process and checked it in the Visual Studio 2017 debugger. It shows two threads ("Main Thread" and "ntdll.dll!TppWorkerThread").

Main thread's call stack:

ntdll.dll!NtWaitForSingleObject ()  Unknown
ntdll.dll!LdrpDrainWorkQueue()  Unknown
ntdll.dll!RtlExitUserProcess()  Unknown
kernel32.dll!ExitProcessImplementation  ()  Unknown
handle64.exe!000000014000664c() Unknown
handle64.exe!00000001400082a5() Unknown
kernel32.dll!BaseThreadInitThunk    ()  Unknown
ntdll.dll!RtlUserThreadStart    ()  Unknown

Worker thread's call stack:

ntdll.dll!NtWaitForSingleObject()   Unknown
ntdll.dll!LdrpDrainWorkQueue()  Unknown
ntdll.dll!LdrpInitializeThread()    Unknown
ntdll.dll!_LdrpInitialize() Unknown
ntdll.dll!LdrInitializeThunk()  Unknown

My question is: Why would a process hang in LdrpDrainWorkQueue? From https://stackoverflow.com/a/42789684/62838, I gather that this is the Windows 10 parallel loader at work, but why would it get stuck while exiting the process? Can this be caused by how we invoke Handle64 from another process? I.e., are we doing something wrong or is this rather a bug in Handle64?

Asked By: Fabian Schmied
||

Answer #1:

How long did you wait?

According to this analysis,

The worker thread idle timeout is set to 30 seconds. Programs which execute in less than 30 seconds will appear to hang due to ntdll!TppWorkerThread waiting for the idle timeout before the process terminates.

I would recommend trying to set the registry key specified in that article to disable the parallel loader and see if this resolved the issue.

Parent Key: HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\handle64.exe
Value Name: MaxLoaderThreads
Type: DWORD
Value: 1 to disable
Answered By: Fabian Schmied
The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .



# More Articles