Internal compiler variables appearing in the debugger Locals pane with Rhino ETL - c#

If you disassemble C# you often see temporary variables inserted by the compiler with names such as:
CS$1$0000
But what would cause them to appear in the debugger Locals/Auto panes?
A colleague of mine is trying to maintain a tool written using Rhino ETL. The symbols for his assembly are reported as loaded correctly by the debugger. He can step through the code. But instead of showing his variables in the debugger, it only shows the internal compiler-generated ones.
I suggested he try writing a new console app with the same code in and substituting dummy classes called AbstractOperation and Row to satisfy the compiler (those are classes from the Rhino ETL library). When he tried that, removing all dependencies on Rhino ETL, everything was back to normal in terms of seeing his own variables in the debugger.
He also tried building Rhino ETL from source in the same solution, but that did not fix the problem. So apparently it's not due to a version incompatibility.
His code is inside an iterator method, hence the need for significant reorganising of the code by the compiler. But an iterator method doesn't usually break the debugger!
In this case, it seems that it will break the debugger if it is an override iterator method and the base class is AbstractOperation from the Rhino ETL library.
How can a base class have such an effect on the debugger?

Apparently PostSharp was also involved, which rewrites the IL, and when the dependency on PostSharp was removed, the problem went away. Mystery solved.

Related

Code Contracts vs Code Analyzers

I'm about to embark on a new C# project. I was wondering what the difference is between using Code Contracts or Code Analyzers (in Roslyn). Am I misunderstanding the usage of each? Being a new project, I would like to maintain the integrity of the code. So I want other developers to adhere to specific code guidelines. I'll research each further, but I was wanting to get the opinion of the community first. Excuse the question, I'm still rather new to C# development.
They are two different tools.
Code Contracts is a way to declare and check... well, contracts, such as pre-conditions and post-conditions:
public class Foo
{
public Foo(object arg)
{
Contract.Requires<ArgumentNullException>(arg != null);
}
public object GetBar()
{
Contract.Ensures(Contract.Result<object>() != null);
// TODO:
}
}
CC check their conditions at run-time. This requires your assembly (not source code!) to be rewritten after compilation to inject appropriate calls into your code.
Code Analyzers use Roslyn to analyze source code while you're writing it.
They can help you to format code, to remind you to call Dispose on IDisposable, and so on, but they don't affect run-time behavior directly.
There are a number of analyzers, grouped by purpose into projects (like StyleCopAnalyzers), while Code Contracts is a standalone project.
(CC also have static analyzer, but I can't tell much here - it kills performance when used on real projects, so, for me it is usually turned off. Anyway, it is intended to check contracts.)
Code analyzers will analyze your code for common mistakes. They look at the structure of the code and the flow of data across to detect problems.
Another type of analyzers looks at the style (StyleCop for example), capitals, camel casing, prefixes, postfixes and what have you.
The third type are the code contracts you've mentioned, and this works slightly different. You declare the expected behavior of your code, for example what is expected of parameters passed into a method, which exceptions your code can throw etc. The contracts analyzer will then check whether calling code is passing in the right parameters (e.g. the analyzer will detect you passing in null and will raise an error if that's not allowed). At the same time it will check the "internal consistency" of your methods to ensure that you don't throw exceptions you're not allowed to throw. Depending on the implementation contracts can be validated at runtime or at compile time.

Methodnames in Output-Assembly

I am compiling a project with Visual Studio 2013 against .NET 4.5 and then checking it again with ILDASM.
What I noticed is that the build in Release still contains method names and variable names, I thought these should be removed in a release-build or do I need an obsfuscator to do that?
You need an obsfuscator to hide method and member names, local variable names should be stripped by the compiler, but anything that can turn up using reflection is preserved that includes class and interface names, public and private methods, public and private fields.
As for method names, the compiler doesn't know if your assembly will be used or not in another project, so the preservation of method names is logical. Though variable names can't be used anywhere than in the method where they're defined, I guess it is useful for debugging (be it Debug or Release) and they really take insignificant space.
And my advice, don't use obfuscator, unless your application contains security critical codes (and then, I'd still advise obfuscating just this code, not the other methods). It is way better for debugging and reading exceptions.

Visual Studio: How to get IDebugEngine2 from VS Package (except IVsLoader)

