Disclaimer: I usually like to keep this blog clean of link posts (posts that only have links to other posts in other blogs), but this time the information was too valuable so I had to make an exception.
Although this information is not exactly pure .NET debugging, it does have some information that can actually save you debugging time 🙂

Tess has some interesting tips that she expanded from a post her colleague Doug wrote about:

Read, learn and implement where needed.

Did you know that you can use SOS from within Visual Studio 2005, not just from WinDbg?
It has been previously discussed in a couple of places but most people don’t know it is possible to do that.

“Why should I use the SOS extension from within Visual Studio?”, you are probably asking.
The answer is quite simple.

Visual Studio is a rich debugger that shows us most of the information we want to know but it doesn’t show us a few important things like the actual size of an object and all of its references and who is referencing our object. While these things are not straight forward in Visual Studio, they are very easy to accomplish in SOS. For example, you can run the following command in SOS:

  • !objsize – to find out the actual size of the object and all of its referenced objects
  • !gcroot – to find who is referencing our object
  • !dumpheap – to see what’s all the stuff that we have on the heap. By using the -gen [generation number] parameter with !dumpheap, we can see all the objects that are currently in that generation
  • !SyncBlk – find out which managed locks are locked at the moment (I’ve talked about it before)

So, how do we actually do that?

Well, the first thing you need to do is enable “unmanaged debugging” by going to the “Project Properties” -> “Debugging” -> “Enable Unmanaged Debugging”.

After doing that, you can stop somewhere in your program, open the “Immediate” window (Debug -> Windows -> Immediate) and type:

.load sos

This will load the SOS extension. From there on you have most of the commands of the SOS extension at your disposal.
You might need to set the symbols path by calling .sympath, just like you would do in WinDbg.

An added bonus to this whole thing is that it also works on Visual Studio 2003, so you get to use it even with .NET Framework 1.1.

There is a new broadcast episode on MSDN TV titled “Introduction to the CLR Managed Debugger“.
It features Jan Stranik, the guy who wrote MDbg and he shows examples, as well as talk about the API and have a few insights as two the problems and solutions he encountered while writing MDbg.

I talked about MDbg briefly here and even used it to create an small tool to capture and log all exceptions being thrown in the process (even swallowed one) which I titled ExceptionDbg.
Its available in both binary and source code and is a nice tool to see all of the exceptions being thrown and caught. It’s also a good reference to implement your own cutomized debuggers and applications based on MDbg.

If you want some more information about MDbg go here, to Mike Stall’s blog.

Yun Jin has this piece about the different special threads in the CLR on his blog.
It coverts the different special threads in both the .NET Runtime as well as the open source Rotor shared source implementation.

It’s a bit of an old post, but I just found it. It has a nice summary of all the different special threads that the CLR creates in various stages and situation.

Some of the threads being mentioned there include:

  • The Finalizer thread. We discussed this a while back in the post about the blocked finalizer thread issues.
  • The Debugger helper thread
  • Concurrent GC thread – Used in a non server GC scenario and enables to collect garbage without freezing up the application.
  • Server GC threads – The specialized GC threads used in the server GC (one per logical, not physical, CPU)

Interesting stuff.

A friend of mine that worked with me on my previous work place talked to me the other day and asked me why we put all of our assemblies in the GAC. After all, it does make a bit of a mess during the installation and no one actually see the benefit of it since a lot of the .NET first hype was “X-Copy Installation” and the “End to DLL Hell”.

As it usually goes in these situations, the “End of DLL Hell” brought its own set of challenges to overcome, therefore, I’ve decide to dedicate this post to the GAC and explain what is it for and how and when to use it.

What is the GAC?
So, what is the GAC? It stands for Global Assembly Cache and has two major functions:

  1. Provides a place to put a few versions of the same assembly that will co-exist side by side.
  2. Provides a place where one can place the native image of an assembly so that it will save us the need to perform Just In Time compilation (JIT) on the fly the first time we call to a certain method in one of the objects in that assembly.

In the old days before .NET and COM people relied on the search path to strategically place DLLs so that the application will find them and load them. There was a certain order and logic to the search path and people usually tried to go with it. If you wanted to place a DLL that will be accessible to all without changing the PATH environment variable, you usually put it in the SYSTEM directory (and later in the SYSTEM32 directory).

This process usually caused the DLL Hell since the application relied on a correct PATH envrionment variable and if, for some reason, it was changed or the same DLL in a different version was in a place before your DLL, your application would load the wrong version and bad things would start the happen.
At best, you can’t see some bug fixes and a new functionality, at the worst case, your application just crashes and strange places (depending how the application is written).

After the old days, came what I’d like to call the “Middle ages” and the era of COM which relied a bit on the search path as in the old days, but now it was written in the registry where to actually look for the exact DLL. If it couldn’t find it, it would rollback to the old days and usea the PATH environment variable and the search logic to try and find the DLL.

In the .NET era the GAC first major function comes to our aid. No more multiple places to put DLLs. We now have a single place that can provide a place to all of the versions of our assemblies all together. We can specifically redirect application that are suppose to use a certain version of the assembly to a different one using policy files and if everything is indeed in the GAC we are no longer in the mercy of the dreaded search path (although, if we can’t find the assembly in the GAC, the loader will revert to the old search path ways, as explained in this post).

The second major function of the GAC is to host the native images of assemblies that were compiled using the NGEN tool. If you wish to read more about NGEN and when to use it I suggest this fine post from Jason Zander‘s blog.

How to use the GAC?
The first basic condition of putting an assembly into the GAC is to strongly sign it. How to sign an assembly is beyond the scope of this post (but I will write about it in a future post).

After the assembly is strongly signed, you simply drop it in the “Assembly” folder located under you Windows Home Directory\assembly (that’s where the GAC is actually stored).

That’s it.

When to use the GAC?
OK, so now that we know how to use the GAC and what it was meant for, when should you use it?

Well, the rule of thumb is this… If you have a shared component that is used in more than one application OR your application exposes some kind of an API that can be used by other, you should definitely put your assemblies in the GAC. After all, this is one of its major uses!

If you have a simple executable or a simple application that only uses the assemblies in its own directory there is no need in putting anything in the GAC.

Quite simple, isn’t it?

In the next post I’ll dig a bit more into the inner workings of the GAC so stay tuned!

Since .NET 2.0 is released for about a month, I think its time for me to cover a few new commands that exists in the SOS.dll WinDbg extension that comes with .NET 2.0.

First of all, the current version of WinDbg – 6.5.3.8 – has an SOS.dll that can only work with .NET 1.1, so even if you do load it and try it out it will not find any .NET data in the processes since the internal .NET structures in .NET 2.0 have changed.

To start using the SOS.dll that comes with .NET 2.0 issues the following commands:

.load C:\<Windows Home Directory>\Microsoft.NET\Framework\v2.0.50727\sos.dll

If you are performing a live debug (you have attached to the process), in newer WinDbg versions you can use the following commands

.loadby sos mscorwks

This command will load the sos.dll near the mscorwks.dll that is currently loaded in the process.

Usually newer versions of WinDbg (I always recommend running the latest version of WinDbg 😉 ) contains a newer version of SOS.dll, so you should prefer to use the SOS.dll provided with WinDbg, although currently, the only SOS.dll that supports .NET 2.0 is located in the Framework’s directory, near the mscorwks.dll.

New and interesting commands

  • !dumparray – Dumps the content of an array.
    The .NET 1.1 version of SOS.dll had a !dumpcollection method which usually didn’t work for me, so it nice to have something that will dump arrays.
  • !printexception – If a parameter is given, it will dump that exception, if no parameter is given, it will dump the last exception on the stack.
    In .NET 1.1 version of SOS.dll one had to dump the stack objects, find one that is an exception and print it using !dumpobj. Now, all one has to do is call !dumpexception and the last managed exception on the current thread’s stack will be printed out.In addition to that, !dumpexception can now parse the _stackTrace field, which is a binary array if the _stackTraceString is not filled.

    !printexception will also notify you if there are nested exceptions (exceptions being thrown inside a catch handler). If you want to see those as well, use the -nested parameter.

  • !bpmd – Sets a breakpoint on managed code.
    Setting a breakpoint on a managed code prior to .NET 2.0 was very tricky. I covered this issue in a previous post.
    In that older post I only covered settings a breakpoint on an already JITed method. Setting a breakpoint on a non-JITed method is even harder. !bpmd will cover all of these aspects.To set the breakpoint all you need to do is provide the module name and method name, or the MethodDesc handle (if you have it).
    !bpmd also works on generic types. If a breakpoint is set on a generic type it will break on all derived types.

    The only way to set a breakpoint on managed code with ease before .NET 2.0 was to use CorDbg (which I covered in an previous post as well).

  • !StopOnException – stops on a particular managed exception.
    This functionality was only supported in CorDbg prior to .NET 2.0. Now, instead of breaking on every CLR exception you can specify a specific .NET exception type, such as System.ApplicationException.
  • !DumpIL – Dumps the IL code of a method.
    This was previously very hard to do. In .NET 2.0 one can always dump the IL code of a method (even at runtime).
    The main advantage here is to debug dynamic methods which are built on the fly. Its also useful for dynamically generated types (using Reflection.Emit).

