microsoft / ConcordExtensibilitySamples

Visual Studio Debug Engine Extensibility Samples
Other
122 stars 50 forks source link

Method chaining in IDkmLanguageExpressionEvaluator not working #63

Closed Rattenhirn closed 3 years ago

Rattenhirn commented 3 years ago

Hello,

I am not sure if this is a bug or me doing something wrong, but I am having troubles getting a basic IDkmLanguageExpressionEvaluator to work. I adapted the HelloWorld sample (not the C# and the c++ flavor) to implement the interface, and my functions are getting called. Since they don't do anything yet, I just hand them off to the next dispatch objects with the method chaining method. However, the dispatch objects down the chain don't seem to do anything anymore as soon as my dispatch object is installed. I get empty watch windows and when I force a watch, it hangs until I stop debugging.

Oddly enough, the watches are broken, regardless of whether my plugin has a high component level and actually gets called, or a low enough level so that it doesn't get called. Hence my suspicion that it might be a bug.

I also tried without method chaining by returning E_NOTIMPL, like the CppCustomVisualizer (which I got to work btw), with no change.

Here is an example of an interface function with chaining:

HRESULT STDMETHODCALLTYPE CHelloWorldService::GetFrameLocals(
    DkmInspectionContext* inspectionContext,
    DkmWorkList* workList,
    DkmStackWalkFrame* frame,
    IDkmCompletionRoutine<DkmGetFrameLocalsAsyncResult>* completionRoutine
)
{
    Log("CHelloWorldService::GetFrameLocals");
    inspectionContext->GetFrameLocals(workList, frame, completionRoutine);
    return S_OK;
}

And here is the .vsdconfigxml with the high component level:

<?xml version="1.0" encoding="utf-8"?>
<Configuration xmlns="http://schemas.microsoft.com/vstudio/vsdconfig/2008">
  <NativeComponent
    ComponentId="EB539DB5-EB09-42C8-8217-AEB14EA4C30B"
    ComponentLevel="10000000"
    ModuleName="HelloWorld.dll">
    <Class Name="CHelloWorldService" ClassId="C797BD7C-E993-440D-BAC3-DCB6858052B4">
      <Implements>
        <InterfaceGroup>
          <NoFilter/>
          <Interface Name="IDkmLanguageExpressionEvaluator"/>
        </InterfaceGroup>
      </Implements>
    </Class>
  </NativeComponent>
</Configuration>
gregg-miskelly commented 3 years ago

What you are doing looks like it should work. I will need to debug to try and understand why it is failing. Can you upload your sources somewhere so that I am doing exactly the same thing that you are? It will probably be a few days before I have time to investigate more, but please ping me if I haven't replied by 11/30.

Rattenhirn commented 3 years ago

Sure thing, I have attached my modified HelloWorld sample! Thanks for looking into this! HelloWorld_Cpp.zip

Edit: This is on VS 16.8.0 btw

gregg-miskelly commented 3 years ago

Sorry for the delay. What is going on is that you have found a bug in method chaining combined with Worker Process Remoting. What is going on is that the request gets to your component, you forward it to the next implementation which is in a worker process. The worker process picks up the request and tries to call the highest priority component that it can find, which is your hello world service, so the request gets forwarded right back.

If you goal is to forward some requests on to the C++ Expression evaluator, you can solve this by loading your extension in the worker process. See the Worker Process Remoting documentation that I linked to for instructions on doing this.

gregg-miskelly commented 3 years ago

I added a fix to 16.9 which should this scenario work. Baring something unexpected, you should be able to try it out starting with 16.9 preview 3. Though if you goal is to send a bunch of requests to the C++ EE, it might still make sense to be in worker process.

Rattenhirn commented 3 years ago

JFYI, got it to work with the Worker Process, thanks!