ASP.Net Exception Shows File Path - asp.net-mvc-3

When my ASP.Net MVC application encounters an error, the full file path of the c# class is displayed in the exception even though I've only deployed binaries. E.g.
at: C:\DevelopmentServer\MVC_Project\AccountManagement.cs line 45
Where is this path information being stored? Is it in the compiled dll and is there a way to remove it?

I believe this is stored in the PDB files generated during the compile, and it reflects the paths to the code on the build machine.

Related

LNK4099 errors for many individual object files, Visual Studio 2015

When building a large C++/Fortran app, I recently started getting LNK4099 errors for virtually every C++ object file. For example
Cfile.obj : warning LNK4099: PDB 'lnk{3FE844DB-7378-4485-9D93-6B1B48386536}.tmp' was not found with 'Cfile.obj' or at 'C:MyApp\x64\Debug\lnk{3FE844DB-7378-4485-9D93-6B1B48386536}.tmp'; linking object as if no debug info
Unlike a number of previous posts, this is not due to a library missing PDB info; the files with the errors are all my own source code, and freshly built.
This is Visual Studio 2015, building under 64-bit Windows 7. The problem occurs for both debug and release builds. The options for the debug build are C++: /Zi / Od; Linker: /DEBUG, Generate Full Program Database File.
The app is C++, using a Fortran library, created by Intel Fortran XE2017, and built with /debug:full. Linking to the Microsoft libraries (MFC, msimg32.lib, nafxcwd.lib, libcmtd.lib, etc) is static.
If I compile a single C++ source file AFile.cpp using F7 (Build/Compile) and then build the project, I get all the same errors EXCEPT there is none for AFile.obj. The debugging information for AFile is in the app's PDB (I can set breakpoints). Files that have the errors are missing debug info in the app's PDB (as the error message says), and I cannot set breakpoints.
What setting or configuration could be causing this mysterious behavior? I do not have this issue with smaller projects.
The LNK4099 documentation shows a DUMPBIN command that can be used to list the full path name of a .pdb file associated with an object file...
dumpbin /section:.debug$T /rawdata objectname.obj
It might be interesting to examine AFile.obj from your F7 experiment and another .obj file generated by the project build to see how the PDB file names differ (if they differ).
Assuming you're doing a build, not rebuild, of the project in your F7 experiment it might also be interesting to see what happens if you compile AFile.cpp with F7 and then do a full rebuild of the project. A full rebuild would recompile AFile.cpp where a regular build wouldn't.
Once you know what you should be looking for you can start trying to figure out if your build is: not creating the PDB files; creating them in the wrong place; creating them with the wrong name; or removing them after they're created.
UPDATE
I should have added the caveat that /PDBALTPATH can set the string shown by the DUMPBIN command above to a value different from the actual PDB file's pathname.
Per #Frank Boyne's suggestion, I found that
dumpbin /section:.debug$T /rawdata *.obj
lists the same result for all the object files, namely 0x1B byes of binary data, followed by the full path to App.pdb. Recompiling a single file shows the identical path, but slightly different binary data.
So, the answer is, the project's Program Database File Name property was set to $(TargetDir)$(TargetName).pdb, when it should have been $(IntDir)%(Filename).pdb. Following this change, .pdb files appeared with each object file (i e, separate file in the same directory), and the build completes without any LNK4099 errors.
This solves the original problem. I am wondering, though, if there is a way to have the PDB information added to a single output file, rather than producing a separate PDB file for each object file.

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

vs2010 debugging: module was built without debugging information?

Getting this message, which is not true
The following module was build either with optimization enabled or without debug information.
And it gives me a path to temp asp.net file as
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root\47cdc49a\658f757e\assembly\dl3\0fbfef54\55a1ff8a_28eacb01\MyModule.dll
I open folder and there are three files as expected dll, pdb, and ini. What gives?
Under Debug>Modules this dll was added to excluded list of dll's that should not have symbols loaded. Once I removed it, it works fine.

