Why are my DLLs loading from SysWOW64 when they exist in the application directory? - windows

I'm writing a 32-bit C++ application on Windows 8.1 x64 using Visual Studio 2013 that depends on Python 3.3 and libVLC. I have python33.dll, libvlc.dll, and libvlccore.dll in the same directory as my executable, which I also have set as the working directory under Project > Properties > Debugging. According to MSDN, unless you're using the altered search path (which should only apply if you're using LoadLibraryEx to load the DLLs at run-time; in my case these DLLs are loaded at load-time), the application directory should always be searched before the system directory. However, according to Visual Studio, all three of these DLLs are being loaded from C:\Windows\SysWOW64. This is causing me problems as the version of libVLC I have there is much older than the one I'm trying to use.
That MSDN article only lists 3 exceptions to the normal search process. These DLLs are loaded as soon as the process starts, so obviously it couldn't be the system versions were already loaded (but just to be sure, I created a .local file since it mentioned redirection would override that, and it had no effect). I've checked the registry to see that they didn't somehow get registered as "Known DLLs", so that doesn't appear to be the problem. It's possible that python33 is being loaded as a dependency of Boost.Python, but even if it's loaded only by name the app directory should still be searched first, and in any case none of my other dependencies reference VLC. As a guess I tried marking the VLC libs as delay-load (I couldn't with Python due to data imports), and I got the following warnings, which I found interesting:
1>LINK : warning LNK4199: /DELAYLOAD:libvlc.dll ignored; no imports found from libvlc.dll
1>LINK : warning LNK4199: /DELAYLOAD:libvlccore.dll ignored; no imports found from libvlccore.dll
However, dumpbin shows that my compiled exe imports several functions from libvlc.dll.
I could of course replace or delete the system versions, but that's not really a solution if I ever attempt to distribute this application. I'm not really sure what else would be causing this. Can anyone suggest anywhere else for me to look?

Related

Visual Studio c++ 2015 runtime deployment with legacy application

I have a winforms .net4.5.2 application which depends on a c++\cli wrapper which is included in the VS project by reference. When the winforms application, that is built using Any CPU, is launched a assembly resolver is used to point out the correct platform dll for the reference and Assembly.Load(ed) in the platform specific folders in the root of the application folder i.e. \x64 or \x86.
This c++\cli is now built using the v140 platform toolset which depends on the Universal CRT dll:s. Looking here https://blogs.msdn.microsoft.com/vcblog/2015/03/03/introducing-the-universal-crt/ I was able to locate the necessary dll:s (41 * 2 of them) and I did what I was told to copy them inside the \x86 and \x64 folders. Now since the change to v140 platform my application does not start anymore and ProcessMonitor file operations tell me the following:
SUCCESS C:\MyApp\x64\TheCLIWrapper.x64.dll
SUCCESS C:\MyApp\x64\ADependency.dll
SUCCESS C:\MyApp\x64\msvcp140.dll
SUCCESS C:\MyApp\x64\vcruntime140.dll
SUCCESS C:\MyApp\x64\api-ms-win-crt-runtime-l1-1-0.dll
NAME NOT FOUND C:\MyApp\ucrtbase.dll
How is this even possible if before assembly resolving my c++\cli wrapper I explicitly set the dll directory (using SetDllDirectory) to the C:\MyApp\x64 folder? By this I mean why is the loading process looking in C:\MyApp for the ucrtbase.dll?
Naturally, if all the 41 dlls of a specific platform are copied to the root C:\MyApp\ folder it works but this is not an option for me, nor is the installation of c++ runtime executable on the clients running the application.
Does anyone have an idea or any tips on how to solve this deployment problem?
So you basically wanna do x-xopy deployment with x86-dll's in MyApp\x86, and x64-dll's in MyApp\x64?
How about explicitly loading the dll's with LoadLibrary?
I used procmon to inspect where the UCRT DLLs were trying to load each other from. Noticed the paths it was searching did not include the path set from the earlier SetDllDirectory. No matter what I tried the paths it searched seemed to only include the default values.
The working directory was always included as per Dynamic-Link Library Search Order and the only solution I could get was to change the current working directory to the appropriate one, load the DLL with the UCRT requirement, and change it back. Nothing else worked (including changing PATH environment variable)
Note this is very much not threadsafe

Why am I getting so many .pdb files?

I'm using MSVC 2013 compiler, CDB debugger, and Qt Creator/qmake under Windows 7. I just discovered that the build directory for one of my projects is a whopping 16 gigabytes. The culprit is a sub-directory named "srv" which contains various .pdb files. The curious part is that there are pdb files for all kinds of system libraries like commctl32, ntdll, user32, etc. Do I really need to generate pdb's for these system files, or is this some setting that I can turn off, or is it a bug? I don't plan to debug user32.dll, so I can't see any reason to have debug information generated for it.
The pdb files for commctl32, ntdll, user32 are not generated (as those libraries are not compiled by you). Those are automatically downloaded when you debug applications for resolving the memory addresses into function names (i.e., preparing a readable stack trace).
You can configure this in VS2013 settings, Debugging, Symbols. There you can disable automatic downloading and/or change the folder where to put the files. Suppose this can also be disabled/configured for other debuggers.
The "symbol cache" grows: whenever you install windows updates, new libraries might get deployed to your computer and in your next debugging sessions new symbols are downloaded. If you have a fast internet connection, it's no problem to empty the cache.

Visual Studio - "The application was unable to start correctly"

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.

Trouble getting xperfview to load symbols for DLL

I have been fighting tooth and nail with xperf to get symbols for a tool I'm profiling. My code that runs within the tool is split between the .exe and a .dll -- the important stuff to profile being in the .dll. I ran xperf:
xperf -on PROC_THREAD+LOADER+INTERRUPT+DPC+PROFILE -stackwalk profile
And then I ran my tool for a bit, and then
xperf -d profile.etl
Then I tried xperfview. I loaded up the profile, toggled "load symbols" on, and opened the summary table. No symbols at all -- literally module came up "unknown" in the function column. I've scoured other threads on this and here's what I've tried:
I set my environment variables, _NT_SYMBOL_PATH and _NT_SYMCACHE
I cleared out my symbol cache and run xperf -symbols -i profile_results.etl.
I copied over dbghelp.dll from a recent version of Windows Debugging Tools and repeated the above.
After doing all this I now get function names showing up properly for most of the modules that are not my own code, but I can't get my dll to show up. The dll is being compiled in release mode (with optimization) but I set the Visual Studio project specifically to create a pdb, I've verified that the pdb exists and that it is within a directory on my _NT_SYMBOL_PATH. Does anyone know how I can fix this, or at least debug it further?
You can set some environment variables to enable diagnostic logging during symbol loading:
DBGHELP_DBGOUT = 1
DBGHELP_LOG = C:\dbghelp.log
I just encountered the same problem... tried all the same steps... browsed all the (apparently) similar advice...
Additionally, I tried launching symchk using the same dbghelp.dll/symsrv.dll DLLs I had copied into my WPA 'bin' folder, to make sure that my PDB is locatable. (still thinking I'm going crazy...)
I should note: my _NT_SYMBOL_PATH value contained servers with lcl cache & straight up local locations: _NT_SYMBOL_PATH=srv*D:\SymbolCache*http://msdl.microsoft.com/download/symbols;D:\GitHub\....
Then it dawned on me that my DLL, used by my "partner" EXE, is loaded dynamically via LoadLibrary()/GetProcAddress() ... could this be an issue for XPerf ?????
I hesitated even trying this...
I added a useless export in my DLL, and I invoke it directly in the EXE (to trigger an Import Table entry for my DLL) So now the EXE depends on the DLL to even load.
Turns out...
.............then XPerf loaded all the symbols :).
Edit: I just found this URL on MSDN, where someone posted code back in '11 that demonstrates a similar (the same?) problem
EDIT:
I recently discussed this with a collegue, and learned that XPerf will properly "decide" to load symbols for DLLs loaded programmatically ... IF the DLL remains loaded until the termination of the process.
So, for DLLs that are Loaded and Unloaded during the execution, and are unloaded at termination... XPerf will skip the attempt to load those symbols.
I'm not sure if this helps, but in here is one more detail I came across today in addition to the Q&A at xperf can't load my DLL's symbols:
For me, xperfview doesn't like PDB files on mapped network drives: as I was running xperf and xperfview on a different machine from where the code was built, I was getting both executables and PDB files off a network share, which I mapped to a drive letter to recreate exactly the same absolute paths as on the build machine - no luck. Even adding the folder with the PDB files to the symbol path didn't help.
Everything worked as expected once I made sure the .pdb file was in a local folder.
Try using wpa instead of xperfview. It uses the same system for loading symbols that xperfview does but it also has a Diagnostic Console which lets you see symbol loading messages which can be helpful.
Also, you should tell us what you have _NT_SYMBOL_PATH set to. There are many ways that it can be incorrectly set.
Also, in _NT_SYMBOL_PATH you should specify a local cache for your PDB files -- you can then check there to see if your PDBs have been copied to the local cache.
You can also look in the SymCache Path (pointed to by _NT_SYMCACHE_PATH, defaults to c:\symcache) which is where the WPT .symcache files are stored. The PDB files are converted to this format and the .symcache files are what are ultimately loaded by WPA and xperfview.
For more information see:
http://randomascii.wordpress.com/2012/10/04/xperf-symbol-loading-pitfalls/

Loading multiple copies of a group of DLLs in the same process

Background
I'm maintaining a plugin for an application. I'm Using Visual C++ 2003.
The plugin is composed of several DLLs - there's the main DLL, that's the one that the application loads using LoadLibrary, and there are several utility DLLs that are used by the main DLL and by each other.
Dependencies generally look like this:
plugin.dll -> utilA.dll, utilB.dll
utilA.dll -> utilB.dll
utilB.dll -> utilA.dll, utilC.dll
You get the picture.
Some of the dependencies between the DLLs are load-time and some run-time.
All the DLL files are stored in the executable's directory (not a requirement, just how it works now).
The problem
There's a new requirement - running multiple instances of the plugin within the application.
The application runs each instance of a plugin in its own thread, i.e. each thread calls functions exported by plugin.dll. The plugin's code, however, is anything but thread-safe - lots of global variables etc..
Unfortunately, fixing the whole thing isn't currently an option, so I need a way to load multiple (at most 3) copies of the plugin's DLLs in the same process.
Option 1: The distinct names approach
Creating 3 copies of each DLL file, so that each file has a distinct name. e.g. plugin1.dll, plugin2.dll, plugin3.dll, utilA1.dll, utilA2.dll, utilA3.dll, utilB1.dll, etc.. The application will load plugin1.dll, plugin2.dll and plugin3.dll. The files will be in the executable's directory.
For each group of DLLs to know each other by name (so the inter-dependencies work), the names need to be known at compilation time - meaning the DLLs need to be compiled multiple times, only each time with different output file names.
Not very complicated, but I'd hate having 3 copies of the VS project files, and don't like having to compile the same files over and over.
Option 2: The side-by-side assemblies approach
Creating 3 copies of the DLL files, each group in its own directory, and defining each group as an assembly by putting an assembly manifest file in the directory, listing the plugin's DLLs.
Each DLL will have an application manifest pointing to the assembly, so that the loader finds the copies of the utility DLLs that reside in the same directory. The manifest needs to be embedded for it to be found when a DLL is loaded using LoadLibrary. I'll use mt.exe from a later VS version for the job, since VS2003 has no built-in manifest embedding support.
I've tried this approach with partial success - dependencies are found during load-time of the DLLs, but not when a DLL function is called that loads another DLL.
This seems to be the expected behavior according to this article - A DLL's activation context is only used at the DLL's load-time, and afterwards it's deactivated and the process's activation context is used.
Edit: Works with ISOLATION_AWARE_ENABLED as expected - runtime loading of DLLs uses the original activation context of the loading DLL.
Questions
Got any other options? Any quick & dirty solution will do. :-)
Will ISOLATION_AWARE_ENABLED even work with VS2003? Edit: It does.
Comments will be greatly appreciated.
Thanks!
ISOLATION_AWARE_ENABLED is implemented by the Windows SDK header files and thus probably wont worth with VS2003 at all. However, it is possible to download the latest Windows 7 SDK and use that with VS2003.
You don't need to use MT to link in manifests. Manifests can be embedded as resources in environments that dont have explicit knowledge.
Add the following to a dll's .rc file to embed a manifest. (With a recent enough platform sdk RT_MANIFEST should already be defined):
#define RT_MANIFEST 24
#define APP_MANIFEST 1
#define DLL_MANIFEST 2
DLL_MANIFEST RT_MANIFEST dllName.dll.embed.manifest

Resources