Skip to content

Commit 553ef86

Browse files
committed
[RemoteMirrors] Change MemoryReader::readBytes to return a unique_ptr instead of a tuple so that the destructor handles freeing the memory.
1 parent 1434fce commit 553ef86

File tree

5 files changed

+55
-76
lines changed

5 files changed

+55
-76
lines changed

include/swift/Reflection/ReflectionContext.h

Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <set>
3535
#include <vector>
3636
#include <unordered_map>
37+
#include <utility>
3738

3839
#if defined(__APPLE__) && defined(__MACH__)
3940
#ifndef __LP64__
@@ -75,7 +76,9 @@ class ReflectionContext
7576

7677
std::unordered_map<typename super::StoredPointer, const TypeInfo *> Cache;
7778

78-
std::vector<std::function<void()>> freeFuncs;
79+
/// All buffers we need to keep around long term. This will automatically free them
80+
/// when this object is destroyed.
81+
std::vector<MemoryReader::ReadBytesResult> savedBuffers;
7982
std::vector<std::tuple<RemoteAddress, RemoteAddress>> dataSegments;
8083

8184
public:
@@ -95,11 +98,6 @@ class ReflectionContext
9598
ReflectionContext(const ReflectionContext &other) = delete;
9699
ReflectionContext &operator=(const ReflectionContext &other) = delete;
97100

98-
~ReflectionContext() {
99-
for (auto f : freeFuncs)
100-
f();
101-
}
102-
103101
MemoryReader &getReader() {
104102
return *this->Reader;
105103
}
@@ -115,50 +113,38 @@ class ReflectionContext
115113

116114
#if defined(__APPLE__) && defined(__MACH__)
117115
bool addImage(RemoteAddress ImageStart) {
118-
const void *Buf;
119-
std::function<void()> FreeFunc;
120-
121-
std::tie(Buf, FreeFunc) =
122-
this->getReader().readBytes(ImageStart, sizeof(MachHeader));
123-
if (Buf == nullptr)
116+
auto Buf = this->getReader().readBytes(ImageStart, sizeof(MachHeader));
117+
if (!Buf)
124118
return false;
125119

126-
auto Header = reinterpret_cast<MachHeader *>(Buf);
127-
120+
auto Header = reinterpret_cast<MachHeader *>(Buf.get());
128121
if (Header->magic != MH_MAGIC && Header->magic != MH_MAGIC_64) {
129-
FreeFunc();
130122
return false;
131123
}
132-
133124
auto Length = Header->sizeofcmds;
134-
FreeFunc();
135125

136126
// Read the commands.
137-
std::tie(Buf, FreeFunc) = this->getReader().readBytes(ImageStart, Length);
138-
139-
if (Buf == nullptr)
127+
Buf = this->getReader().readBytes(ImageStart, Length);
128+
if (!Buf)
140129
return false;
141130

142131
// Find the TEXT segment and figure out where the end is.
143-
Header = reinterpret_cast<MachHeader *>(Buf);
132+
Header = reinterpret_cast<MachHeader *>(Buf.get());
144133
unsigned long TextSize;
145134
auto *TextSegment = getsegmentdata(Header, "__TEXT", &TextSize);
146-
if (TextSegment == nullptr) {
147-
FreeFunc();
135+
if (TextSegment == nullptr)
148136
return false;
149-
}
137+
150138
auto TextEnd =
151-
TextSegment - reinterpret_cast<const uint8_t *>(Buf) + TextSize;
152-
FreeFunc();
139+
TextSegment - reinterpret_cast<const uint8_t *>(Buf.get()) + TextSize;
153140

154141
// Read everything including the TEXT segment.
155-
std::tie(Buf, FreeFunc) = this->getReader().readBytes(ImageStart, TextEnd);
156-
157-
if (Buf == nullptr)
142+
Buf = this->getReader().readBytes(ImageStart, TextEnd);
143+
if (!Buf)
158144
return false;
159145

160146
// Read all the metadata parts.
161-
Header = reinterpret_cast<MachHeader *>(Buf);
147+
Header = reinterpret_cast<MachHeader *>(Buf.get());
162148

163149
// The docs say "not all sections may be present." We'll succeed if ANY of
164150
// them are present. Not sure if that's the right thing to do.
@@ -173,12 +159,10 @@ class ReflectionContext
173159

174160
bool success = FieldMd.second || AssocTyMd.second || BuiltinTyMd.second ||
175161
CaptureMd.second || TyperefMd.second || ReflStrMd.second;
176-
if (!success) {
177-
FreeFunc();
178-
return 0;
179-
}
162+
if (!success)
163+
return false;
180164

181-
auto LocalStartAddress = reinterpret_cast<uintptr_t>(Buf);
165+
auto LocalStartAddress = reinterpret_cast<uintptr_t>(Buf.get());
182166
auto RemoteStartAddress =
183167
reinterpret_cast<uint64_t>(ImageStart.getAddressData());
184168

@@ -194,17 +178,18 @@ class ReflectionContext
194178

195179
this->addReflectionInfo(info);
196180

197-
freeFuncs.push_back(FreeFunc);
198-
199181
unsigned long DataSize;
200182
auto *DataSegment = getsegmentdata(Header, "__DATA", &DataSize);
201183
if (DataSegment != nullptr) {
202-
auto DataSegmentStart = DataSegment - reinterpret_cast<const uint8_t *>(Buf)
184+
auto DataSegmentStart = DataSegment - reinterpret_cast<const uint8_t *>(Buf.get())
203185
+ ImageStart.getAddressData();
204186
auto DataSegmentEnd = DataSegmentStart + DataSize;
205187
dataSegments.push_back(std::make_tuple(RemoteAddress(DataSegmentStart),
206188
RemoteAddress(DataSegmentEnd)));
207189
}
190+
191+
savedBuffers.push_back(std::move(Buf));
192+
208193
return true;
209194
}
210195
#endif // defined(__APPLE__) && defined(__MACH__)

