Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Gendarme for Unity : a code analysis tool

Discussion in 'Scripting' started by florian_d, Nov 20, 2011.

  1. florian_d

    florian_d

    Joined:
    Apr 13, 2010
    Posts:
    34
    I do not often see people talk about Gendarme around here, so i will assume people dont know what is Gendarme, and how it can help them.



    TL;DR VERSION : Now you can analyze your Unity assemblies with Unity specific rules, and see where you can improve your scripts.

    On Mac, you need to download Mono to execute it
    On Windows, you need .Net 3.5 at least

    Get Gendarme + Unity rules here : https://github.com/downloads/fderudder/unity-gendarme/Unity-Gendarme-2.10.zip

    Repository's here https://github.com/fderudder/unity-gendarme

    Dont forget to check "All code, visible or not, outside the assemblies". See last image at the end of this post.

    KNOWN BUGS : n/a




    Gendarme is part of the Mono Tools. For those unaware of that, Mono is what your scripts run on (hence MonoBehaviour). Gendarme is an assembly analyzer. It loads your .Net/Mono code, tests it against a set of rules, and generates a report, telling you with more or less accuracy where you could optimize, get rid of smelly code, refactor your copy/pasted files, etc etc. Gendarme is really usefull on every project, no matter what scale it is.

    Now that everybody is more familiar with Gendarme, i would like to introduce you to the Unity Rules for Gendarme. Since i'm not a big fan of ads, i'll describe it through a Q/A.

    Q : What is that thing ?
    A : As you're reading that, It's only a small set of basic performance tips and tricks, implemented as rules within Gendarme. It analyze your project's assembly and generates a report, pointing you where you could optimize stuff.

    Q : What's the point ?
    A : Automation, optimization, and stuff like that. You can easily use it in a build chain for example (since Gendarme already works with lots of continuous integration system, it will be pretty easy to add this in your jobs). And it can show you errors you may have forgotten, or you werent aware of while writing your code some weeks ago.

    Q : What rules are available ?
    A : I've implemented 4 basic performance oriented rules, just as a proof of concept. Those are :
    - AvoidEmptyComponentsMethods : checks if your scripts have empty Updates. It's tested against all MonoBehaviours basic methods
    - AvoidUsingFindObjectInUpdate : Checks if you are using Object.FindObjectOfType, FindObjectsOfType, or GameObject.Find("name") in your Update/LateUpdate/FixedUpdate.
    - CacheComponentLookup : checks if you call transforms, or stuffs like that in updates, and suggests to cache those in local member instead.
    - UseBuiltInArray : checks the use of Array and ArrayList and suggest to change them for type[] or generic collection instead.

    Q : That's a very little number of rules dude.
    A : I know. The project is just starting. Now i hope people will suggest new rules, new tips and tricks we could add to the set of rules dedicated to Unity.

    Q : This sounds cool, but i tested my game, and i'm pretty sure it has detected false positives.
    A : Oh. Well, it's totally and definitely possible. I didnt have a lot of time and codebase to test this, so it may generates false positives. I have to set up a structure to track down those kind of bug reports by the way.

    Q : How organized are you ?
    A : Badly. I just gave a shot to that idea, wrote the code, tested against some codebase of mine, and that's all. I dont know what i have to do now to get more organized. So feel free to point out where i should start. For example, i know i should setup a repository of some sort somewhere, probably on GitHub, to keep the code open source. And maybe a bugtracker. I dont know, i lack experience in open source projects, and especially public projects. So i'm kinda lost here.

    Q : Well i found that a great tool, though there's a little set of rules. How can i help ?
    A : Report when you think you find false positives. I really want to have the rules as accurate as possibles. If you want to suggests new rules too. I'm open minded, so feel free to rant, to suggest, to report, to send me 24 inches screens.

    Q : Well, i found that's a S***ty tool, and you just ripped off Gendarme and added some rules.
    A : True. That's just the beginning though. I hope you'll find an interest in analyzing your codebase, and maybe it'll help you. And maybe there will be more and more rules coming soon (i hope).

    Q : How do i get it ?
    A : Here : https://github.com/downloads/fderudder/unity-gendarme/Unity-Gendarme-2.10.zipBe warned that it's a .Net/Mono software, so you need at least the Mono runtime on *nix/MacOs, or .Net on Windows. Otherwise, it may have some problem to work properly ;) .

    Q : Where do i report stuff ?
    A : i'd prefer that you report in that thread, or you can do it at: unity.gendarme@gmail.com

    Q : Where do i send the 24" screen mentionned earlier ?
    A : Dont do that, that was a joke. (But if you insist, i could use a third screen).

    Q : I DONT SEE ANYTHING ! YOU LIED !
    A : Nope, it's just that you have to run Gendarme with the "All code, visible or not, outside the assemblies" option.

    Q : How do i use it by the way ?
    A :

    This way :









     
    Last edited: Aug 8, 2012
    Arkade likes this.
  2. florian_d

    florian_d

    Joined:
    Apr 13, 2010
    Posts:
    34
    Just as a reminder, and maybe it was not very obvious in the post, for those who didnt knew Gendarme before this post :

    - Gendarme is a part of Mono Tool's project : i didnt do it.
    - I've only implemented rules to analyze Unity's assembly with Gendarme (which allows you to analyze with both Gendarme's Rules and Unity-specific rules)
    - I dont work for Mono, nor Gendarme.
     
  3. humeware

    humeware

    Joined:
    Apr 29, 2011
    Posts:
    4
    Tool looks great and I think this is a good start to a useful rule set. Hadn't heard of Gendarme before. I encountered a few issues running it:

    First off I'm on osx and didn't know you could run .exe's with mono. To do that open terminal, navigate to the directory you unzipped Gendarme in, and type "mono GendarmeWizard.exe". That should launch it. Took a minute or two to load on my i7 macbook, but it did load. Couple wonky ui errors but not a big deal.

    I got a jillion "AvoidUncalledPrivateCodeRule" high severity rules which were false. It's saying Start() and Awake() aren't called on pretty much every file. Dunno why it doesn't see that through the monobehavior calling it, and I'm not sure if this is fixable, but lots of false positives.
     
  4. florian_d

    florian_d

    Joined:
    Apr 13, 2010
    Posts:
    34
    There are some points on my todo list now (thanks to NCarter and zite who made some feedbacks on IRC).

    First, i'm a windows guy, so i truly dont know how it works on OSX. I have to team up with someone who knows, to write a tutorial for that, or to include easy launchers in further releases.

    On the rules, the visual client allows to choose which rules you want to apply on your assembly. I've shown that in the pictures at the end of the first post. Generic Gendarme rules may not apply well to Unity specific's way of handling code. It's the second point on my todo list : write a default "unity" profile to launch gendarme with. In the meantime, you could modify by hand the rules.xml in the folder, add and remove some pack of rules, and launch the gendarme.exe again against your assemblies. I'll work asap on some basic profiles Unity-oriented

    Thanks for the feedback
     
  5. florian_d

    florian_d

    Joined:
    Apr 13, 2010
    Posts:
    34
    Here you go. A basic rules.xml which can be used instead of the default one. You may be interested by the 2 following profiles : full and default

    Full includes Unity.Rules.Performance, and for Gendarme.Rules : BadPractice, Performance, Security and Maintainability. (yes, it's a fake "full", but since i have Unity in mind, i dont see any interest on adding more rules).

    Default only has Unity.Rules.Performance and Gendarme.Rules.Performance.
     

    Attached Files:

  6. florian_d

    florian_d

    Joined:
    Apr 13, 2010
    Posts:
    34
    dropbox link updated, with the latest rules.xml (the one in the post above)
     
  7. florian_d

    florian_d

    Joined:
    Apr 13, 2010
    Posts:
    34
    No update since last one, kinda busy right now. I'll come back asap, when i'll fix/rework the CacheComponentLookup infinite loop bug.

    I'm still hoping that you'll see how this tool can help your codebase and see more people test it and give feedback on what rule could be implemented next, if you have some in your mind.
     
  8. U7Games

    U7Games

    Joined:
    May 21, 2011
    Posts:
    943
    Interesting, interesting... downloading right now.. thanks :D
     
  9. JRavey

    JRavey

    Joined:
    May 12, 2009
    Posts:
    2,377
    This looks a bit like Cast, except it doesn't cost hundreds of thousands of dollars to implement and probably works better. I'd plan to check it out (this afternoon).
     
  10. Ipsquiggle

    Ipsquiggle

    Joined:
    Nov 15, 2009
    Posts:
    8
    I've been trying to get Gendarme working with Unity for a long time now, was hoping that this would be the ticket (aha! So THAT's the assembly I have to scan!) So THANK YOU!

    However, the rules you've provided are crashing: (Downloaded the full zip, Dec 30th). Let me know if you need more details.

    Code (csharp):
    1. Rule:   Unity.Rules.Performance.CacheComponentLookupRule
    2.  
    3. Target: System.Void AnimatedSpriteSheet::LateUpdate()
    4.  
    5. Stack trace: System.NullReferenceException: Object reference not set to an instance of an object.
    6.    at Unity.Rules.Performance.CacheComponentLookupRule.ComputeNumberOfComponentLookup(MethodDefinition method, Int32 level) in E:\dev\git\gendarme\rules\Unity.Rules.Performance\CacheComponentLookupRule.cs:line 74
    7.    at Unity.Rules.Performance.CacheComponentLookupRule.ComputeNumberOfComponentLookup(MethodDefinition method, Int32 level) in E:\dev\git\gendarme\rules\Unity.Rules.Performance\CacheComponentLookupRule.cs:line 62
    8.    at Unity.Rules.Performance.CacheComponentLookupRule.ComputeNumberOfComponentLookup(MethodDefinition method, Int32 level) in E:\dev\git\gendarme\rules\Unity.Rules.Performance\CacheComponentLookupRule.cs:line 62
    9.    at Unity.Rules.Performance.CacheComponentLookupRule.ComputeNumberOfComponentLookup(MethodDefinition method, Int32 level) in E:\dev\git\gendarme\rules\Unity.Rules.Performance\CacheComponentLookupRule.cs:line 62
    10.    at Unity.Rules.Performance.CacheComponentLookupRule.CheckMethod(MethodDefinition method) in E:\dev\git\gendarme\rules\Unity.Rules.Performance\CacheComponentLookupRule.cs:line 32
    11.    at Gendarme.Framework.Runner.OnMethod(RunnerEventArgs e) in E:\dev\git\gendarme\framework\Gendarme.Framework\Runner.cs:line 342
    12.    at Gendarme.Framework.Runner.Run() in E:\dev\git\gendarme\framework\Gendarme.Framework\Runner.cs:line 386
    13.    at Gendarme.GuiRunner.Execute() in E:\dev\git\gendarme\swf-wizard-runner\GuiRunner.cs:line 110
     
  11. AbgaryanFX

    AbgaryanFX

    Joined:
    Jan 9, 2010
    Posts:
    167
    Code (csharp):
    1.  
    2. Rule:   Unity.Rules.Performance.UseBuiltInArraysRule
    3.  
    4. Target: ContentControl
    5.  
    6. Stack trace: System.NullReferenceException: Object reference not set to an instance of an object.
    7.    at Unity.Rules.Performance.Utilities.IsMonoBehaviour(TypeDefinition type) in E:\dev\git\gendarme\rules\Unity.Rules.Performance\Utilities.cs:line 12
    8.    at Unity.Rules.Performance.UseBuiltInArraysRule.CheckType(TypeDefinition type) in E:\dev\git\gendarme\rules\Unity.Rules.Performance\UseBuiltInArraysRule.cs:line 15
    9.    at Gendarme.Framework.Runner.OnType(RunnerEventArgs e) in E:\dev\git\gendarme\framework\Gendarme.Framework\Runner.cs:line 318
    10.    at Gendarme.GuiRunner.OnType(RunnerEventArgs e) in E:\dev\git\gendarme\swf-wizard-runner\GuiRunner.cs:line 131
    11.    at Gendarme.Framework.Runner.Run() in E:\dev\git\gendarme\framework\Gendarme.Framework\Runner.cs:line 381
    12.    at Gendarme.GuiRunner.Execute() in E:\dev\git\gendarme\swf-wizard-runner\GuiRunner.cs:line 110
    13.  
     
  12. florian_d

    florian_d

    Joined:
    Apr 13, 2010
    Posts:
    34
    Wow, thanks a lot for the feedback and reports. I havent worked a lot on it since the post (everyday work, plus christmas break and stuff). I plan to address those issues asap and set up a proper repository for that project when i've cleaned the VS project.

    Thanks again for the reports, it's really motivating to see that people are actually interested in using that to analyze their assemblies.
     
  13. Demigiant

    Demigiant

    Joined:
    Jan 27, 2011
    Posts:
    3,239
    Wow, this is absolutely awesome, thanks for sharing FDerudder :)

    I'll definitely get it soon and play with it.
     
  14. florian_d

    florian_d

    Joined:
    Apr 13, 2010
    Posts:
    34
    Just a quick update-post to talk about the lack of updates to the tool. I'm currently dealing with work, RL issues and lack of energy when i come back at home right now, so there wont be any work done until...

    I quit my job at the end of February, and while i'm unemployed, i'll work on all the stuff i've said earlier :
    > setting up a proper repository to keep the tool open source and stuff
    > probably setting up a website to centralize as much as possible infos and tuts about it
    > bugfixing and new rules

    I still need to work on a weekly schedule and stick to it to be really efficient, but i just wanted to let you know that. I plan to stay unemployed for roughly 2 months, which should be enough to get things right for this little tool. (And remember you still can use the regular Gendarme, since it's a great tool to pinpoint some programming flaws and errors).
     
  15. hima

    hima

    Joined:
    Oct 1, 2010
    Posts:
    183
    Thanks for making this nice tool work with Unity! I've never heard of this tool before, mainly because I'm still new to Mono. But this sounds like a very interesting and useful tool , indeed.

    I wish you luck in finding a new job. (I just quit my job last year and went full time indie though) If anything, you can always set up a donation button or something for people to show their appreciation during those two months. :)

    Anyway, I'll download it and see how it works for me. Thanks again!
     
  16. florian_d

    florian_d

    Joined:
    Apr 13, 2010
    Posts:
    34
    No donation wanted or needed. Thanks to our interesting unemployement insurance in France, i can expect to be fully covered during this time. I'm not worried about finding a job : coding position are kind of easy to find, and i have some contacts here and there. ;)

    And dont forget that the Vanilla Gendarme is still fully functionnal (and i didnt do it, i'm not that good :D ). I just coded some (broken and bugged apparently) Unity-focused rules.

    (i should add that as a forum signature ^_^)
     
  17. florian_d

    florian_d

    Joined:
    Apr 13, 2010
    Posts:
    34
    Quick update

    The CacheComponentLookup crash has been fixed (it's more a safe workaround than a real fix) and shouldnt cause any problem from now.
    The UseBuiltinArray crash (reported by b4vibe and Superpig on IRC) has been identified and i'm working on it. Right now, it shouldnt crash anymore, but keep in mind that it's not fixed but there's a workaround to prevent the crash (related to multiple assembly and inheritance).

    A more stable version that the precedent one is available here : http://dl.dropbox.com/u/16741711/GendarmeUnity_preview.zip
     
  18. keki

    keki

    Joined:
    Apr 6, 2012
    Posts:
    1
    Hi,

    I'm trying to use this by executing the following command on my mac (Snow Leopard):

    mono gendarme.exe --html output.html *.dll

    Which works, however none of the Unity rules show up as defects, even though I've intentionally put them in (such as empty Update())

    Can it work from the command line???

    If I try to run it using the wizard, I get the following stack trace:

    >mono gendarme-wizard.exe
    2012-04-06 13:06:57.945 mono[5550:903] WARNING: CFSTR("Copyright \37777777702\37777777651 2005-2010 Novell, Inc. and contributors") has non-7 bit chars, interpreting using MacOS Roman encoding for now, but this will change. Please eliminate usages of non-7 bit chars (including escaped characters above \177 octal) in CFSTR().
    Missing method .ctor in assembly /tools/gendarme-2.10-bin/Unity.Rules.Performance.dll, type System.Runtime.Versioning.TargetFrameworkAttribute
    Can't find custom attr constructor image: /tools/gendarme-2.10-bin/Unity.Rules.Performance.dll mtoken: 0x0a000001

    Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.TypeLoadException: Could not load type 'System.Runtime.Versioning.TargetFrameworkAttribute' from assembly 'Unity.Rules.Performance'.
    at (wrapper managed-to-native) System.Reflection.MonoCMethod:InternalInvoke (System.Reflection.MonoCMethod,object,object[],System.Exception)
    at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    --- End of inner exception stack trace ---
    at System.Reflection.MonoCMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    at System.Reflection.MonoCMethod.Invoke (BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
    at System.Reflection.ConstructorInfo.Invoke (System.Object[] parameters) [0x00000] in <filename unknown>:0
    at System.Activator.CreateInstance (System.Type type, Boolean nonPublic) [0x00000] in <filename unknown>:0
    at System.Activator.CreateInstance (System.Type type) [0x00000] in <filename unknown>:0
    at Gendarme.GuiRunner.LoadRulesFromAssembly (System.String assemblyName) [0x00000] in <filename unknown>:0
    at Gendarme.GuiRunner.LoadRules () [0x00000] in <filename unknown>:0
     
  19. florian_d

    florian_d

    Joined:
    Apr 13, 2010
    Posts:
    34
    Last edited: Apr 8, 2012
  20. florian_d

    florian_d

    Joined:
    Apr 13, 2010
    Posts:
    34
    @Keki > any news with the latest version ?
     
  21. SarperS

    SarperS

    Joined:
    Mar 10, 2009
    Posts:
    824
    FDerudder, this is the only static code analysis tool for Unity as far as I know and in my opinion it's extremely important for defining a coding standart for multiple programmers in an office environment. So thanks for your effort!
     
  22. florian_d

    florian_d

    Joined:
    Apr 13, 2010
    Posts:
    34
    Gendarme was available prior to this. The fact is "it's for unity" only comes from the rules i've added according to their docs and by some people suggestions.

    For C#/Net you can find other tools similar, like FX Cop or Style Cop (the former is a Gendarme Like, the later more a "style enforcer"). If you have the opportunity to buy and use VS Pro and Resharper, you can enforce a certain code styling too, and share the Resharper settings among your team.

    All in all, i'm glad it's useful for people.
     
    Last edited: May 21, 2012
  23. increpare

    increpare

    Joined:
    Nov 17, 2010
    Posts:
    151
    Fantastic. I'm on OSX, and after downloading the latest version of mono, everything worked great.
     
  24. mwebi

    mwebi

    Joined:
    Apr 18, 2011
    Posts:
    7

    I got the console runner to work in terminal on OSX with:
    First:
    open terminal and change directory to the directory where you have your Unity-Gendarme
    Second:
    mono gendarme.exe --html log_NAME.html --set unity-full /SOMEPATH/UNITYPROJECT/Library/ScriptAssemblies/Assembly-CSharp.dll

    You can add additional assemblies after the first one (e.g. Assembly-CSharp-Editor.dll).
     
  25. mwebi

    mwebi

    Joined:
    Apr 18, 2011
    Posts:
    7
    I'm having troubles compiling the gendarme or unity-gendarme on OSX though. Can anyone explain how that is done?
     
  26. mwebi

    mwebi

    Joined:
    Apr 18, 2011
    Posts:
    7
    In the end I ended up compiling it on a VM with windows 7 and VS 2010 on it.
    If anyone is successful with compiling it on OSX please explain your procedure.
     
  27. florian_d

    florian_d

    Joined:
    Apr 13, 2010
    Posts:
    34
    AFAIK, Gendarme can be compiled within mono-tools package https://github.com/mono/mono-tools/ . If i remember well, there's a makefile or something very similar. In other words, it relies on something else than the IDE to be compiled.

    For Unity-Gendarme, i used VS to compile it. I guess it could be compiled with an external compiler (monodevelop ?)
     
  28. Juego

    Juego

    Joined:
    Feb 21, 2014
    Posts:
    2
    Hello All,
    Is there any static analyzer tool for unity to check the game performance and load.
     
  29. LastSipahi

    LastSipahi

    Joined:
    Sep 14, 2011
    Posts:
    21
    I'd like to perform some necromancy to bring this topic from dead. Is there anybody able to use this tool without errors? When I tried to implement rule DLLs program gives error and shuts down. Wtihout them runs OK.
     
  30. Contract-killer

    Contract-killer

    Joined:
    Sep 21, 2012
    Posts:
    42
    Hi there,
    I am new to these stuff can anyone let me know how to use them and get expertise on it???
     
  31. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,186
    The original post is from 2011. Looking at the repo, it's 5 years old. Chances are it wasn't maintained so it probably doesn't work with newer Unity versions and I doubt it is going to be updated if the original programmer is still around. Pretty pointless to necro this post.
     
  32. florian_d

    florian_d

    Joined:
    Apr 13, 2010
    Posts:
    34
    True; last time I checked, nothing worked anymore (for various reasons). I couldn't maintain it in the past 4 years for professional reasons.
    I tried to do a simple update but that was not as trivial as I originally thought. Maybe I'll revisit one day, but at this point it's pretty useless.

    If I were you, I'd keep an eye out for https://github.com/vad710/UnityEngineAnalyzer and the upcoming Roslyn compilers, which will pretty much cover the same things.

    However, in the meantime, the rules are fairly simple and straightforward to be included in your own coding guidelines.
    - Avoid Find Objects in Update
    - Avoid Empty Methods
    - Cache component lookups (especially with Camera.main)
     
  33. florian_d

    florian_d

    Joined:
    Apr 13, 2010
    Posts:
    34
    Well, what do you know.

    I was bored so I went to my repo, removed a bit of the dust, and updated some stuff.

    [ Fixes (yay!) ]
    - updated the gendarme-win.sln to VS2019.
    - uses Mono.Cecil nuget package (no need to get cecil from the mono tools on the side)
    - uses NUnit 3.x nuget package
    - fixed all tests for the Unity.Rules.* projects
    - built the project and the wizard. Works On My Machine
    - updated the code from Gendarme to comply with the breaking changes introduced in Cecil
    [WARNING] in that regard, I've tried to quickly understand what the old code was doing and how to change it to make it work with the new one. It seems to be ok, but I'm not 100% sure.

    [ Todo ]

    - make all vanilla Gendarme test pass (there are ~60+ tests that are currently failing for various reasons that I have not investigated)
    - Check the validity of the rules. A lot have changed since they were first written, there's probably room for change
    - Maybe get rid of all the things from the original Gendarme that I did not bother to support (make, etc)
    - Maybe enter the 21st century and attempt porting the whole thing to Core/Standard (ie: change the targets and see what breaks).
    - Find a way to build without a reference to an installed UnityEngine dll (distribute as previously? sounds bad. Regenerate the projects via makefile-like thing?) [WARNING] Currently, the projects that cover Unity (test and rules) reference the 2019.1.10f1 installed UnityEngine dll. If you're running against another version you'll need to re-reference the DLL).


    I don't know if there are still people using (or wanting to use) that project, despite the many better alternatives (Resharper/Rider Unity plugin's Analysis, Roslyn analyzers, etc), but if that's the case, that update is for you.

    If there's any issue, feel free to ping on github (I might have the alerts configured, idk) or complain here.

    Xoxo,
    Florian.
     
    Last edited: Jul 24, 2019