How to Determine Which Dll Dependency is Failing to Load in Windows Store/Universal Apps? - visual-c++

When running a UWP project I'm working on I receive the following dialog.
"Unable to activate Windows Store app 'MyAppsMangledName'. The 'MyExeName' process started, but the activation request failed with error 'The App didn't start'."
The Visual Studio output has the following.
The thread 0x3d4c has exited with code -1073741515 (0xc0000135).
The thread 0x3b50 has exited with code -1073741515 (0xc0000135).
The program 'MyExeName' has exited with code -1073741515 (0xc0000135) 'A dependent dll was not found'.
The Event Viewer has 3 events that basically restate the popup dialog in 3 different ways and nothing else.
Running Process Monitor during the startup shows me many dlls being successfully loaded but nothing indicating failure besides some NAMENOTFOUND events which unfortunately don't show what name wasn't found.
In Win32 a helpful dialog usually indicates which dll could not be loaded. And of course with .Net apps the fusion logs make tracing this very straight forward. But for Store/UWP apps I can't seem to find a good way to track down the offending dependency.

This just hit me too on a project I'm working on. And after much digging, someone on my team was able to figure it out. So figured I'd share it for others struggling with the same issue.
We're doing UWP with C++ using VS2015. So with that in mind, there is a program called gflags located for me at C:\program Files (x86)\Windows Kits 10\Debuggers\x64\gflags.exe
So you'll want a cmd window with admin, and run the command gflags.exe -i your-program-name.exe +sls
Note: gflags wasn't in my path so either add the path or navigate to where it is before executing the command.
Just pass in the name of the exe without directories. What it does is sets a registry setting for VS that turns on sls (show loader snaps) for exe's matching that name. Then run your application in VS and and you'll get a large amount of dll loading information including names of the dlls that fail to load in your output window. In our case it was this:
5038:34f4 # 789320468 - LdrpProcessWork - ERROR: Unable to load DLL: "vccorlib140d_app.DLL", Parent Module: "E:\projects---\Source\Builds\vs2015_Debug_UWP_x64\AppX---.exe", Status: 0xc0000135
Another quicker alternative way to test this (YMMV) was to compare the output with another build config that does work. In our case, we can run release builds just fine, but debug builds barf. And the release output showed vccorlib140_app.dll loaded while the debug had it missing.

Related

DLL not downloading in WinDbg when analysing crash-dump file