Ambiguous dll parser error when trying to debug a project

I'm getting the following error when I try to debug my MVC solution:
Parser Error
Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.
Parser Error Message: The type 'HandiGamer.MvcApplication' is ambiguous: it could come from assembly 'C:\Users\Kevin\documents\visual studio 2010\Projects\HandiGamer\HandiGamer\bin\HandiGamer.DLL' or from assembly 'C:\Users\Kevin\documents\visual studio 2010\Projects\HandiGamer\HandiGamer\bin\HandiGamer.WebUI.DLL'. Please specify the assembly explicitly in the type name.
Source Error:
Line 1: <%# Application Codebehind="Global.asax.cs" Inherits="HandiGamer.MvcApplication" Language="C#" %>
Source File: /global.asax Line: 1
This is the first time I've encountered this error with my project. All I've changed since the last time I debugged it was a .master page, a view, and I added a couple ViewModel classes. My solution has two projects - HandiGamer.WebUI and HandiGamer.Domain - but I've never encountered an ambiguity issue with them before. Rebuilding my solution did nothing. I'm not sure what else to do.
Have you renamed you assembly recently? In this case it can be that the old DLL is still in your bin folder ...\Projects\HandiGamer\HandiGamer\bin and is being loaded on runtime. As the error message tells you, the DLLs
HandiGamer.DLL
HandiGamer.WebUI.DLL
both contain HandiGamer.MvcApplication so the parser cannot decide which of them to take and is getting a conflict when you try to run it (compiling usually works fine with no errors, the issue typically occurs during runtime).
To resolve this, delete them from the bin folder above manually, then rebuild the entire solution. Unfortunately, 'Clean Solution' does not always clean up everything correctly so you have to do it sometimes by yourself.
Hint: If you unload the project (in Visual Studio: right-click the project, then select "Unload..."), you can edit the project file afterwards in the text editor and then search for assemblies there (to do that, right-click again on the unloaded project, then select "Edit...").
It contains all the references you have specified - but be careful not to mess it up. After you have searched and found the information you were looking for, close it and re-load the project. This is usually much faster than going though all entries in the References section of your project.
It looks like the MvcApplication class is defined in both assemblies in the HandiGamer namespace. Try opening them with Reflector to confirm this by searching for this class name. Then remove the duplicate class by leaving it only in your ASP.NET MVC application assembly. The other project must be a class library, not a web application.

How do I use PDB files

I have heard using PDB files can help diagnose where a crash occurred.
My basic understanding is that you give Visual studio the source file, the pdb file and the crash information (from Dr Watson?)
Can someone please explain how it all works / what is involved?
(Thank you!)
PDB files map an assembly's MSIL to the original source lines. This means that if you put the PDB that was compiled with the assembly in the same directory as the assembly, your exception stack traces will have the names and lines of the positions in the original source files. Without the PDB file, you will only see the name of the class and method for each level of the stack trace.
PDB files are generated when you build your project. They contain information relating to the built binaries which Visual Studio can interpret.
When a program crashes and it generates a crash report, Visual Studio is able to take that report and link it back to the source code via the PDB file for the application. PDB files must be built from the same binary that generated the crash report!
There are some issues that we have encountered over time.
The machine that is debugging the crash report needs to have the source on the same path as the machine that built the binary.
Release builds often optimize to the extent where you cannot view the state of object member variables
If anyone knows how to defeat the former, I would be grateful for some input.
You should look into setting up a symbol server and indexing the PDB files to your source code control system. I just recently went through this process for our product and it works very well. You don't have to be concerned about making PDB files available with the binaries, nor how to get the appropriate source code when debugging dump files.
John Robbins' book: http://www.amazon.com/Debugging-Microsoft-NET-2-0-Applications/dp/0735622027/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1222366012&sr=8-1
Look here for some sample code for generating minidumps (which don't have to be restricted to post-crash analysis -- you can generate them at any point in your code without crashing): http://www.codeproject.com/KB/debug/postmortemdebug_standalone1.aspx

Resources