Skip to content

Commit d9805ca

Browse files
mikeashairspeedswift
authored andcommitted
[Reflection] Add error messages to the new Remote Mirror calls and plumb them through swiftdt.
rdar://problem/55481578
1 parent df5580b commit d9805ca

File tree

5 files changed

+74
-41
lines changed

5 files changed

+74
-41
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "llvm/Object/COFF.h"
2525

2626
#include "swift/ABI/Enum.h"
27+
#include "swift/Basic/TaggedUnion.h"
2728
#include "swift/Remote/MemoryReader.h"
2829
#include "swift/Remote/MetadataReader.h"
2930
#include "swift/Reflection/Records.h"
@@ -815,16 +816,16 @@ class ReflectionContext
815816
iterateConformanceTree(NodeData->Right, Call);
816817
}
817818

818-
bool iterateConformances(
819+
llvm::Optional<std::string> iterateConformances(
819820
std::function<void(StoredPointer Type, StoredPointer Proto)> Call) {
820821
std::string ConformancesName = "__ZL12Conformances";
821822
auto ConformancesAddr = getReader().getSymbolAddress(ConformancesName);
822823
if (!ConformancesAddr)
823-
return false;
824+
return "unable to look up conformances cache symbol " + ConformancesName;
824825

825826
auto Root = getReader().readPointer(ConformancesAddr, sizeof(StoredPointer));
826827
iterateConformanceTree(Root->getResolvedAddress().getAddressData(), Call);
827-
return true;
828+
return llvm::None;
828829
}
829830

830831
void iterateModules(Demangle::NodePointer Ptr, std::function<void(llvm::StringRef)> Call) {
@@ -864,11 +865,12 @@ class ReflectionContext
864865
return 0;
865866
}
866867

867-
bool iterateMetadataAllocations(std::function<void (MetadataAllocation)> Call) {
868+
llvm::Optional<std::string>
869+
iterateMetadataAllocations(std::function<void (MetadataAllocation)> Call) {
868870
std::string AllocationPoolName = "__ZL14AllocationPool";
869871
auto AllocationPoolAddr = getReader().getSymbolAddress(AllocationPoolName);
870872
if (!AllocationPoolAddr)
871-
return false;
873+
return "unable to look up allocation pool symbol " + AllocationPoolName;
872874

873875
struct PoolRange {
874876
StoredPointer Begin;
@@ -887,7 +889,7 @@ class ReflectionContext
887889
.readBytes(RemoteAddress(AllocationPoolAddr), sizeof(PoolRange));
888890
auto Pool = reinterpret_cast<const PoolRange *>(PoolBytes.get());
889891
if (!Pool)
890-
return false;
892+
return std::string("failure reading allocation pool contents");
891893

892894
auto TrailerPtr = Pool->Begin + Pool->Remaining;
893895
while (TrailerPtr) {
@@ -921,7 +923,7 @@ class ReflectionContext
921923

922924
TrailerPtr = Trailer->PrevTrailer;
923925
}
924-
return true;
926+
return llvm::None;
925927
}
926928

927929
private:

include/swift/SwiftRemoteMirror/SwiftRemoteMirror.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,15 +289,15 @@ size_t swift_reflection_demangle(const char *MangledName, size_t Length,
289289
char *OutDemangledName, size_t MaxLength);
290290

291291
SWIFT_REMOTE_MIRROR_LINKAGE
292-
int swift_reflection_iterateConformanceCache(
292+
const char *swift_reflection_iterateConformanceCache(
293293
SwiftReflectionContextRef ContextRef,
294294
void (*Call)(swift_reflection_ptr_t Type,
295295
swift_reflection_ptr_t Proto,
296296
void *ContextPtr),
297297
void *ContextPtr);
298298

299299
SWIFT_REMOTE_MIRROR_LINKAGE
300-
int swift_reflection_iterateMetadataAllocations(
300+
const char *swift_reflection_iterateMetadataAllocations(
301301
SwiftReflectionContextRef ContextRef,
302302
void (*Call)(swift_metadata_allocation_t Allocation,
303303
void *ContextPtr),

stdlib/public/SwiftRemoteMirror/SwiftRemoteMirror.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ struct SwiftReflectionContext {
4040
NativeReflectionContext *nativeContext;
4141
std::vector<std::function<void()>> freeFuncs;
4242
std::vector<std::tuple<swift_addr_t, swift_addr_t>> dataSegments;
43+
std::string lastError;
4344

4445
SwiftReflectionContext(MemoryReaderImpl impl) {
4546
auto Reader = std::make_shared<CMemoryReader>(impl);
@@ -422,6 +423,15 @@ static swift_childinfo_t convertChild(const TypeInfo *TI, unsigned Index) {
422423
};
423424
}
424425

426+
static const char *convertError(SwiftReflectionContextRef ContextRef,
427+
llvm::Optional<std::string> Error) {
428+
if (Error) {
429+
ContextRef->lastError = *Error;
430+
return ContextRef->lastError.c_str();
431+
}
432+
return nullptr;
433+
}
434+
425435
swift_typeinfo_t
426436
swift_reflection_infoForTypeRef(SwiftReflectionContextRef ContextRef,
427437
swift_typeref_t OpaqueTypeRef) {
@@ -585,31 +595,33 @@ size_t swift_reflection_demangle(const char *MangledName, size_t Length,
585595
return Demangled.size();
586596
}
587597

588-
int swift_reflection_iterateConformanceCache(
598+
const char *swift_reflection_iterateConformanceCache(
589599
SwiftReflectionContextRef ContextRef,
590600
void (*Call)(swift_reflection_ptr_t Type,
591601
swift_reflection_ptr_t Proto,
592602
void *ContextPtr),
593603
void *ContextPtr) {
594604
auto Context = ContextRef->nativeContext;
595-
return Context->iterateConformances([&](auto Type, auto Proto) {
605+
auto Error = Context->iterateConformances([&](auto Type, auto Proto) {
596606
Call(Type, Proto, ContextPtr);
597607
});
608+
return convertError(ContextRef, Error);
598609
}
599610

600-
int swift_reflection_iterateMetadataAllocations(
611+
const char *swift_reflection_iterateMetadataAllocations(
601612
SwiftReflectionContextRef ContextRef,
602613
void (*Call)(swift_metadata_allocation_t Allocation,
603614
void *ContextPtr),
604615
void *ContextPtr) {
605616
auto Context = ContextRef->nativeContext;
606-
return Context->iterateMetadataAllocations([&](auto Allocation) {
617+
auto Error = Context->iterateMetadataAllocations([&](auto Allocation) {
607618
swift_metadata_allocation CAllocation;
608619
CAllocation.Tag = Allocation.Tag;
609620
CAllocation.Ptr = Allocation.Ptr;
610621
CAllocation.Size = Allocation.Size;
611622
Call(CAllocation, ContextPtr);
612623
});
624+
return convertError(ContextRef, Error);
613625
}
614626

615627
SWIFT_REMOTE_MIRROR_LINKAGE

tools/swiftdt/RemoteMirrorExtensions.swift

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
import SwiftRemoteMirror
22

33
extension SwiftReflectionContextRef {
4+
struct Error: Swift.Error {
5+
var description: String
6+
7+
init(cString: UnsafePointer<CChar>) {
8+
description = String(cString: cString)
9+
}
10+
}
11+
412
func name(metadata: swift_reflection_ptr_t) -> String? {
513
let tr = swift_reflection_typeRefForMetadata(self, UInt(metadata));
614
guard tr != 0 else { return nil }
@@ -19,28 +27,36 @@ extension SwiftReflectionContextRef {
1927
}
2028

2129
func iterateConformanceCache(
22-
call: (swift_reflection_ptr_t, swift_reflection_ptr_t) -> Void) -> Bool {
30+
call: (swift_reflection_ptr_t, swift_reflection_ptr_t) -> Void) throws {
2331
var call = call
24-
let success = swift_reflection_iterateConformanceCache(self, {
25-
let callPtr = $2!.bindMemory(to: ((swift_reflection_ptr_t, swift_reflection_ptr_t) -> Void).self, capacity: 1)
32+
let errStr = swift_reflection_iterateConformanceCache(self, {
33+
let callPtr = $2!.bindMemory(to:
34+
((swift_reflection_ptr_t, swift_reflection_ptr_t) -> Void).self,
35+
capacity: 1)
2636
callPtr.pointee($0, $1)
2737
}, &call)
28-
return success != 0
38+
try throwError(str: errStr)
2939
}
3040

31-
func iterateMetadataAllocations(call: (swift_metadata_allocation_t) -> Void)
32-
-> Bool {
41+
func iterateMetadataAllocations(
42+
call: (swift_metadata_allocation_t) -> Void) throws {
3343
var call = call
34-
let success = swift_reflection_iterateMetadataAllocations(self, {
44+
let errStr = swift_reflection_iterateMetadataAllocations(self, {
3545
let callPtr = $1!.bindMemory(to:
3646
((swift_metadata_allocation_t) -> Void).self, capacity: 1)
3747
callPtr.pointee($0)
3848
}, &call)
39-
return success != 0
49+
try throwError(str: errStr)
4050
}
4151

4252
func metadataPointer(allocation: swift_metadata_allocation_t)
4353
-> swift_reflection_ptr_t {
4454
return swift_reflection_allocationMetadataPointer(self, allocation)
4555
}
56+
57+
private func throwError(str: UnsafePointer<CChar>?) throws {
58+
if let str = str {
59+
throw Error(cString: str)
60+
}
61+
}
4662
}

tools/swiftdt/main.swift

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ guard let executableName = argv.popFirst() else {
2222
struct Command {
2323
var name: String
2424
var help: String
25-
var call: (inout ArraySlice<String>) -> Void
25+
var call: (inout ArraySlice<String>) throws -> Void
2626

2727
init(name: String, help: String,
2828
call: @escaping (inout ArraySlice<String>) -> Void) {
@@ -32,10 +32,10 @@ struct Command {
3232
}
3333

3434
init(name: String, help: String,
35-
call: @escaping (SwiftReflectionContextRef) -> Void) {
35+
call: @escaping (SwiftReflectionContextRef) throws -> Void) {
3636
self.name = name
3737
self.help = help
38-
self.call = { withReflectionContext(args: &$0, call: call) }
38+
self.call = { try withReflectionContext(args: &$0, call: call) }
3939
}
4040
}
4141

@@ -54,21 +54,18 @@ let commands = [
5454
call: printUsage),
5555
]
5656

57-
func dumpConformanceCache(context: SwiftReflectionContextRef) {
58-
let success = context.iterateConformanceCache(call: { type, proto in
57+
func dumpConformanceCache(context: SwiftReflectionContextRef) throws {
58+
try context.iterateConformanceCache(call: { type, proto in
5959
let typeName = context.name(metadata: type) ?? "<unknown>"
6060
let protoName = context.name(proto: proto) ?? "<unknown>"
6161
print("Conformance: \(typeName): \(protoName)")
6262
})
63-
if !success {
64-
print("Error!")
65-
}
6663
}
6764

68-
func dumpMetadataAllocations(context: SwiftReflectionContextRef) {
65+
func dumpMetadataAllocations(context: SwiftReflectionContextRef) throws {
6966
var allocations: [swift_metadata_allocation_t] = []
7067
var metadatas: [swift_reflection_ptr_t] = []
71-
let success = context.iterateMetadataAllocations(call: { allocation in
68+
try context.iterateMetadataAllocations(call: { allocation in
7269
allocations.append(allocation)
7370
print("Metadata allocation at: \(hex: allocation.Ptr) " +
7471
"size: \(allocation.Size) tag: \(allocation.Tag)")
@@ -77,10 +74,6 @@ func dumpMetadataAllocations(context: SwiftReflectionContextRef) {
7774
metadatas.append(ptr)
7875
}
7976
})
80-
if !success {
81-
print("Error!")
82-
return
83-
}
8477

8578
allocations.sort(by: { $0.Ptr < $1.Ptr })
8679
for metadata in metadatas {
@@ -138,18 +131,28 @@ func makeReflectionContext(args: inout ArraySlice<String>)
138131
return (inspector, reflectionContext)
139132
}
140133

141-
func withReflectionContext(args: inout ArraySlice<String>,
142-
call: (SwiftReflectionContextRef) -> Void) {
134+
func withReflectionContext(
135+
args: inout ArraySlice<String>,
136+
call: (SwiftReflectionContextRef) throws -> Void) throws {
143137
let (inspector, context) = makeReflectionContext(args: &args)
144-
call(context)
145-
swift_reflection_destroyReflectionContext(context)
146-
inspector.destroyContext()
138+
defer {
139+
swift_reflection_destroyReflectionContext(context)
140+
inspector.destroyContext()
141+
}
142+
try call(context)
147143
}
148144

149145
let commandName = argv.popFirst()
150146
for command in commands {
151147
if command.name == commandName {
152-
command.call(&argv)
148+
do {
149+
try command.call(&argv)
150+
} catch let error as SwiftReflectionContextRef.Error {
151+
print("Error: \(error.description)", to: &Std.err)
152+
exit(1)
153+
} catch {
154+
print("Unknown error: \(error)")
155+
}
153156
exit(0)
154157
}
155158
}

0 commit comments

Comments
 (0)