Getting the error when trying to connect to a DSN with SQLDriverConnect.
SQLGetDiagRec shows me the following:
Specified driver could not be loaded due to system error 126: The
specified module could not be found (, )
I can't disclose the name of the driver, but I can say that it is correct the the dll path exists.
I looked inside the registry at ODBC.INI and ODBCINST.INI and everything seems to be in order.
Any more ideas where to look?
Turns out that the problem was not with my DLL, but with missing dependencies.
To find out which DLLS were missing I used process monitor to see which other DLLs failed to load after my DLL was accessed.
Initially I also tries to use Dependency Walker to solve the mystery, but load time was very long in my case and then there was just too much info.
Related
We have a huge program. Approximately 250 DLLs. Of these, we have approximately 45 COM DLLs and 20+ .NET assemblies that have ComVisible classes in them.
Now we want to work on an XCopy deployable version... WHich means that we need to use Isolated COM. I have been experimenting with smaller projects and have the basic mechanics down of how it works.
Now the problem is that after having built the manifest for one application, it won't load. I used sxsTrace and it gives a useless error message.
Last four lines of sxstrace log:
INFO: Parsing Manifest File c:\src\v13\Debug-Win32\sta_net_DMModel.DLL.
INFO: Manifest Definition Identity is sta_net_DMModel,processorArchitecture="x86",version="1.0.0.0".
ERROR: Activation Context generation failed.
End Activation Context Generation.
The only thing useful is the name of the last DLL manifest it was trying to load. It was a .NET assembly that had a bunch of ComVisible classes in it that are not necessary at startup. I commented it out of the manifest and then the program loaded. But, as I looked at it, I noticed it had nearly 500 clrClass definitions in the manifest for the DLL. I had another DLL that had about a third of that number. I re-included the original DLL in my application manifest but commented out the ~170 clrClass DLL in the application manifest. When I did that, the application loaded to success.
So, it appears to me that there is some kind of limit on the maximum number of clrClass type information that can be loaded from the manifests for Isolated COM. It seems to be a cumulative thing because if I comment out either DLL, then it loads. But if I leave both in, then it won't load.
Is there a documented limit to the amount of type information that the manifest loaders can process?
Is there a registry setting I could change, or some constant I could add to my manifest to bump up the limit? I have no idea what the limit is, but there seems to be one.
Running depends.exe gives this:
Error: The Side-by-Side configuration information for "c:\src\v13\debug-win32\STATIST.EXE" contains errors. The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail (14001).
I eventually found the problem. It was not that there were too many clrClass'es in the manifests. I used ProcMon and PerfView to try and see the problem, but they didn't show much.
Eventually, I just started editing on the manifests and deleting and undeleting clrClass entries from the manifest until I found the problem. I sort of did a binary search...delete half and see if it goes away. If not delete the other half and see if the problem goes away. Then repeat with the problem section and keep halving until the offending clrClass (or clrClasses) is found.
To make a long story short, I found that two different clrClass'es in the two DLLs I was having problems with had the same CLSID. The manifest loader was erroring out because there were COM visible classes in the two DLLs that had duplicate CLSIDs. Somewhere, someone had made a mistake with copy and paste or something. However, the error message from the sxstrace utility did not specify what the error was. It just gave the generic error. To triple check, I wrote a utility to check the CLSID, ProgID, and class names of all the COM visible classes in the two libraries. I eventually found that there were 3 CLSIDs that were duplicates.
So, if anyone ever looks at this in the future, they can see that duplicate CLSIDs (or ProgIDs?) in the clrClass declarations in the .NET assemblies might be their problem.
I have a MATLAB mex file which does not work, giving me the "The specified module
could not be found." error. Now, I understand that probably the issue is that it tries to link\call\whatever dll's which are missing. I'd like to figure out which ones so that I can provide them.
Here it is explained how to use the Dependency Walker to generate a text file which supposedly has this information. I generated the file but it's a huge one and I am at a loss as to where exactly the information about the missing files is.
I am thus looking for advice on how to locate the missing files reports in the Dependency Walker output.
One way might be to run Process Monitor, filter (Ctrl+L) processes to matlab.exe, and inspect lines with 'file name not found' immediately after calling your mex.
I can suggest another way - but it is more complicated and involves attaching a debugger to matlab. Don't go there unless Process Monitor fails to address this.
When I try to run my Visual C++ application, a box comes up saying "The application was unable to start correctly (0xc000007b)." The only output is
Loaded 'C:\Windows\SysWOW64\ntdll.dll', Cannot find or open the PDB file
Loaded 'C:\Windows\SysWOW64\kernel32.dll', Cannot find or open the PDB file
Loaded 'C:\Windows\SysWOW64\KernelBase.dll', Cannot find or open the PDB file
But all of those files exist...which makes me think that its not the cause of the application's error. With no other output, I don't know what could be wrong. If anyone knows what I could check for or how to fix it, I would be grateful.
Few blueprints:
Rebuild the application, including all dependent DLLs, and try again.
Ensure all dependent DLLs, services (like MSMQ) are available and running.
Check if one of your DLLs DllMain is returing failure, which causes the application to start. OS won't start, if any of DLL returns failure while initializing.
Ensure you have correct CRT/MFC versions for the Debug/Release DLL you are using, or have linked other DLLs/EXE with.
Use Dependency Walker to find out of any DLL is missing, not found, or of different platform.
A colleague of min told me he read once that re-building opencv should fix this. Which worked for me. Notice I'm using opencv1.1(x86) under a win7 64-bit cpu.
Best of luck.
Hasan.
I have a program which stores plugins in multiple directories, like so:
root/
core/bin/
app.exe
core.dll
plugin.dll
support.dll
a/bin/
a.dll
a_support.dll
In this example, a.dll imports core.dll, support.dll, and a_support.dll (they are in that order in the import table). a_support.dll imports support.dll. I can change all but the support modules, those are redists of a third-party library.
My code calls LoadLibraryEx(name, NULL, LOAD_WITH_ALTERED_SEARCH_PATH) to load each plugin. For core.dll and plugin.dll, this works fine.
When I try to load a.dll, it fails saying a_support.dll was not found. No errors about core.dll or support.dll, perhaps because they're already in memory.
My suspicion is that when a_support.dll is loaded, support.dll cannot be found, but this seems unusual as a.dll appears to import support.dll before a_support.dll.
Is this layout of modules even possible to use? Will the system be able to use the already-loaded support DLLs, or will it go searching for them and fail? Would there be a way to handle this through manifests? Is there a way to make this work, or will I have to relocate all modules into a single directory?
Edit: At Adrian McCarthy's suggestion, I ran the loading sequence with Process Monitor tracking, and it seems that when I call LoadLibrary("root/a/bin/a.dll", ...), it starts by searching the root directory, then system directories, then down through the path. For some reason, it never searches a/bin/, which it very much should.
I double-checked the paths, and noticed that my calls to load plugin.dll where using the wrong path (root, instead of root/core/bin). Either way, core.dll was loading correctly. After fixing that, I tried it again and this time a.dll does find a_support.dll and seems to load. However, that makes absolutely no sense, unless the loader is successfully using support.dll from... somewhere. The procmon log doesn't show it even attempting to load support.dll again, so I'm not entirely sure at this point if there actually is a problem (besides behavior from the loader that makes no sense).
I suggest using Process Monitor to see what's really happening. You'll see if it's looking in the right place, whether a_support.dll is opened but not loadable because something else is missing, etc.
Certainly one solution would be to place all DLLs in the same directory, the same directory as the .exe. If you can bring yourself to do that it would be the simplest approach for sure.
If not then you will have a bit more work on your hands. I guess you are expecting that the loader will search in the directory where the DLL lives. Sadly it doesn't. Instead the loader will look first in the executable file's directory, and then the rest of the DLL search order. This is why a_support.dll fails to load, because it is not in the same directory as the executable.
The fact that modules are already in memory is beside the point. The loader goes looking for the file. When it finds the file that it wants it then checks to see if it is already loaded. If so then it simply bumps the reference count to that module. Otherwise it loads it into the process.
You could switch to using LoadLibrary for all DLL loads and always being explicit about the path. That's probably inconvenient.
You could use side-by-side assemblies but that doesn't sound very compatible with a plugin architecture.
So I think the main remaining option is SetDllDirectory. Call this just before you load the plugin. You only need to add a/bin to the search path since the rest of the modules are in the executable directory and so will be found without trouble. Restore this setting to its default by calling SetDllDirectory again, passing NULL, once the plugin has loaded and resolved all of its imports.
If you have multiple sub-directories then use AddDllDirectory.
This is a rather confusing application.
Some questions then:
Which dll's does app.exe implicitly import?
core.dll is both implicitly loaded by a.dll AND as a plugin via LoadLibraryEx?
How was the call to LoadLibraryEx on /plugin.dll ever succeeding? If the path was FQ and did not point at an actual dll, LoadLibrary should have failed outright on that dll.
I can't tell if you're giving sample code or real code. You wrote:
LoadLibrary("root/a/bin/a.dll", ...)
If that's the real code, there are two problems here.
First, LoadLibrary doesn't do what you'd expect with a relative path. From MSDN:
To load a module from a relative path without searching any other
path, use GetFullPathName to get a nonrelative path and call
LoadLibrary with the nonrelative path. For more information on the DLL
search order, see Dynamic-Link Library Search Order.
Basically, you give it a full path and get that file, or you let it search for a name in all the "usual" locations. If you give it a relative path, it basically ignores that path, grabs the name, and looks in the usual locations.
If you really meant LoadLibraryEx, note that when you use LOAD_WITH_ALTERED_SEARCH_PATH you get "undefined behavior" if handed a relative path. Again quoting MSDN:
If this value is used and lpFileName specifies a relative path, the behavior is undefined.
Second, you have forward slashes instead of backslashes. Neither LoadLibrary nor LoadLibraryEx likes those.
This is a variation on the old
System.DllNotFoundException: Unable to load DLL 'foo.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E).
problem (where, of course, foo.dll is the name of an actual DLL). The strange part is that I only get this error when I "Run" in VS (2008 if that's relevant). That sits in the MyApp.vhost.exe processes.
If I run the actual app in a command line (MyApp.exe) I encounter no errors. The problem extends to unit tests with MSTest.
A check on the DLL with DependencyWalker on Foo.dll doesn't show any issues.
Any ideas?
Make sure the DLL is in the folder where your EXE is.