[Mono-list] [ANN] Smokey - assembly bug checker

Jesse Jones jesjones at mindspring.com
Tue Mar 25 07:30:32 EDT 2008

Smokey is a command line tool used to analyze assemblies and report  
problems. Problems include buggy code (e.g. infinite recursion, null  
deref, malformed format string), performance issues (e.g. string  
concatenation in loops, excessive boxing, large structs), violations  
of the .NET design guidelines (e.g. inheriting from  
ApplicationException or ICloneable, naming, and swallowing  
exceptions), and miscellaneous rules like misspelled words in string  

You can download Smokey from the web site:
<https://home.comcast.net/~jesse98/public/Smokey>. The web site also  
has an html report for one of the System assemblies and a list of all  
of Smokey's rules.

Changes from Smokey
* Added 33 new rules:
    CircularReference, two classes refer to each other.
    EmptyOverride, non-empty virtual has an empty override.
    GodClass, type refers to more than 40 distinct types.
    HashOverflow, GetHashCode result is summed with add.ovf.
    IdenticalMethods, two non-trivial methods are identical.
    IgnoredReturn, method return value isn't used.
    RecursiveEquality, an operator== or operator!= method calls itself.
    SchizoidType, a type can be neatly split apart.
    TemplateMethod, a new virtual method has a ratio of more than 120  
instructions to virtual method calls.
    TooManyArgs, a method has more than six arguments.
    UncheckedAssembly, the assembly was compiled without checked  

    These are from from FindBugs:
    ArrayIndexOf, code checks for index > 0.
    Average, average value computation may overflow.
    BadExit, winforms app calls Environment.Exit.
    BadRegEx, regex is invalid.
    CollectionToString, ToString called on a collection.
    DontExit, System.Windows.Forms.Application.Exit is called
    ExplicitGC, explicit collection call.
    IdenticalCase, two or more switch case blocks are identical.
    IdenticalBranch, both if statement blocks are identical.
    IntegerDivision, the result of an integer division is cast to a  
float or double.
    IntegerMultiply, the result of an integer multiplication is cast  
to a long.
    NullField, a private field is never set to a non-null value.
    RandomUsedOnce, instance is created but only used once.
    StringIndexOf, code checks for index > 0.
    UnrelatedEquals, Equals is called with types which can never be  
    UnusedNew, result of a new expression is never used.
    UnusedStore, value is stored into a local but immediately over  

    These are from Gendarme:
    ExitCode, System.Environment.Exit is called with a value outside  
    GuiUsesConsole, winforms or gtk app uses System.Console.
    IdenticalCodeBlocks, two blocks within a type are identical.
    UseSetterValue, setter property doesn't use value argument.
    WinExe, winforms or gtk app wasn't compiled with -target:winexe.
* Removed MethodCanBeMadeStaticRule.
* Added install and uninstall scripts.
* All rules now have a breaking property which is true if fixing the  
violation is likely to break binary compatibility with client  
* There is no longer special code which disabled certain rules for  
system assemblies. Instead use the new -ignore-breaking command line  
* Added -only-type to allow only the specified types to be checked.
* ClassCanBeMadeStaticRule now checks for classes which inherit from  
System.Object, have no non-static fields, and declare no new virtual  
methods instead of checking for all static members.
* Made DeepInheritanceRule a nitpick.
* Added a new namespace called App which contains public classes  
which can be used by .NET tools to smoke assemblies.
* Made some changes to the report text:
    - Tweaked comments in the Dispose code examples to clarify the  
issues involved when using managed objects from a finalizer.
    - Code samples use IEquatable<T> where appropiate.
    - Updated mono naming rule to reflect that the naming rules wants  
constants to be PascalCase.
    - Made the OverridenFinalizer cause text less confusing.
    - Code examples use an unchecked statement and + for GetHashCode  
instead of ^.
* Finalizers are now treated as thread roots.
* Skip methods with more than 256 local variables (they can take a  
long time to process).
* Main no longer returns 1 if the only violations are nitpicks.
* Bug fixes:
    - Fixed an off-by-one error in SymbolTable which resulted in  
index exceptions.
    - SymbolTable now gets the correct names for local variables.
    - ValuesTracker::GetStackIndex no longer asserts if nth is too  
large (it can be if the code doesn't match what we expect).
    - CallGraph, AssemblyCache::FindMethod, and  
ClassifyMethod::ThreadRoots use MethodReferences instead of  
MetadataTokens so that methods defined outside the assembly we're  
checking are properly handled.
    - SortedMethodsRule special case property names under four chars  
(Cecil can return "?" for these).
    - InlineStaticInitRule ignores <PrivateImplementationDetails>.
    - AttributePropertiesRule now has a check for no method body.
    - CtorCallsVirtualRule ignores final methods.

   -- Jesse

More information about the Mono-list mailing list