VS 2010 Beta 2 Code Analysis In-Depth First Look
Code Analysis is one of those great tools that people don't run nearly enough. I have screamed repeatedly, "Never do anything at run time you can do at compile time." The best time to catch the Design Guidelines, security, and performance violations is at build time. Code Analysis and its standalone twin, FxCop, have been around long enough that I shouldn't have to convince anyone that every single build, no matter who does it, must have Code Analysis running.
If you start using Code Analysis from day one, it's easy, but sadly, many teams have not. Recently, I wrote an article talking about how to introduce Code Analysis and FxCop on Visual Studio 2008 projects without getting overwhelmed. For Visual Studio 2010, Microsoft has added a great feature to Code Analysis called Rule Sets, where you can create subsets of the rules you're most interested in running. The estimable Habib Heydarian wrote an article that shows you everything you need to know about creating and manipulating rule set files.
With Beta 2, I was hoping Microsoft was going to fix a large bug pertaining to Code Analysis. The bad news is that it wasn't. No new projects created in Visual Studio 2010 have Code Analysis enabled by default. That's frustrating because Code Analysis uses a default Rule Set "Minimum Recommended Rules" whose rule set description says it all, "These rules focus on the most critical problems in your code, including potential security holes, application crashes, and other important logic and design errors." Yes, I will be logging this as a bug because positive nudges like this are an extremely cheap and easy way to avoid bugs.
With Visual Studio Beta 2 being essentially feature complete, I was very curious to see the new rules that Microsoft has added to Code Analysis. Here's the list I compiled by comparing Code Analysis from Visual Studio 2008 to that in Visual Studio 2010. Note that some of these links to the rule documentation go to pages that do not yet exist on the MSDN web site as of this writing. I pulled the help URLs for the rules out of the assembly resources so they will eventually be valid.
- CA2100 – Review SQL queries for security vulnerabilities
- CA2130 – Security critical constants should be transparent
- CA2131 – Security critical types my not participate in type equivalence
- CA2132 – Default constructors must be at least as critical as base type default constructors
- CA2133 – Delegates must bind to methods with consistent transparency
- CA2134 – Methods must keep consistent transparency when overriding base methods
- CA2135 – Level 2 assemblies should not contain LinkDemands
- CA2136 – Security assemblies should not contain security critical code
- CA2137 – Transparent methods must contain only verifiable IL
- CA2138 – Transparent methods must not call methods with the SuppressUnmanagedCodeSecurity attribute
- CA2139 – Transparent methods may not use the HandleProcessCorruptingExceptions attribute
- CA2140 – Transparent code must not reference security critical items
- CA2141 – Transparent methods must not satisfy LinkDemands
- CA2142 – Transparent code should not be protected with LinkDemands
- CA2143 – Transparent methods should not use security demands
- CA2144 – Transparent code should not load assemblies from byte arrays
- CA2145 – Transparent methods should not be decorated with the SuppressUnmanagedCodeSecurity attribute
- CA2146 – Types must be at least as critical as their base types and interfaces
- CA2147 – Transparent code may not use security asserts
- CA2149 – Transparent methods must not call into native code
- CA 2202 – Do not dispose object multiple times
- CA2215 – Dispose methods should call base class dispose
- CA2241 – Provide correct arguments to formatting methods
Interestingly, I noticed the following rules are no longer alive in Visual Studio 2010. May they rest in peace.
- CA2127 – Security transparent assemblies should not contain security critical code
- CA2128 – Security transparent code should not assert
- CA2129 – Security transparent code should not reference non-public security critical members
Probably the most interesting thing about Code Analysis in Visual Studio 2010 is that Microsoft has reintroduced the dataflow analysis. Back in the early versions of FxCop there was a dataflow analysis engine but it was scrapped and a new engine has taken its place.
Many of the new rules, such as CA 1062 – Validate arguments of public methods utilize the new engine. If you're super curious, you can use Reflector to poke around the dataflow rules by opening the DataFlowRules.DLL assembly in <Visual Studio Directory>\Team Tools\Static Analysis\FxCop\Rules. Without documentation and a simple example, it's hard to see how it all works. However, poking around through the dataflow engine supporting assemblies, you will come across PHX.DLL.
At one point Microsoft was working on a compiler framework called Phoenix, which was going to be used to build a pluggable compiler system. The idea was that if someone had an idea for an analysis or optimization tool they could plug into the compiler chain or rewrite the Intermediate Representation (IR) and add their additional analysis or optimizations. While there's a vibrant research community built around Phoenix, I don't know where it stands on the product side. However, as I poked around PHX.DLL, it wasn't too much of a stretch to see that I was looking at a version of the Phoenix code. Namespaces like Phx.Pdb, Phx.PE, and Phx.LoopOptimizer aren't the typical namespaces used in a SilverLight line of business application.
For more traditional rules, such as CA1714 – Flags enums should have plural names, they still use the Introspection engine first introduced in FxCop 1.30. That means if you've already written rules for FxCop they will port right over to Visual Studio 2010's Code Analysis without much trouble.
Code Analysis is one of those tools that just sits there quietly doing its job and if you run it on every compile, you never see just how valuable it really is. Catching errors as early as possible in the development cycle is what saves you the big time and money. Nothing annoys me more that when I hear someone say that they don't run Code Analysis because they don't have the time, or because Code Analysis is to slow, or any other of a million lame excuses. Oh, let me take that back. Actually, I when I hear people say any reason they don't run Code Analysis on every build, I rub my hands with delightful glee because I know that Wintellect will be getting a huge contract soon from them to debug or take over developing their application.
OK, let me get serious: Microsoft runs Code Analysis on everything and so should you. That's what great companies do and the Code Analysis in Visual Studio 2010 with its rule sets makes it even easier to do. You no longer have any excuses.