Thursday, October 19, 2017

How to find which dependent DLL can't be found

A couple of times in the last few years I have faced a knotty problem to do with DLLs on Windows. The first occasion was when a large complex program was performing that Win32 function ::LoadLibrary and it failed to find a sub-dependent DLL. A more recent case was where a java program called loadLibrary to load a shared C++ library used by a JNI interface. This library load also failed. Both failures were silent and mysterious. No details are given, just that the load failed.

I googled for help and asked friends and colleagues. The answer that came back again and again was to use the Dependency Walker at http://www.dependencywalker.com. Well, it turns out that every time I used that program to solve the riddle it was no help at all. I have now found a more reliable way, thanks to a tip via the ACCU general mailing list. I wrote a little C++ program. Before you run the program set PATH to the value it would have in your particular problem situation. The program waits for the user to hit return, then it calls ::LoadLibrary on the library name supplied. What you have to do is run the program (with PATH set appropriately) and while it is waiting for you to hit return, run Procmon from SysInternals. Enter the pid for the LoadLibrary program and set a filter for Operation to QueryOpen. Then hit return so it tries to load the library. The Procmon windows will then fill with all the file access attempts made to resolve the DLLs.Bear in mind that it is using PATH to locate the DLLs so there will be several access failures. The thing to do is check each leaf DLL name and find the case or cases where it failed to find the DLL no matter which PATH directories were searched. That's it, you have found which DLL failure(s) occurred!

It is a shame there is no more convenient way to deal with situation. If only the logic of calling ::LoadLibrary could be combined with the logic in Procmon that gets all the OpenQuery cases with the pathname and whether or not the access worked, all in one program. Maybe one day someone will write such a program, but in the meantime this solution will have to do.

No comments: