Skip to content

Commit cc6b62c

Browse files
committed
Add error handling to GetChildCompilerTypeAtIndex()
This was prompted by a crash report due to an out-of-bounds access of "fields" in return get_from_field_info(fields[idx], tuple, true); which is now wrapped in an error. I don't know how to trigger this situation from a testcase. rdar://128284599
1 parent a29d0b3 commit cc6b62c

File tree

9 files changed

+301
-194
lines changed

9 files changed

+301
-194
lines changed

lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,11 +591,18 @@ static bool ExtractBytesFromRegisters(
591591
bool child_is_base_class = false;
592592
bool child_is_deref_of_parent = false;
593593
uint64_t language_flags;
594-
CompilerType field_clang_type = clang_type.GetChildCompilerTypeAtIndex(
594+
CompilerType field_clang_type;
595+
auto field_clang_type_or_err = clang_type.GetChildCompilerTypeAtIndex(
595596
&exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
596597
ignore_array_bounds, name, child_byte_size, child_byte_offset,
597598
child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
598599
child_is_deref_of_parent, nullptr, language_flags);
600+
if (!field_clang_type_or_err)
601+
LLDB_LOG_ERROR(GetLog(LLDBLog::Types),
602+
field_clang_type_or_err.takeError(),
603+
"could not find child #{1}: {0}", idx);
604+
else
605+
field_clang_type = *field_clang_type_or_err;
599606

600607
const uint64_t field_bit_offset = child_byte_offset * 8;
601608
const size_t field_bit_width =

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,12 +1670,17 @@ class ProjectionSyntheticChildren : public SyntheticChildren {
16701670
uint32_t child_bitfield_bit_offset;
16711671
uint64_t language_flags;
16721672

1673-
type = parent_type.GetChildCompilerTypeAtIndex(
1673+
auto type_or_err = parent_type.GetChildCompilerTypeAtIndex(
16741674
exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
16751675
ignore_array_bounds, child_name, child_byte_size, byte_offset,
16761676
child_bitfield_bit_size, child_bitfield_bit_offset,
16771677
child_is_base_class, child_is_deref_of_parent, valobj,
16781678
language_flags);
1679+
if (!type_or_err)
1680+
LLDB_LOG_ERROR(GetLog(LLDBLog::Types), type_or_err.takeError(),
1681+
"could not find child #{1}: {0}", idx);
1682+
else
1683+
type = *type_or_err;
16791684

16801685
if (child_is_base_class)
16811686
type.Clear(); // invalidate - base classes are dealt with outside of the
@@ -2445,7 +2450,7 @@ SwiftLanguageRuntime::GetIndexOfChildMemberWithName(
24452450
omit_empty_base_classes, child_indexes);
24462451
}
24472452

2448-
CompilerType SwiftLanguageRuntime::GetChildCompilerTypeAtIndex(
2453+
llvm::Expected<CompilerType> SwiftLanguageRuntime::GetChildCompilerTypeAtIndex(
24492454
CompilerType type, size_t idx, bool transparent_pointers,
24502455
bool omit_empty_base_classes, bool ignore_array_bounds,
24512456
std::string &child_name, uint32_t &child_byte_size,

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ class SwiftLanguageRuntime : public LanguageRuntime {
356356
std::vector<uint32_t> &child_indexes);
357357

358358
/// Ask Remote Mirrors about a child of a composite type.
359-
CompilerType GetChildCompilerTypeAtIndex(
359+
llvm::Expected<CompilerType> GetChildCompilerTypeAtIndex(
360360
CompilerType type, size_t idx, bool transparent_pointers,
361361
bool omit_empty_base_classes, bool ignore_array_bounds,
362362
std::string &child_name, uint32_t &child_byte_size,

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp

Lines changed: 78 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,14 @@ using namespace lldb_private;
5353

5454
namespace lldb_private {
5555

56+
std::string toString(const swift::reflection::TypeRef *tr) {
57+
if (!tr)
58+
return "null typeref";
59+
std::stringstream s;
60+
tr->dump(s);
61+
return s.str();
62+
}
63+
5664
static lldb::addr_t
5765
MaskMaybeBridgedPointer(Process &process, lldb::addr_t addr,
5866
lldb::addr_t *masked_bits = nullptr) {
@@ -686,11 +694,11 @@ SwiftLanguageRuntimeImpl::GetNumChildren(CompilerType type,
686694

687695
auto ts = type.GetTypeSystem().dyn_cast_or_null<TypeSystemSwiftTypeRef>();
688696
if (!ts)
689-
return llvm::make_error<llvm::StringError>("no Swift typesystem",
690-
llvm::inconvertibleErrorCode());
697+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
698+
"no Swift typesystem");
691699
if (!type)
692-
return llvm::make_error<llvm::StringError>("invalid type",
693-
llvm::inconvertibleErrorCode());
700+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
701+
"invalid type");
694702

695703
// Deal with the LLDB-only SILPackType variant.
696704
if (auto pack_type = ts->IsSILPackType(type))
@@ -718,10 +726,10 @@ SwiftLanguageRuntimeImpl::GetNumChildren(CompilerType type,
718726
const swift::reflection::TypeRef *tr = nullptr;
719727
auto *ti = GetSwiftRuntimeTypeInfo(type, exe_scope, &tr);
720728
if (!ti)
721-
return llvm::make_error<llvm::StringError>(
729+
return llvm::createStringError(
730+
llvm::inconvertibleErrorCode(),
722731
"could not get Swift runtime type info for type " +
723-
type.GetMangledTypeName().GetString(),
724-
llvm::inconvertibleErrorCode());
732+
type.GetMangledTypeName().GetString());
725733
if (llvm::isa<swift::reflection::BuiltinTypeInfo>(ti)) {
726734
// This logic handles Swift Builtin types. By handling them now, the cost of
727735
// unnecessarily loading ASTContexts can be avoided. Builtin types are
@@ -734,10 +742,10 @@ SwiftLanguageRuntimeImpl::GetNumChildren(CompilerType type,
734742
"{0}: unrecognized builtin type info or this is a Clang type "
735743
"without DWARF debug info",
736744
type.GetMangledTypeName());
737-
return llvm::make_error<llvm::StringError>(
738-
"missing debug info for Clang type \"" +
739-
type.GetDisplayTypeName().GetString() + "\"",
740-
llvm::inconvertibleErrorCode());
745+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
746+
"missing debug info for Clang type \"" +
747+
type.GetDisplayTypeName().GetString() +
748+
"\"");
741749
}
742750
// Structs and Tuples.
743751
if (auto *rti = llvm::dyn_cast<swift::reflection::RecordTypeInfo>(ti)) {
@@ -782,18 +790,18 @@ SwiftLanguageRuntimeImpl::GetNumChildren(CompilerType type,
782790
}
783791

784792
if (!tr)
785-
return llvm::make_error<llvm::StringError>(
786-
"could not typeref for " + type.GetMangledTypeName().GetString(),
787-
llvm::inconvertibleErrorCode());
793+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
794+
"could not typeref for " +
795+
type.GetMangledTypeName().GetString());
788796

789797
// Existentials.
790798
if (size_t n = GetExistentialSyntheticChildren(ts, tr, ti).size())
791799
return n;
792800

793801
ThreadSafeReflectionContext reflection_ctx = GetReflectionContext();
794802
if (!reflection_ctx)
795-
return llvm::make_error<llvm::StringError>(
796-
"no reflection context", llvm::inconvertibleErrorCode());
803+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
804+
"no reflection context");
797805

798806
LLDBTypeInfoProvider tip(*this, exe_scope);
799807
auto *cti = reflection_ctx->GetClassInstanceTypeInfo(
@@ -810,18 +818,15 @@ SwiftLanguageRuntimeImpl::GetNumChildren(CompilerType type,
810818
return rti->getNumFields() + 1;
811819
return rti->getNumFields();
812820
}
813-
return llvm::make_error<llvm::StringError>(
814-
"No Swift runtime type info for " +
815-
type.GetMangledTypeName().GetString(),
816-
llvm::inconvertibleErrorCode());
821+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
822+
"No Swift runtime type info for " +
823+
type.GetMangledTypeName().GetString());
817824
}
818825

819826
LogUnimplementedTypeKind(__FUNCTION__, type);
820-
return llvm::make_error<llvm::StringError>(
821-
"GetNumChildren unimplemented for type " +
822-
type.GetMangledTypeName().GetString(),
823-
llvm::inconvertibleErrorCode());
824-
{};
827+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
828+
"GetNumChildren unimplemented for type " +
829+
type.GetMangledTypeName().GetString());
825830
}
826831

827832
std::optional<unsigned>
@@ -1097,7 +1102,8 @@ SwiftLanguageRuntimeImpl::GetIndexOfChildMemberWithName(
10971102
}
10981103
}
10991104

1100-
CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
1105+
llvm::Expected<CompilerType>
1106+
SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
11011107
CompilerType type, size_t idx, bool transparent_pointers,
11021108
bool omit_empty_base_classes, bool ignore_array_bounds,
11031109
std::string &child_name, uint32_t &child_byte_size,
@@ -1107,7 +1113,8 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
11071113
uint64_t &language_flags) {
11081114
auto ts = type.GetTypeSystem().dyn_cast_or_null<TypeSystemSwiftTypeRef>();
11091115
if (!ts)
1110-
return {};
1116+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
1117+
"no type system");
11111118

11121119
lldb::addr_t pointer = LLDB_INVALID_ADDRESS;
11131120
ExecutionContext exe_ctx;
@@ -1192,16 +1199,16 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
11921199
auto *ti = GetSwiftRuntimeTypeInfo(
11931200
type, exe_ctx.GetBestExecutionContextScope(), &tr);
11941201
if (!ti)
1195-
return {};
1202+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
1203+
"could not get runtime type info for" +
1204+
toString(tr));
1205+
11961206
// Structs and Tuples.
11971207
if (auto *rti =
11981208
llvm::dyn_cast_or_null<swift::reflection::RecordTypeInfo>(ti)) {
11991209
auto fields = rti->getFields();
12001210

12011211
// Handle tuples.
1202-
if (idx >= rti->getNumFields())
1203-
LLDB_LOGF(GetLog(LLDBLog::Types), "index %zu is out of bounds (%d)", idx,
1204-
rti->getNumFields());
12051212
std::optional<TypeSystemSwift::TupleElement> tuple;
12061213
if (rti->getRecordKind() == swift::reflection::RecordKind::Tuple)
12071214
tuple = ts->GetTupleElement(type.GetOpaqueQualType(), idx);
@@ -1220,6 +1227,11 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
12201227
language_flags = 0;
12211228
return ts->GetRawPointerType();
12221229
}
1230+
if (idx - 3 >= fields.size())
1231+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
1232+
llvm::Twine("index") + llvm::Twine(idx) +
1233+
"is out of bounds (" +
1234+
llvm::Twine(fields.size()) + ")");
12231235
return get_from_field_info(fields[idx - 3], tuple, false);
12241236
}
12251237
if (rti->getRecordKind() ==
@@ -1239,6 +1251,11 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
12391251
return protocol_child.get_type();
12401252
}
12411253
}
1254+
if (idx >= fields.size())
1255+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
1256+
llvm::Twine("index") + llvm::Twine(idx) +
1257+
"is out of bounds (" +
1258+
llvm::Twine(fields.size()) + ")");
12421259
return get_from_field_info(fields[idx], tuple, true);
12431260
}
12441261
// Enums.
@@ -1251,9 +1268,10 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
12511268
if (i++ == idx)
12521269
return get_from_field_info(enum_case, {}, true);
12531270
}
1254-
LLDB_LOG(GetLog(LLDBLog::Types), "index {0} is out of bounds ({1})", idx,
1255-
eti->getNumPayloadCases());
1256-
return {};
1271+
return llvm::createStringError(
1272+
llvm::inconvertibleErrorCode(),
1273+
llvm::Twine("index") + llvm::Twine(idx) + "is out of bounds (" +
1274+
llvm::Twine(eti->getNumPayloadCases()) + ")");
12571275
}
12581276
if (auto *rti =
12591277
llvm::dyn_cast_or_null<swift::reflection::ReferenceTypeInfo>(ti)) {
@@ -1272,9 +1290,10 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
12721290
return protocol_child.get_type();
12731291
}
12741292
if (i) {
1275-
LLDB_LOG(GetLog(LLDBLog::Types), "index {0} is out of bounds ({1})", idx,
1276-
i - 1);
1277-
return {};
1293+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
1294+
llvm::Twine("index") + llvm::Twine(idx) +
1295+
"is out of bounds (" +
1296+
llvm::Twine(i - 1) + ")");
12781297
}
12791298

