How to visit mscorlib?
-
29 Temmuz 2011 Cuma 02:43
One of the aspects of a rule I'm trying to write requires checking to see if the analyzed code makes method calls into BCL methods that match certain characteristics. Genreally, I'm attempting to get the statements in methods called by the analyzed code.
I'm running into a snag when the method calls into the BCL though. No matter what physical location I point to mscorlib at inside my rule, I end up getting a useless module. It's useless because the path of the module that loads is the design time reference assembly in C:\program files\reference assemblies. The problem with the design time reference assembly is that all of the method bodies are empty, so I can't analyze them.
When I try calling ModuleNode.GetModule(...), if I pass any path to mscorlib, such as in the GAC or a local copy I've made somewhere, FxCop still loads the design time reference assembly. At first I thought it had to do with caching since the GetModule method has a lot of overloads related to caching, but experimenting with these overloads has yielded nothing.
AssemblyNode does the same thing. It loads the design time reference assembly instead of the exact assembly I name.
The only way that I can get this to work is when I copy mscorlib.dll into the working directory of the FxCop process. In that condition, the mscorlib picked by FxCop is the copy, which contains method bodies and then I can look at their statements. Obviously, this is not the solution I want. I should be able to load the runtime mscorlib (in the GAC) in my FxCop rule, but I can't seem to get it.
Any ideas?
Evan
Tüm Yanıtlar
-
01 Ağustos 2011 Pazartesi 06:27Moderatör
I cannot find mscorlib.dll under "C:\program files\reference assemblies" folder; however, I checked other assemblies there, for example, System.Core.dll, its methods has method body.
By the way, what FxCop version you're using?
Eric Yang [MSFT]
MSDN Community Support | Feedback to us
Get or Request Code Sample from Microsoft
Please remember to mark the replies as answers if they help and unmark them if they provide no help.

-
01 Ağustos 2011 Pazartesi 20:27
Eric-
I'm using the latest version (I presume) - the one that is installed with VS2010. 1.36?
The specific assembly that is referenced when I visit a MethodCall node for a method in a BCL class is C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll.
When I get the method in FxCop and access its Body property and then the Statements property, it claims the method has no statements. When I open the assembly in question in ILDASM and look at the method in question, this is what I see:
.method public hidebysig newslot virtual final instance void Add(!T item) cil managed { // Code size 0 (0x0) } // end of method List`1::Add
This is for System.Collections.Generic.List<T>.Add.Evan
-
02 Ağustos 2011 Salı 08:38Moderatör
Thank you for your clarification, I find the mscorlib.dll under the Reference Assemblies folder, and ILDasm show me that System.Collections.Generic.List<T>.Add() method has an empty method body.
I'm investigating on why Fxcop always load "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll", will let you know as soon as there is any update.
Eric Yang [MSFT]
MSDN Community Support | Feedback to us
Get or Request Code Sample from Microsoft
Please remember to mark the replies as answers if they help and unmark them if they provide no help.

-
15 Ağustos 2011 Pazartesi 06:27
Hi,
Could you please provide more informaiton about how you pass the path to mscorlib FxCop ? Have you specify the path like what in http://msdn.microsoft.com/en-us/library/bb429449(v=vs.80).aspx?
Thanks
-
15 Ağustos 2011 Pazartesi 22:22
The issue isn't with FxCopCmd.exe itself but rather the FxCop SDK.
The core of the SDK is the BinaryReadOnlyVisitor class which visits elements of a type so that these elements can be analyzed.
Specifically, my custom rule is visiting LINQ delegates, e.g.:
public void F() { List<string> strings = new List<string>(); var matches = strings.Where(match=> { strings.Add("hello")); return true; }}
Now, the problem that I am detecting is the fact that Where is being hideously misused here. Namely, a Where method is adding something to a list. That's a really bad thing to be doing. In general, this is called causing a side-effect in a LINQ query.
My first thought was to simply check for a few specific methods (e.g., List.Add) being used inside a LINQ delegate, but then I thought that the rule would be stronger if I could automatically determine if any method called inside a LINQ delegate caused a state-changing side effect.
In order to do that, I decided the best thing to do would be to visit all of the method calls inside the delegate. From the method call, I get the method. I then use a different visitor to analyze that method's body to look for cases where the method body changes the value of a field (or calls another method which does).
It works perfectly for custom types. The problem is when I try to analyze the example above, the psuedo-code is basically:
Visit the LINQ delegate (match=> { strings.Add("hello"); return true; })
Visit the List<string>.Add method call
Examine List<string>.Add's body
And this is where the problem is. The List<T>.Add method's body has zero statements because it is being loaded from the Referenced Assemblies directory. I tried a bunch of different tricks to get FxCop to load a system type from a specifically named assembly but it still always reverts to the Referenced Assemblies version.
I don't have the code in front of me, but basically I used the AssemblyNode (possibly the ModuleNode) class to load an assembly by its explicit location, e.g., C:\windows\microsoft.net\.... And the load is successful, but still, all of the TypeNodes contain MethodNodes who have Body properties with Statements properties with a count of 0, and when inspecting the AssemblyNode that is loaded when calling AssemblyNode.Load(...) (or something like that, I forget the exact method name), I see that the path is not the path I provided. The path always reverts to the Referenced Assemblies location.
The only way I can get this to work is when I copy mscorlib into the working directory. Then it works as I expect and I can analyze the core code. I can work around this issue by running this rule in its own appdomain with a working directory set to the .NET directory but this is a less than ideal solution.
In actuality, I gave up on this rule since it was just too difficult to write correctly so this specific issue isn't a holdup, but I still want to know why I can't visit mscorlib.
Evan
-
26 Eylül 2011 Pazartesi 07:07
Not saw the same issue during the research, and here are some realted references we got during the reserach, hope they could do some help:
http://msdn.microsoft.com/en-us/library/bb429472(v=VS.80).aspx
http://social.msdn.microsoft.com/Forums/en-MY/vstscode/thread/c438c3a8-de0a-42f3-b3a3-04db8088b0de
http://www.codeproject.com/KB/dotnet/FxCop.aspx
http://social.msdn.microsoft.Also you could get a more in-depth level of support from http://support.microsoft.com/default.aspx?id=fh;en-us;offerprophone to
better meet your needs if necessary.
Thanks