As in previous version of SOS.dll, you can type !help <CommandName> to get detailed help and sometimes examples on that specific commands.

Scott has a great post in his blog about how to share authentication between ASP.NET 1.1 and ASP.NET 2.0.

It’s useful for those of you who actually needs to be able to share the same authentication between an older ASP.NET 1.1 application and a new ASP.NET 2.0 application.

This article exposes some information I didn’t know (or didn’t want to know 😉 ).

First, ASP.NET 1.1 encrypted cookie uses the 3DES (a.k.a Triple DES) encryption. This key is per ASP.NET application (unless configured otherwise in the configuration).

According to the Scott’s post, ASP.NET 2.0 uses a stronger encryption (I assume AES since 3DES is AES predecessor).
Therefore, if you do use this feature mind that it will weaken your ecnrypted cookine in your ASP.NET 2.0 application.

Though I’ve briefly mentioned in a previous post that WinDbg has a built-in Semi-Scripting language to instrument it a bit, I didn’t explained much about it, so here is a nice little trick that you can do with it.

As part of this semi-scripting language there are a few flow controls that are very useful for performing a specific opeartions on multiple items such as object addresses.
One such useful flow control is “.foreach” which enables one to run a command that returns a result and for each line that returns invoke another command on that specific line.

Let’s say you want to view the full content of all of the string objects in your application that are in Generation 2.

The long way to perform this is to run dump all Generation 2 string objects using “!dumpheap“, save the list of addresses on the side and run “!dumpobj” on each and every one of the addresses we got.

The quick way to do it would be to use the “.foreach” command like this:
.foreach (obj { !dh -type System.String -gen 2 -short }) { !do ${obj} }

What we are doing here is running “!dh -type System.String -gen 2 -short” which returns all of the Generation 2 String objects currently alive on the heap (!dh is the short form of !dumpheap).

Mind the “-short” parameter. It is essential for this to work since “-short” tells the “!dumpheap” command to return the object’s address, one in each new line, instead of the normal output of “!dumpheap“.

NOTE: “-short” was only introduced in newer version of the SOS.dll that comes with WinDbg, so be sure to catch the latest version if you want to use it.

The second part of the “.foreach” command expands the obj parameter which contains each new line that we recieved from the “!dumpheap” command and we expand it by using the “${obj}” syntax.

This will run “!do” (the short form command of “!dumpobj“) on each and everyone of the addresses that returned from the “!dumpheap” command.

Just a small and useful tip for debugging… Enjoy!

Dan McKinley Emailed me to tell me about a WinDbg Extension he wrote that interogates CLR information. In the process of writing it he also documented the process of its creation, thus producing a tutorial of how to create WinDbg extension.

It’s all written in a nice and tidy post on his blog.

What is most interesting about his extension is that it interogates CLR information, so it should be a good basis for people writing WinDbg extensions that perform operations on CLR information.

If you are in the process of thinking about writing a WinDbg extension that’s a good place to start.

I’m often being asked to resolve various problems in which the .NET Assembly loader does not find the right assembly to load and therefore doesn’t load it at all.

While this is not hard core debugging that you would usually expect using WinDbg, CorDbg, MDbg and others, this is a very common case that with a little more information about how .NET works and one simple tool, can be easily resolved in both development and production environments.