After failing to get DebugDiag to analyse crash-dump files it was suggested that I try using WinDbg instead.
The crash-dump files have been created on a Windows Server 2016 box, running my ASP.Net 4.5.2 web application on IIS-10. My ASP.Net web application contains several 3rd party components, with their individual DLLs.
I have copied the crash-dump files onto my Windows 10 development machine, and am running WinDbg locally instead of on the server.
The problem is... when I run !analyze -v in WinDbg on any of the crash-dump files, it effectively hangs while "Downloading file xxx.DLL" (xxx.DLL being the name of just one of the 3rd party component DLLs), and eventually cancels itself after a period of time.
I'm running WinDbg on the same machine that I built the website on in the first place... so is there a way of telling WinDbg that it can find the DLL in a particular location on the local machine?
I obviously don't have a .pdb file for any of the 3rd party components, and so I'm not bothered about it loading symbols for those DLLs... but either I somehow tell it to ignore those particular DLLs, or I tell it how to find them locally.
Can anybody point me in the right direction?
You don't have to analyze the dump file with !analyze -v.
If you need to load dll, then .load D:.... is enough.
To maunal analyze a dump file.
Please run .loadb sos clr to load debug module. If the crash server and your machine run different version of .net framework. Then you need to load sos.dll manually.
When you need to debug .net application in IIS, !mex extension is recommened.
https://www.microsoft.com/en-us/download/details.aspx?id=53304
You can load mex.dll via .load c:\.....\mex.dll
!mex.aspxpages can show all requests inside the process and their process
!mex.mthreads show the status of all threads
!mex.clrstack2 will show all exceptions and mananaged call stack in specific thread.
1.You can use ~* k to load the full call stack in all threads and !mex.mthreads check status.
Then you may find something like KERNELBASE!RaiseException in specific thread
2.Then go to this thread via threadid~ like 12~
3.Run !mex.clrstack2 and it will show the crash exception
Basically, no, you cannot speed up the process of loading symbols for DLLs where you don't have symbols. IMHO, the only way of speeding up the symbol process would be to disable the HTTP server, so that symbols are only searched on your local disk.
See also: How to set up symbols in WinDbg if you have not done this often.
Getting a HTTP 404 for those files should not take very long. However, it tries various file endings and pointers etc. Sometimes Microsoft servers are slow. Also, having a lot of 3rd party DLLs may sum up of course. That can be pretty anoying.
I'll start by saying I don't 100% understand everything I had to do, but here are the step I took to discover where the stackoverflow issue was in my application...
The majority of the information came from this blog.
On the server I added the following registry settings to create the crash dump files...
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps]
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\w3wp.exe]
"DumpCount"=dword:00000005
"DumpFolder"=hex(2):43,00,3a,00,5c,00,43,00,72,00,61,00,73,00,68,00,44,00,75,\
00,6d,00,70,00,73,00,5c,00,00,00
(The DumpCount is the number of files to store before it starts overwriting old ones - DumpFolder is where the files are to be saved, is a REG_EXPAND_SZ and in my case represents C:\CrashDumps\)
Waited for crashes to happen
Copied the crash files into a directory on my local machine called C:\WinDbg\CrashDumps\
Create another directory called C:\WinDbg\Symbols, into which I placed...
clr.dll (from the server, taken from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\)
sos.dll (from the server, taken from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\)
all .dll and .pdb files from my local development environment, including third party component .dll files
Installed WinDbg via Windows Store on my Windows 10 development machine
Ran windbgx -y c:\windbg\symbols via Run command (for some reason it's windbgx on my machine but maybe that's because it's via the Store rather than manual download)
In the file menu Open dump file and select one of the dump files in C:\WinDbg\CrashDumps
Ran the following commands...
.symfix
.reload
.load c:\windbg\symbols\sos.dll (see note 1 below)
!clrstack (see note 2 below)
Although this didn't give me all the information I expected, what it did show was that one of my 3rd party components was 100% to blame for the stackoverflow exception.
Note 1 - Lots of places I read said that .loadby sos clr should be used, but that just gave me The call to LoadLibrary(C:\ProgramData\Dbg\sym\clr.dll\5E7D1F3B9eb000\sos.dll) failed and I couldn't figure out how to fix it... so instead I've used .load c:\windbg\symbols\sos.dll.
Note 2 - The !clrstack command worked because WinDbg appeared to pre-select the thread that had the exception. The other option is to use ~*e !clrstack which will show you call stacks for ALL threads.

Debugging Azure WebJob locally - recompile fails

I have a webjob that I'm debugging locally as a console app. But once I stop the code from within VS2017 I'm unable to recompile the exe as I get the following error
Unable to copy file "obj\Debug\******.******.exe" to "bin\Debug\******.******.exe". Access to the path 'bin\Debug\******.******.exe' is denied.
When I look at the processes that are running theres nothing there that jumps out.
I've closed VS and restarted it, but thats not cleared the issue.
Other than restarting my machine is there anything else I can try?
You can use the Windows Resource Monitor tool. Once opened, navigate to the CPU tab and enter the full path of the .exe (e.g. C:\Project\bin\debug\App.exe) in the Search Handles text box in the bottom-mid right corner and search. You should see the list of processes currently locking on the particular resource (in this case, the .exe). Select all the unwanted processes, right-click and end process. Depending upon on the version of Windows you are running, the experience might differ a bit but the general idea is more or less the same.

Unable to debug in Visual Studio because process can not access file

When I try to debug in Visual Studio I get the error message:
Unable to copy file "C:\Users\Name\Dropbox\Company Name\Development\Product Name 4 - Release Candidate\packages\MahApps.Metro.1.1.2.0\lib\net45\MahApps.Metro.dll" to "bin\Debug\MahApps.Metro.dll". The process cannot access the file 'bin\Debug\MahApps.Metro.dll' because it is being used by another process. Product Name 4 - Release Candidate
How can I fix this error?
This happens all the time in Dropbox. Dropbox does some occasional (very brief) locking of files as it is indexing them, and if you happen to attempt to open a file handle with the write attribute set at the same moment, the program will receive a file I/O exception (this can happen to your own code as well, so if you regularly work in Dropbox, be sure to handle that gracefully).
Try compiling/running it again and see if the problem goes away. If not, then you likely still have an instance of your application running in the background. This can occur if your program ever forks. VS will terminate the original process, but often not forked processes from it. Check task manager to be sure. It will be listed as a background process in Windows 8/8.1

How to see MSBuild output generated in project load time?

I've noticed that when Visual Studio 2012 loads/initializes projects (when opening a solution or when changing platforms/configurations), it may execute some MSBuild targets - those that are listed as InitialTargets (it doesn't always do that - sometimes it waits until you actually build it; I can't figure out when exactly, but that's a different question).
Anyway, these targets may generate some output in the form of MSBuild messages. If the targets were being run as part of a build, these messages would go to the output window of Visual Studio (and perhaps a log file). These "load-time targets", though, do not seem to send their output to the output window.
How can I see or log the output of MSBuild targets which execute outside of build time, and specifically in initialization time?
The best information source from the MSBuild team at Microsoft I could find is dated (2005), but may still be actual if no one could come up with fresher information:
The project load logger is used when projects are opened. It discards all messages logged while the project is opened, puts warnings in the error list, and displays any errors in a message box to the user. The errors displayed are quite detailed and useful in helping diagnose project file formatting issues.

