Category Archives: Visual Studio

Debugging a release build of a .NET application

What’s a Release Build compared to a Debug build

Release builds of a .NET application (by default) add optimizations, remove any debug code from the build, i.e. anything inside #if DEBUG is remove as well as Trace. and Debug. calls being removed. You also have reduced debug information. However you will still have .PDB files…

PDB files are generated by the compiler if a project’s properties allow for .PDB file to be generated. Simply check the project properties, select the Build tab and the Advanced… button. You’ll see Debug Info, which can be set to full, pdb-only or none. Obviously none will not produce any .PDB files.

At this point, I do not know the differences between pdb-only and full, if I find out I’ll amend this post, but out of the box, Release builds used pdb-only whilst Debug use full.

So what are .PDB files ?

Simply put – PDB files contain symbol information which allows us to map debug information to source files when we attach a debugger and step through the code.

Debugging a Release Build

It’s often the case that we’ll create a deployment of a Release build without the PDB files, this may be due to a desire to reduce the deployment foot print or some other reason. If you cannot or do not wish to deploy the PDB’s with an application then we should store them for a specific version of a release.

Before attaching our debugger (Visual Studio) we ned to add the PDB file locations to Visual Studio. So select the Debug menu, then Options and Settings. From here select Debugging | Symbols from the tree view on the left of the Options dialog. Click on the add folder button and type in (or paste) the folder name for the symbols for the specific Release build.

Now attach Visual Studio using Debug | Attach Process and the symbols will get loaded for the build and you can now step through the source code.

Let’s look at a real example

An application I work on deploys over the network and we do not include PDB files with it so we can reduce the size of the deployment. If we find a bug only repeatable “production” we cannot step through the source code related to the build without both a version of the code related to the release and without the PDB files for that release.

What we do is, when our continuous integration server runs, it builds a specific version of the application as a release build. We embed the source repository revision into the EXE version number. This allows us to easily check out the source related to that build if need be.

During the build process, we the copy the release build to a deployment folder, again using the source code revision in the folder name. We (as already mentioned) remove the PDB files (and Tests and other such files are also obviously removed). However we don’t just throw away the PDB’s, we instead copy them to a folder similarly named to the release build but with the name Symbols within the folder name (and ofcourse with the same version number). The PDB’s are all copied to this folder and now accessible if we need to debug a release build.

Now if the Release (or a production) build is executed and an error occurs or we just need to step through code for some other reason, we can get the specific source for the deployed version, direct Visual Studio to the PDB files for that build and now step through our code.

So don’t just delete your PDB’s store them in case you need to use them in the future.

Okay, how do we use the symbol/PDB files

So, in Visual Studio (if you’re using that to debug/step through your code). Obviously open your project with the correct source for your release build.

In the Tools | Options dialog, select the Debugging parent node in the dialog and then select Symbols or ofcourse just type Symbols into the search text box in Visual Studio 2013.

Now press the folder button and type in the location of your PDB files folder. Note that this option doesn’t have a folder browse option so you’ll need to type (or copy and paste) the folder name yourself.

Ensure the folder is checked so that Visual Studio will load the symbols.

Now attach the debugger to your release build and Visual Studio will (as mentioned) locate the correct symbols and attach them and then allow you to step through your source.

See Specify Symbol (.pdb) and Source Files in the Visual Studio Debugger for more information and some screen shots of the process just described.

How to exclude code from code coverage

In Visual Studio 2012 we can run code coverage analysis across our code (for example across our unit test suite). But we might not want to have all code analysed. For example I don’t really want to see the test classes as part of the analysis but do want to see the code under test.

So we can exclude code from the code coverage analysis using the ExcludeFromCodeCoverageAttribute. This can be applied to methods, properties, classes, structs etc.

What to do with NuGet packages and source control

I’ve been wondering about the best strategy with using NuGet packages and source control. For example, I don’t like to have to get the source for a project then spend ages installing all the different pre-requisites from NuGet if I can help it. Also checking in all the binaries from the packages seems a waste of space plus the problems if ever merge issues come up and the general nastiness of binaries in source control. So what to do…

Well VS2012 has a very neat feature, the Enable NuGet Package Restore option on the context menu of the solution (in solution explorer). If you select this option and you mark the NuGet packages folder as being ignored from your source control system. Then VS2012 will automatically grab the correct versions of the packages for you, but you’ll also need to go into Tools | Options | Package Manager and tick the All NuGet to download missing packages during build and then when you build the project the missing packages will be downloaded as part of the pre-build step (note: this step will not need to be repeated on a per solution basis, unlike the Enable NuGet Package Restore step).

See Using NuGet without committing Packages for a far better explanation.

Publishing an ASP.NET site to Windows 7 and IIS 7.5

I’ve just started developing a new ASP.NET MVC application on Windows 7 using IIS 7.5 and wanted to publish it to IIS. The steps are simple.

  • Right mouse click on your project and select Publish.. or select the Build menu and select Publish Selection.
  • If you do not have a profile select <New..> from the drop down and create one
  • Select Next and in my case I was deploying to a file system, so selected Publish Method: File System.
  • Browse to the target path (for example C:\inetpub\wwwroot\MyApp)
  • Set Destination URL to localhost
  • Select Next, I set this to Release configuration and delete all existing files prior to publish (obviously you choose what options you wish)
  • Select Next, the n Publish

The files and folders are copied and ready to access.

Now I was using a machine not yet set up correctly for hosting IIS and the first thing I got when trying to view http://localhost/MyApp was HTTP Error 403.14 – Forbidden. I needed to set Internet Information Services (IIS) Manager up to see the MyApp folder as an application.

  • So open IIS Manager and right mouse click on MyApp (under Sites/Default Web Site in my case).
  • Right mouse click on MyApp and select Convert to Application
  • Accept the defaults and press OK

Now reload the web page. If you get the following error in your browser Handler “ExtensionlessUrlHandler-Integrated-4.0” has a bad module “ManagedPipelineHandler” in its module list. Try opening a Visual Studio command  prompt as Administrator and type/paste

aspnet_regiis -i

(this should be available from C:\Windows\Microsoft.NET\Framework\v4.0.30319)

or to check if this is installed select the Application Pools in IIS Manager and you should see ASP.NET v4.0 (probably along with ASP.NET v4.0 Classic, Classic .NET AppPool and DefaultAppPool).

Now reload the web page and all should be working.

Note: For deploying ASP.NET MVC, make sure you set System.Web.Routing, System.Web.Mvc and System.Web.Abstractions to Copy Local = True as per documentation on http://msdn.microsoft.com/en-us/library/dd410407(v=vs.90).aspx