Debugging LoadLibrary Failures

LoadLibrary is one of the mostly used yet unbelieveably complex APIs in Windows, if not the one. Russ Osterlund has a full MSDN article discussing LoadLibrary, yet he only touches the surface of the problem (how it works under normal condition.) Mike Grier is one of the most talented developers I have worked with in Microsoft. He devoted a full series on the intricacy of LoadLibrary. Yet he has to put it to a halt due to the complexity of the problem.

For developers that outside of the loader team, they don't have to understand all the intricacy of LoadLibrary (though they do need to understand how it works, the dos and don'ts of LoadLibrary, etc.). But then LoadLibrary fails, they do need to figure out why it fails. There are times that this is just hard to figure out why, especially when the binary depends on other dlls that they don't have source code available.

Fortunately, the loader team recognized the problem, and provided a built-in trace log to debug obsure LoadLibrary failures. The trace log is called "loader snaps" internally.

You can turn on loader snaps using gflags.exe. gflags.exe is part of Debugging Tools for Windows. You can download it from https://www.microsoft.com/whdc/devtools/debugging/default.mspx.

To enable loader snaps, run "gflags.exe -i your-app-without-path.exe +sls"

You have to run your application under debugger to see the loader snaps. You can use debuggers in the Debugging Tools for Windows package. An example is shown at the bottom of this article.

If there is any failures, you will see "failed" in loader snaps.

Be warned that loader snaps may have enormous output. You may want to isolate the problem before turning on loader snaps.

gflags.exe can also turn on all kinds of debugging capabilities, please refer to MSDN https://technet2.microsoft.com/WindowsServer/en/library/00d4872f-eeb3-4a6e-910a-299ad55aed631033.mspx?mfr=true for more information.

An example of loader snaps:

D:\Tools>c:\debuggers\cdb loadlib svn-win32-1.4.2\bin\ssleay32.dll

Microsoft (R) Windows Debugger Version 6.6.0007.5
Copyright (c) Microsoft Corporation. All rights reserved.

CommandLine: loadlib svn-win32-1.4.2\bin\ssleay32.dll
Symbol search path is: *** Invalid ***
****************************************************************************
* Symbol loading may be unreliable without a symbol search path. *
* Use .symfix to have the debugger choose a symbol path. *
* After setting your symbol path, use .reload to refresh symbol locations. *
****************************************************************************
Executable search path is:
ModLoad: 00400000 0040a000 image00400000
ModLoad: 7c900000 7c9b0000 ntdll.dll
ModLoad: 7c800000 7c8f4000 C:\WINDOWS\system32\kernel32.dll
(b1c.f94): Break instruction exception - code 80000003 (first chance)
eax=00241ea4 ebx=7ffd3000 ecx=00000000 edx=00000001 esi=00241f18 edi=00241ea4
eip=7c901230 esp=0012fb20 ebp=0012fc94 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
*** ERROR: Symbol file could not be found. Defaulted to export symbols for ntdl
l.dll -
ntdll!DbgBreakPoint:
7c901230 cc int 3
0:000> g
[b1c,f94] LDR: Real INIT LIST for process D:\Tools\loadlib.exe pid 2844 0xb1c
Loading library svn-win32-1.4.2\bin\ssleay32.dll...
LDR: LdrLoadDll, loading svn-win32-1.4.2\bin\ssleay32.dll from D:\Tools;C:\WINDO
WS\system32;C:\WINDOWS\system;C:\WINDOWS;.;c:\debuggers\winext\arcade;C:\WINDOWS
\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\PROGRA~1\CA\SHARED~1\SCANEN~1;C
:\PROGRA~1\CA\ETRUST~1;C:\Program Files\ATI Technologies\ATI Control Panel;C:\Pr
ogram Files\Common Files\Roxio Shared\DLLShared;C:\WINDOWS\system32\WindowsPower
Shell\v1.0
LDR: Loading (DYNAMIC, NON_REDIRECTED) D:\Tools\svn-win32-1.4.2\bin\ssleay32.dll

ModLoad: 10000000 10031000 D:\Tools\svn-win32-1.4.2\bin\ssleay32.dll
LDR: LIBEAY32.dll used by ssleay32.dll
LDR: LdrpResolveDllName - call to RtlDosSearchPath_U failed

DllName: "LIBEAY32.dll"
Path: "D:\Tools;C:\WINDOWS\system32;C:\WINDOWS\system;C:\WINDOWS;.;c:\debugge
rs\winext\arcade;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\PROG
RA~1\CA\SHARED~1\SCANEN~1;C:\PROGRA~1\CA\ETRUST~1;C:\Program Files\ATI Technolog
ies\ATI Control Panel;C:\Program Files\Common Files\Roxio Shared\DLLShared;C:\WI
NDOWS\system32\WindowsPowerShell\v1.0"
LDR: LdrpLoadImportModule - LdrpMapDll(00143278, LIBEAY32.dll, NULL, TRUE, 0, 00
12F658) failed with status c0000135
LDR: LdrpWalkImportTable - LdrpLoadImportModule failed on import LIBEAY32.dll wi
th status c0000135

LDR: Unloading svn-win32-1.4.2\bin\ssleay32.dll due to error c0000135 walking im
port descriptors
LDR: UNINIT LIST
(1) [ssleay32.dll] D:\Tools\svn-win32-1.4.2\bin\ssleay32.dll (0) deini
t 0
LDR: Unmapping [ssleay32.dll]
LoadLibrary failed with GetLastError() = 126
LDR: LdrGetDllHandle, searching for mscoree.dll from
LDR: LdrGetDllHandle, searching for mscoree.dll from D:\Tools;C:\WINDOWS\system3
2;C:\WINDOWS\system;C:\WINDOWS;.;c:\debuggers\winext\arcade;C:\WINDOWS\system32;
C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\PROGRA~1\CA\SHARED~1\SCANEN~1;C:\PROGRA~1
\CA\ETRUST~1;C:\Program Files\ATI Technologies\ATI Control Panel;C:\Program File
s\Common Files\Roxio Shared\DLLShared;C:\WINDOWS\system32\WindowsPowerShell\v1.0

LDR: PID: 0xb1c finished - 'loadlib svn-win32-1.4.2\bin\ssleay32.dll'
eax=0012faa0 ebx=00000000 ecx=0000e6dc edx=0012fb4d esi=7c90e88e edi=00000001
eip=7c90eb94 esp=0012fdb8 ebp=0012feb4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ntdll!KiFastSystemCallRet:
7c90eb94 c3 ret