Skip to content

Commit

Permalink
Fix some visualizer crashes and misbehavior (#734)
Browse files Browse the repository at this point in the history
* Don't throw an error on an unrecognized type.

* Don't endlessly recreate property data.

Co-authored-by: Ben Kuhn <bjk4929@yahoo.com>
  • Loading branch information
DefaultRyan and BenJKuhn committed Aug 21, 2020
1 parent c1b3d93 commit 3a95080
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 33 deletions.
8 changes: 3 additions & 5 deletions natvis/cppwinrtvisualizer.vcxproj
Expand Up @@ -205,10 +205,10 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="$(NugetPackagesDirectory)Microsoft.VSSDK.Debugger.VSDebugEng.*\inc\VSDebugEng.h" />
<ClInclude Include="$(NugetPackagesDirectory)Microsoft.VSSDK.Debugger.VSDebugEng.*\inc\vsdebugeng.templates.h" />
<ClInclude Include="object_visualizer.h" />
<ClInclude Include="cppwinrt_visualizer.h" />
<ClInclude Include="packages\Microsoft.VSSDK.Debugger.VSDebugEng.16.0.2012201-preview\inc\VSDebugEng.h" />
<ClInclude Include="packages\Microsoft.VSSDK.Debugger.VSDebugEng.16.0.2012201-preview\inc\vsdebugeng.templates.h" />
<ClInclude Include="property_visualizer.h" />
<ClInclude Include="pch.h" />
</ItemGroup>
Expand Down Expand Up @@ -238,9 +238,7 @@
<None Include="packages.config">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<ItemGroup>
<None Include="$(NugetPackagesDirectory)Microsoft.VSSDK.Debugger.VSDConfigTool.*\content\vsdconfig.xsd">
<None Include="packages\Microsoft.VSSDK.Debugger.VSDConfigTool.16.0.2012201-preview\content\vsdconfig.xsd">
<SubType>Designer</SubType>
</None>
</ItemGroup>
Expand Down
68 changes: 40 additions & 28 deletions natvis/object_visualizer.cpp
Expand Up @@ -347,6 +347,7 @@ struct property_type
};

void GetInterfaceData(
Microsoft::VisualStudio::Debugger::DkmProcess* process,
coded_index<TypeDefOrRef> index,
_Inout_ std::vector<PropertyData>& propertyData,
_Out_ bool& isStringable
Expand All @@ -370,20 +371,25 @@ void GetInterfaceData(
continue;
}

PropertyCategory propCategory;
std::optional<PropertyCategory> propCategory;
std::wstring propAbiType;
std::wstring propDisplayType;

auto retType = method.Signature().ReturnType();
std::visit(overloaded{
[&](ElementType type)
{
if ((type < ElementType::Boolean) || (type > ElementType::String))
if ((ElementType::Boolean <= type) && (type <= ElementType::String))
{
return;
propCategory = (PropertyCategory)(static_cast<std::underlying_type<ElementType>::type>(type) -
static_cast<std::underlying_type<ElementType>::type>(ElementType::Boolean));
}
else if (type == ElementType::Object)
{
//propDisplayType = L"winrt::Windows::Foundation::IInspectable";
//propCategory = PropertyCategory::Class;
//propAbiType = L"winrt::impl::inspectable_abi*";
}
propCategory = (PropertyCategory)(static_cast<std::underlying_type<ElementType>::type>(type) -
static_cast<std::underlying_type<ElementType>::type>(ElementType::Boolean));
},
[&](coded_index<TypeDefOrRef> const& index)
{
Expand Down Expand Up @@ -443,21 +449,24 @@ void GetInterfaceData(
},
[&](GenericTypeIndex /*var*/)
{
throw_invalid("Generics are not yet supported");
NatvisDiagnostic(process, L"Generics not yet supported", NatvisDiagnosticLevel::Warning);
},
[&](GenericMethodTypeIndex /*var*/)
{
throw_invalid("Generic methods not supported.");
NatvisDiagnostic(process, L"Generics not yet supported", NatvisDiagnosticLevel::Warning);
},
[&](GenericTypeInstSig const& /*type*/)
{
throw_invalid("Generics are not yet supported");
NatvisDiagnostic(process, L"Generics not yet supported", NatvisDiagnosticLevel::Warning);
}
}, retType.Type().Type());

auto propName = method.Name().substr(4);
std::wstring propDisplayName(propName.cbegin(), propName.cend());
propertyData.push_back({ propIid, propIndex, propCategory, propAbiType, propDisplayType, propDisplayName });
if (propCategory)
{
auto propName = method.Name().substr(4);
std::wstring propDisplayName(propName.cbegin(), propName.cend());
propertyData.push_back({ propIid, propIndex, *propCategory, propAbiType, propDisplayType, propDisplayName });
}
}
}

Expand Down Expand Up @@ -498,17 +507,17 @@ void object_visualizer::GetTypeProperties(Microsoft::VisualStudio::Debugger::Dkm
auto impls = type.InterfaceImpl();
for (auto&& impl : impls)
{
GetInterfaceData(impl.Interface(), m_propertyData, m_isStringable);
GetInterfaceData(process, impl.Interface(), m_propertyData, m_isStringable);
}
}
else if (get_category(type) == category::interface_type)
{
auto impls = type.InterfaceImpl();
for (auto&& impl : impls)
{
GetInterfaceData(impl.Interface(), m_propertyData, m_isStringable);
GetInterfaceData(process, impl.Interface(), m_propertyData, m_isStringable);
}
GetInterfaceData(type.coded_index<TypeDefOrRef>(), m_propertyData, m_isStringable);
GetInterfaceData(process, type.coded_index<TypeDefOrRef>(), m_propertyData, m_isStringable);
}
}

Expand Down Expand Up @@ -574,22 +583,25 @@ HRESULT object_visualizer::GetChildren(
)
{
// Ignore metadata errors to ensure that Raw Data is always available
try
if (m_propertyData.empty())
{
GetPropertyData();
}
catch (std::invalid_argument const& e)
{
std::string_view message(e.what());
NatvisDiagnostic(m_pVisualizedExpression.get(),
std::wstring(L"Exception in object_visualizer::GetPropertyData: ") +
try
{
GetPropertyData();
}
catch (std::invalid_argument const& e)
{
std::string_view message(e.what());
NatvisDiagnostic(m_pVisualizedExpression.get(),
std::wstring(L"Exception in object_visualizer::GetPropertyData: ") +
std::wstring(message.begin(), message.end()),
NatvisDiagnosticLevel::Error, to_hresult());
}
catch (...)
{
NatvisDiagnostic(m_pVisualizedExpression.get(),
L"Exception in object_visualizer::GetPropertyData", NatvisDiagnosticLevel::Error, to_hresult());
NatvisDiagnosticLevel::Error, to_hresult());
}
catch (...)
{
NatvisDiagnostic(m_pVisualizedExpression.get(),
L"Exception in object_visualizer::GetPropertyData", NatvisDiagnosticLevel::Error, to_hresult());
}
}

com_ptr<DkmEvaluationResultEnumContext> pEnumContext;
Expand Down

0 comments on commit 3a95080

Please sign in to comment.