When sampling profiling on Windows 8 or Server 2012, nothing looks different in Visual Studio 2012, but the entire insides of the profiling collector is completely changed. With the profiler now based on Event Tracing for Windows (ETW) everything is spiffy but PDB files are more important than ever. While I’m sure you are all using the Symbol Servers and have all symbols for the code you build, what about the binaries you didn’t build and was built on the server/user’s machine?

If you’re installing binaries in the Global Assembly Cache or running Native Generation (NGEN) to pre-JIT your binaries, that code generation is done on each machine so each machine has a unique copy of the binary. When profiling, you need the PDB files for those unique binaries to see the JIT’d methods show up in the sampling profiling. You’re probably thinking you are safe that since you are not putting anything in the GAC you can stop reading now. Sadly you have to keep reading because the .NET Framework itself is NGEN’d on each install so if you want to see where your calls into the .NET Framework are eating your time, you need to get those PDBs from that machine.

Fortunately, it’s relatively easy to generate the PDB file for an individual computer after the binary was pre-JITTED by running NGEN.EXE again. Andrew Hall from the profiler team shows you exactly what you need to do here. I strongly suggest you read Andrew’s blog entry before continuing so the rest of what I’m talking about makes sense.

As Andrew points out, you can run NGEN.EXE to create the necessary PDB files, but you need to manually hunt down super-secret directory names for each individual DLL you need. That’s a whole bunch of manual steps that are screaming to be automated so that’s exactly what I did for you. You can grab the code at my ongoing WintellectPowerShell module up on Wintellect’s Code Page on GitHub.

My Add-NgenPdbs cmdlet will enumerate the GAC on a machine and produce the required PDB files for in one step. If you’re sampling on your Windows 8 or Server 2012 development machine, and you have the Symbol Server already set up, running Add-NgenPdbs will put all the appropriate PDB files into your symbol cache so the profiler will find them automatically.

If you are running the command line profiler on a different machine, run Add-NgenPdbs with the –CacheDirectory switch specifying an output directory. That will put all that machine’s PDB files into the directory and you’ll copy the paths onto your development machine’s symbol cache. Note that if your symbol cache is C:SymbolsPublic, Visual Studio will look for the symbols in C:SymbolsPublicMicrosoftPublicSymbols so that’s where you would copy the directories. As I’ve been sampling profiling on various machines I’ve just gotten into the habit of always running Add-NgenPdbs before any sampling takes place because you’re going to need those PDBs. As you would guess, if you put a .NET Framework hot fix or service pack on the machine, you’ll need to rerun Add-NgenPdbs.

By default Add-NgenPdbs only does the .NET Framework NGEN’d binaries because those alone take up at least 150MB. If you need other files, specify the –DoAllGACFiles and Add-NgenPdbs will process all files on the machine’s GAC but that can chew up a lot of disk space quickly. In my sampling profiling I just needed the .NET Framework PDB files so I made that easy. Once thing I noticed is that there are a few files, mainly from SQL Server that NGEN.EXE can’t produce the PDB files so I’ll report those as errors.

If you’d like Add-NgenPdbs to handle individual binaries or match wildcards, please feel free to create a pull request. If you have ideas for any other common developer automation, feel free to request that on the WintellectPowerShell repository or send me an email at john@<this company>.com.

  1. NAME
  2.     Add-NgenPdbs
  3. SYNOPSIS
  4.     Create PDB files for NGEN’d images on a machine.
  5. SYNTAX
  6.     Add-NgenPdbs [[-CacheDirectory] <String>] [-DoAllGACFiles] [-Quiet] [<CommonParameters>]
  7. DESCRIPTION
  8.     When running the Visual Studio profiler on Windows 8 or Windows Server 2012,
  9.     you need the PDB files for any binaries that have been NGEN’d and put in the GAC
  10.     so you can see the calls into those binaries. Fortunately NGEN.EXE can generate
  11.     the PDB files after the fact and this script automates the process for so you
  12.     don’t have to run NGEN on each binary.
  13.     Because each machine has it’s own unique NGEN’d files, you will have to run this
  14.     script on the machine you are collecting the performance runs. After creating
  15.     the PDB files, you’ll have to copy them into your symbol server on the machine
  16.     where you are analyzing the performance runs.
  17. PARAMETERS
  18.     -CacheDirectory <String>
  19.         The cache directory to place the resulting PDB files. If not specified, looks
  20.         at the Visual Studio 2012 symbol settings and uses that as the cache directory.
  21.     -DoAllGACFiles [<SwitchParameter>]
  22.         By default, this command only does the NGEN’d binaries that are in the .NET
  23.         framework directories for both x86 and x64. If you need other NGEN’d binaries
  24.         from 3rd pary tools, specify this switch. Some NGEN’d binaries, but not from the .NET
  25.         framework, will report errors when attempting to build their PDB files.
  26.     -Quiet [<SwitchParameter>]
  27.         Because it can take a long while for this function to produce all the PDB files
  28.         it reports the assembly being processed. If this is annoying to you, specifing
  29.         -Quiet will turn off that output. Any warnings about PDB creation will still be
  30.         reported.
  31. NOTES
  32.         To read more about using NGEN to produce PDB files after a binary has been precompiled
  33.         see this article:
  34.         http://blogs.msdn.com/b/visualstudioalm/archive/2012/12/10/creating-ngen-pdbs-for-profiling-reports.aspx
  35.         For an alternative implementation to this one, see
  36.         http://knagis.miga.lv/blog/post/2013/01/22/VS2012-Windows-8-profilesana-ar-NGEN-bibliotekam.aspx