Today I had one of those days where you engage in an extended exercise of hide and seek trying to work out why it works on our machines but not on yours, Yes, I was hunting dependencies for a software deployment.
As is often the case, today the dependencies were hidden underneath some third party code and that third party code was using LoadLibrary to load dependencies at runtime.
Furthermore we wipe out and reset the path – to include certain third party libraries – with a cmd we use to open our VS solution. If you happen to forget that for a moment then tracking down dependencies becomes that little bit harder.
Now, in general it’s hard to give a one-size-fits-all process for tracking down library dependencies (Yes, Tess had the right idea with sets of debugging tutorials). On the other hand, a couple of tools didn’t quite spring to mind as quick as they should have, and some were unknown to members of the team I’m on, so I thought I might write myself a list of tools useful in diagnosing these problems.
Visual Studio | In debug, use the Immediate Window to run
System.Environment.GetEnvironmentVariable(“PATH”)
to work out whether your path is being managed unexepectedly, and
System.IO.Directory.GetCurrentDirectory()
to work out where you are.
You can drag a module/dll onto VS and open up the manifest as well. |
Fuslogvw | Helps you monitor managed assembly binding – and tells you where the runtime is trying to load assemblies from. |
Depends | Dependency walker determines the (native) dependency tree of a module, and tells you if anything’s missing. If there’s an hourglass next to a dependency it means it’s late loaded – and may not be a problem. |
Windbg | If you run an executable in windbg (Open Executable, ‘g’ to go) it’ll tell you which modules it loads, and where from.
To debug LoadLibrary fails:
x MyModule!*LoadLib*
locates symbols in MyModule that reference LoadLib.
bu kernel32!LoadLibraryExW ".echo LoadLibraryExW for ->; du dwo(@esp+4); g"
sets a breakpoint for LoadLibrary calls and displays the name of the library that’s meant to be loaded.
These examples are drawn from this page of common windbg commands, which is a good one to have bookmarked. |
Process Explorer | Can show you which modules have been loaded by a still-running process, and from where it loaded them. |
Frequently Depends.exe says that ieshims.dll and wer.dll are missing – if I recall correctly this is associated with an upgrade to Internet Explorer 8, and can basically be discounted in most situations (google search for ieshims and wer.dll should clarify this).
If Depends.exe shows up missing MSVC*{80,90,100}.dll then you’re missing a Visual C++ runtime redistributable. If you’re missing one titled DebugCRT then you’ll probably need to rebuild, as these versions are only available on machines with VS installed. Remember that you shouldn;t assume that these redistributables are installed on machines in a cluster – you might need to package them up alongside your app code to make sure they get out there at deployment time.