Skip to content

Commit 70f94e1

Browse files
committed
Cherry-pick llvm only changes from minidump multiple exceptions PR.
1 parent 52dc491 commit 70f94e1

File tree

3 files changed

+64
-8
lines changed

3 files changed

+64
-8
lines changed

llvm/include/llvm/Object/Minidump.h

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,25 @@ class MinidumpFile : public Binary {
8383
return getListStream<minidump::Thread>(minidump::StreamType::ThreadList);
8484
}
8585

86-
/// Returns the contents of the Exception stream. An error is returned if the
87-
/// file does not contain this stream, or the stream is smaller than the size
88-
/// of the ExceptionStream structure. The internal consistency of the stream
89-
/// is not checked in any way.
90-
Expected<const minidump::ExceptionStream &> getExceptionStream() const {
91-
return getStream<minidump::ExceptionStream>(
92-
minidump::StreamType::Exception);
86+
/// Returns the contents of the Exception stream. An error is returned if the
87+
/// associated stream is smaller than the size of the ExceptionStream
88+
/// structure. Or the directory supplied is not of kind exception stream.
89+
Expected<const minidump::ExceptionStream &>
90+
getExceptionStream(minidump::Directory Directory) const {
91+
if (Directory.Type != minidump::StreamType::Exception) {
92+
return createError("Not an exception stream");
93+
}
94+
95+
return getStreamFromDirectory<minidump::ExceptionStream>(Directory);
9396
}
9497

98+
/// Returns the contents of the Exception streams. An error is returned if
99+
/// any of the streams are smaller than the size of the ExceptionStream
100+
/// structure. The internal consistency of the stream is not checked in any
101+
/// way.
102+
Expected<std::vector<const minidump::ExceptionStream *>>
103+
getExceptionStreams() const;
104+
95105
/// Returns the list of descriptors embedded in the MemoryList stream. The
96106
/// descriptors provide the content of interesting regions of memory at the
97107
/// time the minidump was taken. An error is returned if the file does not
@@ -264,6 +274,12 @@ class MinidumpFile : public Binary {
264274
return arrayRefFromStringRef(Data.getBuffer());
265275
}
266276

277+
/// Return the stream of the given type, cast to the appropriate type. Checks
278+
/// that the stream is large enough to hold an object of this type.
279+
template <typename T>
280+
Expected<const T &>
281+
getStreamFromDirectory(minidump::Directory Directory) const;
282+
267283
/// Return the stream of the given type, cast to the appropriate type. Checks
268284
/// that the stream is large enough to hold an object of this type.
269285
template <typename T>
@@ -279,6 +295,15 @@ class MinidumpFile : public Binary {
279295
DenseMap<minidump::StreamType, std::size_t> StreamMap;
280296
};
281297

298+
template <typename T>
299+
Expected<const T &>
300+
MinidumpFile::getStreamFromDirectory(minidump::Directory Directory) const {
301+
ArrayRef<uint8_t> Stream = getRawStream(Directory);
302+
if (Stream.size() >= sizeof(T))
303+
return *reinterpret_cast<const T *>(Stream.data());
304+
return createEOFError();
305+
}
306+
282307
template <typename T>
283308
Expected<const T &> MinidumpFile::getStream(minidump::StreamType Type) const {
284309
if (std::optional<ArrayRef<uint8_t>> Stream = getRawStream(Type)) {

llvm/lib/Object/Minidump.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,27 @@ Expected<std::string> MinidumpFile::getString(size_t Offset) const {
5353
return Result;
5454
}
5555

56+
Expected<std::vector<const minidump::ExceptionStream *>>
57+
MinidumpFile::getExceptionStreams() const {
58+
59+
std::vector<const minidump::ExceptionStream *> exceptionStreamList;
60+
for (const auto &directory : Streams) {
61+
if (directory.Type == StreamType::Exception) {
62+
llvm::Expected<minidump::ExceptionStream *> ExpectedStream =
63+
getStreamFromDirectory<minidump::ExceptionStream *>(directory);
64+
if (!ExpectedStream)
65+
return ExpectedStream.takeError();
66+
67+
exceptionStreamList.push_back(ExpectedStream.get());
68+
}
69+
}
70+
71+
if (exceptionStreamList.empty())
72+
return createError("No exception streams found");
73+
74+
return exceptionStreamList;
75+
}
76+
5677
Expected<iterator_range<MinidumpFile::MemoryInfoIterator>>
5778
MinidumpFile::getMemoryInfoList() const {
5879
std::optional<ArrayRef<uint8_t>> Stream =
@@ -128,6 +149,7 @@ MinidumpFile::create(MemoryBufferRef Source) {
128149
return ExpectedStreams.takeError();
129150

130151
DenseMap<StreamType, std::size_t> StreamMap;
152+
std::vector<std::size_t> ExceptionStreams;
131153
for (const auto &StreamDescriptor : llvm::enumerate(*ExpectedStreams)) {
132154
StreamType Type = StreamDescriptor.value().Type;
133155
const LocationDescriptor &Loc = StreamDescriptor.value().Location;
@@ -143,6 +165,15 @@ MinidumpFile::create(MemoryBufferRef Source) {
143165
continue;
144166
}
145167

168+
// We treat exceptions differently here because the LLDB minidump
169+
// makes some assumptions about uniqueness, all the streams other than
170+
// exceptions are lists. But exceptions are not a list, they are single
171+
// streams that point back to their thread So we will omit them here, and
172+
// will find them when needed in the MinidumpFile.
173+
if (Type == StreamType::Exception) {
174+
continue;
175+
}
176+
146177
if (Type == DenseMapInfo<StreamType>::getEmptyKey() ||
147178
Type == DenseMapInfo<StreamType>::getTombstoneKey())
148179
return createError("Cannot handle one of the minidump streams");

llvm/lib/ObjectYAML/MinidumpYAML.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ Stream::create(const Directory &StreamDesc, const object::MinidumpFile &File) {
499499
switch (Kind) {
500500
case StreamKind::Exception: {
501501
Expected<const minidump::ExceptionStream &> ExpectedExceptionStream =
502-
File.getExceptionStream();
502+
File.getExceptionStream(StreamDesc);
503503
if (!ExpectedExceptionStream)
504504
return ExpectedExceptionStream.takeError();
505505
Expected<ArrayRef<uint8_t>> ExpectedThreadContext =

0 commit comments

Comments
 (0)