12801299
// Objects.
@@ -1303,7 +1322,9 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
13031322

13041323
// Try the instance type metadata.
13051324
if (!valobj)
1306-
return {};
1325+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
1326+
"object has no address");
1327+
13071328
bool found_start = false;
13081329
using namespace swift::Demangle;
13091330
Demangler dem;
@@ -1314,12 +1335,16 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
13141335

13151336
ThreadSafeReflectionContext reflection_ctx = GetReflectionContext();
13161337
if (!reflection_ctx)
1317-
return {};
1338+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
1339+
"no reflection context");
1340+
13181341
CompilerType instance_type = valobj->GetCompilerType();
13191342
auto instance_ts =
13201343
instance_type.GetTypeSystem().dyn_cast_or_null<TypeSystemSwift>();
13211344
if (!instance_ts)
1322-
return {};
1345+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
1346+
"no typesystem");
1347+
13231348
// LLDBTypeInfoProvider needs to be kept alive while supers gets accessed.
13241349
llvm::SmallVector<SuperClassType, 2> supers;
13251350
auto superclass_finder = [&](SuperClassType sc) -> bool {
@@ -1371,7 +1396,9 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
13711396
return get_from_field_info(fields[idx], tuple, true);
13721397
}
13731398
}
1374-
return {};
1399+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
1400+
llvm::Twine("index") + llvm::Twine(idx) +
1401+
"is out of bounds");
13751402
}
13761403