include/swift/Remote/CMemoryReader.h

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,31 +62,26 @@ class CMemoryReader final : public MemoryReader {
6262
if (!length)
6363
return false;
6464

65-
const void *ptr;
66-
std::function<void()> freeFunc;
67-
std::tie(ptr, freeFunc) = readBytes(address, length);
68-
if (ptr != nullptr) {
69-
dest = std::string(reinterpret_cast<const char *>(ptr), length);
70-
freeFunc();
71-
return true;
72-
} else {
65+
auto Buf = readBytes(address, length);
66+
if (!Buf)
7367
return false;
74-
}
68+
69+
dest = std::string(reinterpret_cast<const char *>(Buf.get()), length);
70+
return true;
7571
}
7672

77-
std::tuple<const void *, std::function<void()>>
78-
readBytes(RemoteAddress address, uint64_t size) override {
73+
ReadBytesResult readBytes(RemoteAddress address, uint64_t size) override {
7974
void *FreeContext;
8075
auto Ptr = Impl.readBytes(Impl.reader_context, address.getAddressData(), size,
8176
&FreeContext);
8277

8378
auto Free = Impl.free;
8479
if (Free == nullptr)
85-
return std::make_tuple(Ptr, []{});
80+
return ReadBytesResult(Ptr, [](const void *) {});
8681

8782
auto ReaderContext = Impl.reader_context;
88-
auto freeLambda = [=]{ Free(ReaderContext, Ptr, FreeContext); };
89-
return std::make_tuple(Ptr, freeLambda);
83+
auto freeLambda = [=](const void *Ptr) { Free(ReaderContext, Ptr, FreeContext); };
84+
return ReadBytesResult(Ptr, freeLambda);
9085
}
9186
};
9287

include/swift/Remote/InProcessMemoryReader.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,8 @@ class InProcessMemoryReader final : public MemoryReader {
4242
return true;
4343
}
4444

