microsoft / ConcordExtensibilitySamples

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

Difficulties changing names on DkmEvaluationResults #79

Open fredrikz opened 2 years ago

fredrikz commented 2 years ago

This is not really an issue per se, more of a question of how to use the API.

I have a modified CCppCustomVisualizer class I'm working on, for a complex object(the object is actually a collection of structs residing in different memory locations, so the object can have 0-N "members"). So far so good, I've gotten it to work and when resolving the complex object, it has a dynamic amount of children.

The problem I'm encountering is when I try to rename the children by recreating a DkmSuccessEvaluationResult, is that the little "+" next to the object stops working in Visual Studios 'Watch' window, i.e. we cannot expand the child components. However, dragging the child member so it creates a new entry in the 'Watch' window, allows expansion. Also, not renaming/recreating DkmSuccessEvaluationResult also works.

HRESULT STDMETHODCALLTYPE CCppCustomVisualizerService::GetItems(
    _In_ Evaluation::DkmVisualizedExpression *pVisualizedExpression,
    _In_ Evaluation::DkmEvaluationResultEnumContext *pEnumContext,
    _In_ UINT32 StartIndex, _In_ UINT32 Count,
    _Out_ DkmArray<Evaluation::DkmChildVisualizedExpression *> *pItems) {
  HRESULT hr;
  hr = DkmAllocArray(Count, pItems);
  if (FAILED(hr)) {
    return hr;
  }

  Evaluation::DkmPointerValueHome *pPointerValueHome =
      Evaluation::DkmPointerValueHome::TryCast(
          pVisualizedExpression->ValueHome());

  vector<name_and_expr> comps;
  hr = evaluate_entity(pVisualizedExpression, pPointerValueHome, comps);
  if (FAILED(hr)) {
    return hr;
  }

  for (UINT32 i = StartIndex; i < StartIndex + Count; ++i) {
    const name_and_expr &expr = comps[i];
    DkmChildVisualizedExpression **children = pItems->Members;
    DkmChildVisualizedExpression **pChild = &children[i];

    CComPtr<DkmEvaluationResult> pEEEvaluationResultOther;
    hr =
        EvaluateOtherExpression(pVisualizedExpression, DkmEvaluationFlags::None,
                                expr._expr.c_str(), &pEEEvaluationResultOther);
    CComPtr<DkmString> pName;
    hr = DkmString::Create(DkmSourceString(expr._name.c_str()), &pName);
    if (FAILED(hr)) {
      return hr;
    }

    if (pEEEvaluationResultOther->TagValue() ==
            DkmEvaluationResult::Tag::SuccessResult &&
        !expr._name.empty()) {
      DkmSuccessEvaluationResult *success =
          DkmSuccessEvaluationResult::TryCast(pEEEvaluationResultOther);

      CComPtr<DkmSuccessEvaluationResult> pNamedEEEvaluationResultOther;

      // NOTE: HERE IS THE PROBLEM CODE
      // Createa success result, but with a custom name
      // Either using 'success->Name()' or 'pName' here leads to a child member which cannot be expanded
      hr = DkmSuccessEvaluationResult::Create(
          success->InspectionContext(), success->StackFrame(), success->Name(),
          success->FullName(), success->Flags(), success->Value(),
          success->EditableValue(), success->Type(), success->Category(),
          success->Access(), success->StorageType(),
          success->TypeModifierFlags(), success->Address(),
          success->CustomUIVisualizers(), success->ExternalModules(),
          DkmDataItem::Null(), &pNamedEEEvaluationResultOther);

      pEEEvaluationResultOther = pNamedEEEvaluationResultOther.Detach();
      // NOTE: PROBLEM CODE END
    }

    DkmChildVisualizedExpression::Create(
        pVisualizedExpression->InspectionContext(),
        pVisualizedExpression->VisualizerId(),
        pVisualizedExpression->SourceId(), pVisualizedExpression->StackFrame(),
        pPointerValueHome, pEEEvaluationResultOther.Detach(),
        pVisualizedExpression, i, DkmDataItem::Null(), pChild);
  }

  return S_OK;
}

Image of the result, where the selected row cannot be expanded, but as you can see, the row at the end containing the same expression can be. image

Do you have any idea what could cause such a behavior? Is it possible to change the 'Name' of a DkmEvaluationResult in some other way? Or clone it somehow? I have used the same approach in another part of the code, and there it works. You can check the fork with modified CppCustomVisualizer/dll and CppCustomVisualizer/TargetApp here: https://github.com/fredrikz/ConcordExtensibilitySamples