13771404
// Handle the artificial base class fields.
@@ -1387,7 +1414,7 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
13871414
// field in the base class.
13881415
if (!type_ref) {
13891416
child_name = "<base class>";
1390-
return {};
1417+
return CompilerType();
13911418
}
13921419
CompilerType super_type = GetTypeFromTypeRef(*ts, type_ref);
13931420
child_name = super_type.GetTypeName().GetStringRef().str();
@@ -1411,24 +1438,27 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex(
14111438
// Handle the "real" fields.
14121439
auto *object = supers[0].get_record_type_info();
14131440
if (!object)
1414-
return {};
1441+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
1442+
"no record type info");
14151443
for (auto &field : object->getFields())
14161444
if (i++ == idx)
14171445
return get_from_field_info(field, {}, true);
14181446

1419-
LLDB_LOG(GetLog(LLDBLog::Types), "index {0} is out of bounds ({1})", idx,
1420-
i - 1);
1421-
return {};
1447+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
1448+
llvm::Twine("index") + llvm::Twine(idx) +
1449+
"is out of bounds (" +
1450+
llvm::Twine(i - 1) + ")");
14221451
}
14231452
if (llvm::dyn_cast_or_null<swift::reflection::BuiltinTypeInfo>(ti)) {
14241453
// Clang enums have an artificial rawValue property. We could
14251454
// consider handling them here, but
14261455
// TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex can also
14271456
// handle them and without a Process.
1428-
return {};
1457+
return CompilerType();
14291458
}
14301459
LogUnimplementedTypeKind(__FUNCTION__, type);
1431-
return {};
1460+
return llvm::createStringError(llvm::inconvertibleErrorCode(),
1461+
"not implemented");
14321462
}
14331463

14341464
bool SwiftLanguageRuntimeImpl::ForEachSuperClassType(

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ class SwiftLanguageRuntimeImpl {
144144
bool omit_empty_base_classes,
145145
std::vector<uint32_t> &child_indexes);
146146

147-
CompilerType GetChildCompilerTypeAtIndex(
147+
llvm::Expected<CompilerType> GetChildCompilerTypeAtIndex(
148148
CompilerType type, size_t idx, bool transparent_pointers,
149149
bool omit_empty_base_classes, bool ignore_array_bounds,
150150
std::string &child_name, uint32_t &child_byte_size,

0 commit comments

Comments
 (0)