45-
std::tuple<const void *, std::function<void()>>
46-
readBytes(RemoteAddress address, uint64_t size) override {
47-
return std::make_tuple(address.getLocalPointer<void>(), []{});
45+
ReadBytesResult readBytes(RemoteAddress address, uint64_t size) override {
46+
return ReadBytesResult(address.getLocalPointer<void>(), [](const void *) {});
4847
}
4948
};
5049

include/swift/Remote/MemoryReader.h

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "swift/Remote/RemoteAddress.h"
2222

2323
#include <functional>
24+
#include <memory>
2425
#include <string>
2526
#include <tuple>
2627

@@ -33,6 +34,9 @@ namespace remote {
3334
/// representation of the address space of a remote process.
3435
class MemoryReader {
3536
public:
37+
/// A convenient name for the return type from readBytes.
38+
using ReadBytesResult = std::unique_ptr<const void, std::function<void(const void *)>>;
39+
3640
/// Return the size of an ordinary pointer in the remote process, in bytes.
3741
virtual uint8_t getPointerSize() = 0;
3842

@@ -47,7 +51,7 @@ class MemoryReader {
4751
///
4852
/// Returns false if the operation failed.
4953
virtual bool readString(RemoteAddress address, std::string &dest) = 0;
50-
54+
5155
/// Attempts to read an integer from the given address in the remote
5256
/// process.
5357
///
@@ -65,15 +69,17 @@ class MemoryReader {
6569
///
6670
/// NOTE: subclasses MUST override at least one of the readBytes functions. The default
6771
/// implementation calls through to the other one.
68-
virtual std::tuple<const void *, std::function<void()>>
72+
virtual ReadBytesResult
6973
readBytes(RemoteAddress address, uint64_t size) {
70-
void *buffer = malloc(size);
71-
bool success = readBytes(address, reinterpret_cast<uint8_t *>(buffer), size);
74+
auto *Buf = malloc(size);
75+
ReadBytesResult Result(Buf, [](const void *ptr) {
76+
free(const_cast<void *>(ptr));
77+
});
78+
bool success = readBytes(address, reinterpret_cast<uint8_t *>(Buf), size);
7279
if (!success) {
73-
free(buffer);
74-
return std::make_tuple(nullptr, []{});
80+
Result.reset();
7581
}
76-
return std::make_tuple(buffer, [=]{ free(buffer); });
82+
return Result;
7783
}
7884

7985
/// Attempts to read 'size' bytes from the given address in the
@@ -84,16 +90,12 @@ class MemoryReader {
8490
/// NOTE: subclasses MUST override at least one of the readBytes functions. The default
8591
/// implementation calls through to the other one.
8692
virtual bool readBytes(RemoteAddress address, uint8_t *dest, uint64_t size) {
87-
const void *ptr;
88-
std::function<void()> freeFunc;
89-
std::tie(ptr, freeFunc) = readBytes(address, size);
90-
if (ptr != nullptr) {
91-
memcpy(dest, ptr, size);
92-
freeFunc();
93-
return true;
94-
} else {
93+
auto Ptr = readBytes(address, size);
94+
if (!Ptr)
9595
return false;
96-
}
96+
97+
memcpy(dest, Ptr.get(), size);
98+
return true;
9799
}
98100

99101
virtual ~MemoryReader() = default;

tools/swift-reflection-dump/swift-reflection-dump.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -196,14 +196,12 @@ class ObjectMemoryReader : public MemoryReader {
196196
return false;
197197
}
198198

199-
std::tuple<const void *, std::function<void()>>
200-
readBytes(RemoteAddress address, uint64_t size) override {
199+
ReadBytesResult readBytes(RemoteAddress address, uint64_t size) override {
201200
if (!isAddressValid(address, size))
202-
return std::make_tuple(nullptr, []{});
201+
return ReadBytesResult(nullptr, [](const void *){});
203202

204203
// TODO: Account for offset in ELF binaries
205-
auto ptr = (const void *)address.getAddressData();
206-
return std::make_tuple(ptr, []{});
204+
return ReadBytesResult((const void *)address.getAddressData(), [](const void *) {});
207205
}
208206

209207
bool readString(RemoteAddress address, std::string &dest) override {

0 commit comments

Comments
 (0)