Today’s post is about… A command line utility I wrote a few days back for analysing and finding out possible leaks by not disposing of objects properly.
Before we get into the nuts and bolts of the utility, please find attached two files which are:
It’s well-known that every single object that implements IDisposable must be disposed by:
- Calling the Dispose method explicitly
- Enclosing the object that implements IDisposable within an using statement
Said that, let’s have a look at the code snippet shown below
This is the generated MSIL from the code snippet
As you can see, three objects of type SqlConnection are created and two of them are disposed. When enclosing the object within an using statement what really happens is that a try… finally… block is produced. As you can see the Dispose method is a callvirt which is a “Call to a virtual method” and it’s virtual because it was implemented from the IDisposable interface. MSIL similar to assembler has some Op codes, actually there are 256 (0x100) Op codes being [Dec = 111 | Hex =0x6f] (callvirt) and this is the one we’ll use in our utility.
The way as our utility works is described as follows:
- An assembly is loaded for analysis as specified in argument (eg.: -a “C:myassembly.dll”)
- The Inspect method is called which performs the analysis on the modules & types referenced in the assembly
- The InspectMethod is called only processing the variables (objects) which implement IDisposable
- Then we call IdentifyDisposableObjects method that takes as an argument an array of bytes containing the MSIL of the method. We take into account only callvirt (0x6F) op code.
- We do this for every method in the assembly, and add this information to a dictionary that’s later dumped as a report.
If you have a copy of reflector, please feel free to check the results of the report with reflector’s disassembly… You’ll be amazed with the amount of objects that are being left behind and not being disposed.