Is it possible to get a list or a specific instance of IDebugEngine2 (MSDN) from a Visual Studio Package without using IVsLoader approach (described here)?
Normally I would expect most services to be available through GetService, either directly or through some other service. But I can not easily find anything that can provide debug engines.
What are you trying to do with it? The debugger interfaces are extremely fragile. Often there are 2, 3, or maybe more possible ways to perform an action with the debugger interfaces, but the particular DE implementation only supports 1 of them. Debug engine implementers are not expecting any direct calls to their debug engine interfaces from anywhere except Visual Studio itself, and the risk of breaking debugger functionality if you attempt it lies somewhere between very high and guaranteed.
For example, here are some of the potential ways to tell a DE to launch and/or attach to a process:
IDebugEngineLaunch2.LaunchSuspended
IDebugPortEx2.LaunchSuspended
IDebugProgramEx2.Attach
IDebugProgramNode2.Attach_V7
IDebugProgramNodeAttach2.OnAttach
IDebugEngine2.Attach
IVsDebuggableProjectCfg.DebugLaunch
VsShellUtilities.LaunchDebugger
IVsDebugger2.LaunchDebugTargets
IVsDebugger2.LaunchDebugTargets2
Edit 1: In the case of my Java debugger, the debug engine is created by the session manager with the following stack:
My code calls IVsDebugger2.LaunchDebugTargets2
The environment calls back to my implementation of IDebugProgramProvider2.WatchForProviderEvents
After creating a new instance of IDebugProgram2 (a copy of IDebugProcess2 obtained from the IDebugDefaultPort2 that VS passed to WatchForProviderEvents is passed to the IDebugProgram2 constructor), my code calls IDebugPortNotify2.AddProgramNode
The environment calls back to the constructor of my debug engine
I recently was investigating the same question, and eventually found you can easily do this via ILocalRegistry3.CreateInstance!
Please see my post here for more info

How is compiler dealing with these Generic Plugin Interface instance methods?

I'm working with some, unfortunately largely undocumented, existing code and I'm having trouble understanding how it calls upon the methods of the plugins it loads.
My aim at the moment is simply to step into one of the methods loaded via the plugin manager, as it's causing an exception. However I had to rebuild the pluginManager from the source to get debug symbols and when I reference this new DLL version the compiler throws up arms.
The code appears to load the plugin into plug.Instance and then access the specific methods like so plug.Instance.ReturnLeaNumber();
This compiler error makes sense, because it doesn't know the details of the plugins. What confuses me is how the compiler ever knew these where valid before run time, when no plugins are initialized. I can step through the code that doesn't work now with the older DLL!
This is an example of where the program loads up a plugin.
plug = GenericServicePlugins.AvailablePlugins.Find(Application.StartupPath + "\\Dlls\\SchoolInterface.dll");
// Compiler doesn't like this next line anymore though
plug.Instance.Initialize(null, null);
If there are any differences between my rebuilt library and the previously working one, I can't tell how as the versions match up with the ones in our source control. Would appreciate some advice on where to start looking!
public interface IGenericPluginMasterInterface
{
String returnName();
void Initialize(ExceptionStringResources.Translate ExceptionStrings);
Object ExecuteFunction(String macAddress, bool log, String functionName, LoginCredentials logonCredentials, WebConfiguration webConfig,
Int64 dataLinkId, DataLinkParam[] dataLinkParams, String dataName,
DataParam[] dataParams, Object[] additionalParams);
}
Rest of Manager code on PasteBin
How does the compiler know about these plug.Instance.Method() methods before runtime?
Edit:
I've not quite worked this out yet, but there was a "PluginsService" file I missed which partly mirrors the "GenericPluginServices".
I think this error could have been caused when I removed parts of this class that related to an now defunct plugin, which I am looking into. However I figured posting this other code snippet would help the question.
PluginService.cs code
GenericPluginService code
Find returns AvailablePlugin, so .Instance is of type IGenericPluginMasterInterface; if so, indeed; that .Instance.ReturnLeaNumber() can't possibly work...
The only way that could work (without introducing some generics etc) is if .Instance actually returned dynamic. With dynamic the name/method resolution is happening at runtime. The compiler treats dynamic very deliberately such as to defer all resolution to runtime, based on either reflection (for simple cases) or IDynamicMetaObjectProvider (for more sohpisticated cases).
However, if the code you have doesn't match what was compiled, then: we can't tell you what it was. IMO, the best option is to get hold of the working dll, and look at it in reflector to see what it is actually doing, and how it is different to the source code that you have.
Actually, strictly speaking it could still do that with the code you've pasted, but only if plug is typed as dynamic, i.e. dynamic plug = ...

How to generate a compiler error based on an attribute being missing in C#?

I create a number of add-ins for the Revit Structure API. Each tool has to habe a class which implements the interface IExternalCommand.
In the latest version of Revit, for your tool to work you need to have two attributes on the class that implements that interface:
[Regeneration(RegenerationOption.Manual)]
[Transaction(TransactionMode.Automatic)]
The values in brackets can change, but there must be something there. Often I am finding myself forgetting to put the attributes on, then when it comes to runtime it crashes. Is there any way in Visual Studio 2010 to add a compiler warning or error saying that if your class implements that interface it must have those 2 attributes? I have resharper if that helps.
Can anyone point me into the right direction?
Unfortunately not. (I don't know about Resharper, though)
If you have VS2010 Ultimate, you could write a custom Code Analysis rule.
Not during compile time, but I think it'd be easy to with reflection.
I suggest a separate program that uses reflection to examine your compiled assembly, finds all classes with the specified interface, then checks attributes on those classes, returning a nice friendly error message very quickly.
You'd still have to run this program after you compile your program, but depending on your IDE, you could set it as a post-build step.

Categories