Did you see the error “File or assembly name XXX, or one of its dependencies, was not found” error (replace XXX with the relevant assembly name) before?

That’s exactly the error I’m talking about.

Before we will go into common problems and how to resolve them, let us first understand how the .NET assembly loader actually works and how and where it searches for the assembly we want to load.

Strongly Signed Assembly
A strongly signed assembly is an assembly that was signed using a key pair during compilation (or after it).
The key pair is generated using the “sn.exe” utility and can be unique per assembly, per product or per publisher (depending on your needs).

Strong signing an assembly gives the assembly a unique identifer which is composed out of the following parameters:

  1. Assembly Name – the file name of the assembly minus the “.dll” suffix.
  2. Assembly Version – The version of the assembly as defined in the AssemblyInfo file. It can contain a fixed number which the developer / build machine will advance manually or have the “*” sign at the end so each build will increment it automatically.
  3. Culture – The deafult value for this parameter in most assembly is “neutral” meaning, that this assembly is not culture specific. It is mainly used to create assembly (or satellite assemblies) that are culture specific such as a specific assembly which has resource string that contains German text instead of English text. In which case, the culture will be “de”.
  4. Public Key Token – A token generate from the public key that you have in your key pair. It is used to verify the signature of the assembly to check that it was not tempered with after it was signed.

All of these parameters together create, what is referred to as, a “Fully Qualified Name” of a .NET assembly and looks like this:

MyAssembly, Version=1.0.2.3, Culture=neutral, PublicKeyToken=b77a5c561934d069

A fully qualified name for a specific type will look like this:

MyType, MyAssembly, Version=1.0.2.3, Culture=neutral, PublicKeyToken=b77a5c561934d069

If there is a program that needs to load some type and create it dynamically and the assembly of that type is strongly signed you can use the following piece of code to load and create that specific type given its fully qualified name:

string typeFullQualifiedName = “fully qualified name of type here”;
Type type = Type.GetType(typeFullQualifiedName);
if (type != null) {
object obj = Activator.CreateInstance(type);
}

This piece of code will try to load the relevant assembly (we will talk about the .NET assembly loader logic next) and if it succeeds, it will get the Type object which will allow us to create an instance of that type.

If you don’t have a full qualified name of the type, you can always use System.Reflection.Assembly.Load, give it the full path (or relative path) to the assembly and call assembly.GetType with the type you want to get and continue from there on.

.NET Assembly Loader – The real story

The first thing the .NET assembly loader checks is whether the assembly is strongly signed. If it is, it will start its search in the Global Assembly Cache (a.k.a the GAC. You can read more about it here).

The loader will search for a policy file named in the format of:
policy.AssemblyMajorVersion.AssembyMinorVersion.AssemblyName

For example:
Policy.1.2.MyAssembly

If such a file exists it will look inside of it if the version of the assembly that we are trying to load matches the version/versions range written in the policy file. If it does, it will try to load the assembly with the version specified there. If no such policy file exists, it will try to load the assembly from the GAC.

If it will fail to find it in the GAC, it will start to serach in the system’s search path.
In web applications it will also include the application’s Bin directory in the search path.

You can manully add folders to an AppDomain’s search path by using the “AppendPrivatePath” method.

So, what should I do if it can’t find the assembly?
The best method I’ve found to check if there is a policy problem or a path/version problem is to use FileMon from SysInternals.

FileMon tracks all activities that relates to accessing files in your operating system including read, write, access denieds on files and so on.

I would suggest adding a filter with the name (or partial name) of your application and start the application.

It will start showing you all file access that your appliction does. When you’ll receive the assembly load error, search for “NOT FOUND” or “ACCESS DENIED”.

If you have policies for that specified assembly you will see that the application accessed the policy file and directly after it will try to load the assembly with the version specified in the policy file.

If this is not a strongly signed assembly or the file is not in the GAC you will see all the places the application searched for to load the file.

Summary
This is a very easy trick that saves long hours of debugging, specifically in a production or semi-production environment.

If you are using the various abilities of .NET for side-by-side versioning, policy files and the GAC, do mind that you WILL run into these simple problems that consumes a lot of time and effort.

If this post helped you, comment on this post or just Email me. I would like to know that I’m not the only one fighting with the GAC and policy files 🙂