prevent vstest discovery engine locking DLLs

I have some C# unit tests for a VS2012 project which calls a VS2010 c++ DLL using DllImport pinvoke.
As a pre-build event for the test project, I copy the latest version of the DLL to the binary project for the test.
This repeatedly fails if vstest.discoveryengine is running. It appears that the 'discovery engine' is loading the tests and holding the lock on the DLL.
If I kill vstest discovery engine, then I can build and run the tests. otherwise the build fails, and VS2012 offers to run a previous version ( with a model dialog which doesn't have a 'don't show this message again' option)
Is there something I can do to either force the test project to unload the DLL when not actually running the tests, or to disable the background discovery executable?
I've hacked a workaround by creating an executable called Kealakekua which kills vstest.discoveryengine.x86, vstest.executionengine.x86, and with that as the first part of the pre-build event it can copy the files and build, but would prefer not to be fighting visual studio for my file.
I recently also had this issue and the problem was caused by my own user code.
During test discovery all the test classes are instantiated and in one of our test class constructors, a quite complex business classes was initialized. The problem is that during initialization of it a background thread was created, that did the following:
socket.Read(...)
This thread kept running forever waiting for some socket data to arrive and as a result locked our assembly.
So the solution for me was to make sure this code won't get called during test discovery.
You can check, if you are affected by this issue, by attaching Visual Studio to the test discovery engine when it has locked some assembly. After pressing pause you normally will see, that the current executing line is somewhere in your own user code (also check the Threads window).
I had a similar problem where I created a "Test" project that didn't actually have any tests in it. (As a C++ Library developer I wanted to make sure that certain headers were able to be compiled with CLR enabled, so I made a fake CLR project to just compile them with CLR. If it compiled, it passed.) The DLL created was being held open indefinitely by the vstest.discoveryengine.
I fixed it by adding an Ignored test to the project. I think vstest.discoveryengine will hold on to the dll until it finds all the tests in the dll, but if there are no tests to be found, then it will hold onto it forever.
The test I added (I think it is the default test) Note the TEST_IGNORE() to make sure it isn't executed:
#include <CppUnitTest.h>
namespace CLRTests
{
TEST_CLASS(CLRTestsClass)
{
public:
BEGIN_TEST_METHOD_ATTRIBUTE(CLRTest1)
TEST_OWNER(L"")
TEST_DESCRIPTION(L"")
TEST_PRIORITY(1)
TEST_IGNORE()
END_TEST_METHOD_ATTRIBUTE()
TEST_METHOD(CLRTest1)
{
// TODO: Your test code here
}
};
}
I hope this is possible in your situation.

Resources