Visualizer should try to find winmd for interface and property types, and should fail more gracefully when not found. (#864)

This commit is contained in:
Ryan Shepherd 2021-02-27 14:15:14 -08:00 коммит произвёл GitHub
Родитель 39c062ecc9
Коммит 2e3d3a9454
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 44 добавлений и 9 удалений

Просмотреть файл

@ -100,8 +100,14 @@ void LoadMetadata(DkmProcess* process, WCHAR const* processPath, std::string_vie
if (FindMetadata(process, winmd_path))
{
MetadataDiagnostic(process, L"Loaded ", winmd_path);
db_files.push_back(winmd_path.string());
db->add_database(winmd_path.string());
auto const path_string = winmd_path.string();
if (std::find(db_files.begin(), db_files.end(), path_string) == db_files.end())
{
db->add_database(path_string);
db_files.push_back(path_string);
}
}
auto pos = probe_file.rfind('.');
if (pos == std::string::npos)
@ -129,6 +135,19 @@ TypeDef FindType(DkmProcess* process, std::string_view const& typeName)
return type;
}
TypeDef FindType(DkmProcess* process, std::string_view const& typeNamespace, std::string_view const& typeName)
{
auto type = db->find(typeNamespace, typeName);
if (!type)
{
std::string fullName(typeNamespace);
fullName.append(".");
fullName.append(typeName);
FindType(process, fullName);
}
return type;
}
cppwinrt_visualizer::cppwinrt_visualizer()
{
try

Просмотреть файл

@ -361,7 +361,11 @@ void GetInterfaceData(
_Inout_ std::vector<PropertyData>& propertyData,
_Out_ bool& isStringable
){
auto [type, propIid] = ResolveTypeInterface(index);
auto [type, propIid] = ResolveTypeInterface(process, index);
if (!type)
{
return;
}
if (propIid == IID_IStringable)
{
@ -402,7 +406,12 @@ void GetInterfaceData(
},
[&](coded_index<TypeDefOrRef> const& index)
{
auto type = ResolveType(index);
auto type = ResolveType(process, index);
if (!type)
{
return;
}
auto typeName = type.TypeName();
if (typeName == "GUID"sv)
{

Просмотреть файл

@ -89,21 +89,22 @@ inline bool starts_with(std::string_view const& value, std::string_view const& m
}
winmd::reader::TypeDef FindType(Microsoft::VisualStudio::Debugger::DkmProcess* process, std::string_view const& typeName);
winmd::reader::TypeDef FindType(Microsoft::VisualStudio::Debugger::DkmProcess* process, std::string_view const& typeNamespace, std::string_view const& typeName);
inline winmd::reader::TypeDef ResolveType(winmd::reader::coded_index<winmd::reader::TypeDefOrRef> index) noexcept
inline winmd::reader::TypeDef ResolveType(Microsoft::VisualStudio::Debugger::DkmProcess* process, winmd::reader::coded_index<winmd::reader::TypeDefOrRef> index) noexcept
{
switch (index.type())
{
case winmd::reader::TypeDefOrRef::TypeDef:
return index.TypeDef();
case winmd::reader::TypeDefOrRef::TypeRef:
return winmd::reader::find_required(index.TypeRef());
return FindType(process, index.TypeRef().TypeNamespace(), index.TypeRef().TypeName());
default: //case TypeDefOrRef::TypeSpec:
return winmd::reader::find_required(index.TypeSpec().Signature().
GenericTypeInst().GenericType().TypeRef());
}
}
std::pair<winmd::reader::TypeDef, std::wstring> ResolveTypeInterface(winmd::reader::coded_index<winmd::reader::TypeDefOrRef> index);
std::pair<winmd::reader::TypeDef, std::wstring> ResolveTypeInterface(Microsoft::VisualStudio::Debugger::DkmProcess* process, winmd::reader::coded_index<winmd::reader::TypeDefOrRef> index);
void ClearTypeResolver();

Просмотреть файл

@ -3,6 +3,7 @@
using namespace winrt;
using namespace winmd::reader;
using namespace std::literals;
using namespace Microsoft::VisualStudio::Debugger;
static std::map<coded_index<TypeDefOrRef>, std::pair<TypeDef, std::wstring>> _cache;
@ -277,14 +278,19 @@ static guid generate_guid(coded_index<TypeDefOrRef> const& type)
return set_named_guid_fields(endian_swap(to_guid(calculate_sha1(buffer))));
}
std::pair<TypeDef, std::wstring> ResolveTypeInterface(coded_index<TypeDefOrRef> index)
std::pair<TypeDef, std::wstring> ResolveTypeInterface(DkmProcess* process, coded_index<TypeDefOrRef> index)
{
if (auto found = _cache.find(index); found != _cache.end())
{
return found->second;
}
TypeDef type = ResolveType(index);
TypeDef type = ResolveType(process, index);
if (!type)
{
return {};
}
auto guid = index.type() == TypeDefOrRef::TypeSpec ?
format_guid(generate_guid(index)) : format_guid(get_guid(type));