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
Related
I'm working on a huge C# + VB.NET solution that has about 210 projects.
Some developers have over time been using a method that only work in a specific context (HttpContext needs to be present) which means that Console Applications that somewhere in their calltree use this method, will fail.
Other than throwing an exception (which might break running solutions), is there a way to check if this context dependent method is called by a specific 'parent' ?
In Visual Studio it's possible to "Find All References", so i'm looking for some tool that could do this recursively to give me a list of eg: all projects that somehow call this broken code.
I'm working on a Visual Studio solution that currently has two projects in it (with more to come later). One project is a mature C#/Winforms application that I built last year (think of it as the prototype). The other one is a DLL that is going to do the same thing as the prototype but through a different application. I'd like to re-use code from the prototype (let's call the method in question SyncInvoices() ) in the DLL because the prototype code works perfectly b/c I've hammered the bugs out of it. The class that contains SyncInvoices is baked into the prototype application instead of being its own DLL.
I've added the class that contains SyncInvoices() to the DLL's project (as a linked file, since it already exists elsewhere in the solution). I can instantiate that class in the DLL project and call SyncInvoices() but the compiler throws errors related to GUI elements.
The problem is that SyncInvoices() has some-thread safe calls to the Prototype application's GUI in it, basically used to pass messages/errors back to the interface.
The DLL doesn't have a GUI, so it doesn't need to run that code. It still builds the rest of the methods in that class, even though they aren't used. Is there a way I can tell the compiler to ignore those lines when building the DLL? I'd rather not maintain two sets of nearly identical code, especially when the two projects are part of the same solution.
I thought about using #define/ #if blocks to partition off the code but I'm not sure if C# works that way-- most of the time I've seen those used is to keep debug code from ending up in production. If it is possible to tell the app to include/exclude code through #if blocks, how do I set the values?
Should I just bite the bullet and make a copy of the method without the offending code in it?
Without more specifics it's hard to give the correct answer, but I'd say generally you'd handle this with events. Whatever calls into the GUI are happening in the prototype, that would typically be some form of event, which you would subscribe to in the prototype when you instantiate your new class.
Are there any particularly problematic cases you could give more specifics on?
I'm looking for a way to detect how code is called during a debugging session in Visual Studio. Trying to differentiate these two contexts:
Ordinary debugging, whether running or single stepping.
Called via the debugger itself, such as my ToString being called from the watch window.
(I'm doing this because I have some non-release thread validation code I want to disable in the second case.)
Anyone have a way to do this, or ideas about things to pursue? I'm fine with hacky, tricksy methods, even if they are specific to a particular version of VS.
Things that don't work:
Grabbing a StackTrace and looking for something magic that means the debugger is calling in, rather than regular code. VS uses the current thread in its current state to call out of for the Watch window, so all the StackTrace is going to see is the current stack at the debugger breakpoint + the getter/ToString that the Watch window is calling, right on top of it.
This situation typically arises when methods that Visual Studio assumes are pure (i.e. evaluation has no impact on the state of the program) either have side effects or have preconditions that the debugger violates.
These situations are best solved using the following tools:
DebuggerBrowsableAttribute: Apply this attribute to properties:
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
Apply to all properties whose get method is not pure, i.e. the getter alters the state of the program, either through setting a cached value or otherwise
Apply to all properties whose get method has preconditions the debugger could violate, such as threading restrictions, cross-thread invocations (don't forget implicit if you use COM interop)
DebuggerDisplayAttribute: Apply this attribute to all types whose ToString() implementation performs non-trivial operations (avoid debugger performance impact) or has preconditions the debugger might not meet (e.g. threading requirements). This attribute is used instead of calling ToString() for these types.
DebuggerTypeProxyAttribute: Apply this attribute to types that require special consideration for when, what, and how information is presented in the debugger. The .NET framework itself uses this attribute extensively to provide features like clear output for the List<T> and HashMap<T> types, and even to improve information available for types like Lazy<T> that are sometimes OK to evaluate and other times could affect the state of the program.
As far as ordinary debugging goes, I think this is what you want:
System.Diagnostics.Debugger.IsAttached
Here's the documentation.
This won't help with the watch window though. On this, maybe the StackTrace class can help but I haven't tried it myself. It's in the same namespace.
I have the following code. The CustomControlHelper generates an instance of an object via reflection. At this stage we don't know what type of object we are dealing with. We do know it will be a CustomControl, but we don't know if it implements any particular interface or if it extends any other classes. The following code is trying to establish whether the loaded control implements the IRichAdminCustomControl interface.
Object obj = CustomControlHelper.GetControl(cc.Id, cc.ControlClass);
if(obj != null)
{
bool isWhatWeWant = (obj is IRichAdminCustomControl);
return isWhatWeWant;
}
That's all fine, but I've noticed that when I know I have an object that implements IRichAdminCustomControl, the expression evaluates to false.
Okay, this is where it gets really weird. If I inspect the code when debugging, the expression evaluates to true, but then if I immediately let the code run and inspect the result, it evaluates to false (I've attached an animated gif below to illustrate).
Has anyone come across weirdness like this before and if so, what on earth is causing it?
Incidentally, I believe the product I'm using uses Spring.NET to provide dependency injection in the CustomControlHelper.
If you are using Visual Studio 2010 SP1, I came across this bug:
Misreporting of variable values when debugging x64 code
There is a workaround on that page, posted by Microsoft:
You can either set all projects to compile to x86, or create an intermediate initialised variable declaration to ensure the debugger reports the correct value of the variable being examined.
Try this as a workaround:
bool isWhatWeWant = true;
isWhatWeWant &= (obj is IRichAdminCustomControl);
bool finalValue = isWhatWeWant; // this line should fix isWhatWeWant too in the debugger
return finalValue;
EDIT: seems like VS2012 also encounters similar problems in specific conditions.
Two possibilities come to mind. The first is that your interface name is generic enough that it could already be in the namespace somewhere. Try fully qualifying the interface in the is clause. The second possibility is that you might be running the code as part of a constructor, or being called indirectly by a constructor. Any reflection like stuff needs to be done after we are certain the application has fully loaded.
So I found the answer. It was because I had two copies of the dll in different locations. I had one copy in the bin of my back-end application and one in a shared external directory that gets dynamically loaded by the backend app.
I should explain; this application consists of two apps running in tandem, a frontend app and a backend app. Ordinarily, you place "Custom Controls" into your frontend app. These controls are then copied on application start to a external directory that is accessible to the backend app.
In this case, I had logic in my Custom Control library that needed to be accessed in the backend app - so I had to make a reference to it... which ended up with the backend app having two references to the same class. D'oh! And OF COURSE that's going to work when you're debugging.
Solution was to split my extra logic into its own project and reference THAT in the backend app.
I'm not going to "accept" my own answer here because, although it solved my specific problem, the solution is a bit TOO specific to the apps I'm working with and would be unlikely to help anyone else.
This happened to me once and even though I never came to a conclusion as to why it was happening I believed the PDB files that were being loaded with the debugging symbols where out of sync. So, by "cleaning" the solution and then rebuilding the solution this weird issue went away.
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.