LLDB  mainline
MinidumpParser.cpp
Go to the documentation of this file.
1 //===-- MinidumpParser.cpp ---------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "MinidumpParser.h"
10 #include "NtStructures.h"
12 
15 #include "lldb/Utility/Log.h"
16 
17 // C includes
18 // C++ includes
19 #include <algorithm>
20 #include <map>
21 #include <vector>
22 #include <utility>
23 
24 using namespace lldb_private;
25 using namespace minidump;
26 
27 llvm::Expected<MinidumpParser>
28 MinidumpParser::Create(const lldb::DataBufferSP &data_sp) {
29  auto ExpectedFile = llvm::object::MinidumpFile::create(
30  llvm::MemoryBufferRef(toStringRef(data_sp->GetData()), "minidump"));
31  if (!ExpectedFile)
32  return ExpectedFile.takeError();
33 
34  return MinidumpParser(data_sp, std::move(*ExpectedFile));
35 }
36 
37 MinidumpParser::MinidumpParser(lldb::DataBufferSP data_sp,
38  std::unique_ptr<llvm::object::MinidumpFile> file)
39  : m_data_sp(std::move(data_sp)), m_file(std::move(file)) {}
40 
41 llvm::ArrayRef<uint8_t> MinidumpParser::GetData() {
42  return llvm::ArrayRef<uint8_t>(m_data_sp->GetBytes(),
43  m_data_sp->GetByteSize());
44 }
45 
46 llvm::ArrayRef<uint8_t> MinidumpParser::GetStream(StreamType stream_type) {
47  return m_file->getRawStream(stream_type)
48  .getValueOr(llvm::ArrayRef<uint8_t>());
49 }
50 
51 UUID MinidumpParser::GetModuleUUID(const minidump::Module *module) {
52  auto cv_record =
53  GetData().slice(module->CvRecord.RVA, module->CvRecord.DataSize);
54 
55  // Read the CV record signature
56  const llvm::support::ulittle32_t *signature = nullptr;
57  Status error = consumeObject(cv_record, signature);
58  if (error.Fail())
59  return UUID();
60 
61  const CvSignature cv_signature =
62  static_cast<CvSignature>(static_cast<uint32_t>(*signature));
63 
64  if (cv_signature == CvSignature::Pdb70) {
65  const CvRecordPdb70 *pdb70_uuid = nullptr;
66  Status error = consumeObject(cv_record, pdb70_uuid);
67  if (error.Fail())
68  return UUID();
69 
70  CvRecordPdb70 swapped;
71  if (!GetArchitecture().GetTriple().isOSBinFormatELF()) {
72  // LLDB's UUID class treats the data as a sequence of bytes, but breakpad
73  // interprets it as a sequence of little-endian fields, which it converts
74  // to big-endian when converting to text. Swap the bytes to big endian so
75  // that the string representation comes out right.
76  swapped = *pdb70_uuid;
77  llvm::sys::swapByteOrder(swapped.Uuid.Data1);
78  llvm::sys::swapByteOrder(swapped.Uuid.Data2);
79  llvm::sys::swapByteOrder(swapped.Uuid.Data3);
80  llvm::sys::swapByteOrder(swapped.Age);
81  pdb70_uuid = &swapped;
82  }
83  if (pdb70_uuid->Age != 0)
84  return UUID::fromOptionalData(pdb70_uuid, sizeof(*pdb70_uuid));
85  return UUID::fromOptionalData(&pdb70_uuid->Uuid, sizeof(pdb70_uuid->Uuid));
86  } else if (cv_signature == CvSignature::ElfBuildId)
87  return UUID::fromOptionalData(cv_record);
88 
89  return UUID();
90 }
91 
92 llvm::ArrayRef<MinidumpThread> MinidumpParser::GetThreads() {
93  llvm::ArrayRef<uint8_t> data = GetStream(StreamType::ThreadList);
94 
95  if (data.size() == 0)
96  return llvm::None;
97 
99 }
100 
101 llvm::ArrayRef<uint8_t>
102 MinidumpParser::GetThreadContext(const LocationDescriptor &location) {
103  if (location.RVA + location.DataSize > GetData().size())
104  return {};
105  return GetData().slice(location.RVA, location.DataSize);
106 }
107 
108 llvm::ArrayRef<uint8_t>
110  return GetThreadContext(td.thread_context);
111 }
112 
113 llvm::ArrayRef<uint8_t>
115  // On Windows, a 32-bit process can run on a 64-bit machine under WOW64. If
116  // the minidump was captured with a 64-bit debugger, then the CONTEXT we just
117  // grabbed from the mini_dump_thread is the one for the 64-bit "native"
118  // process rather than the 32-bit "guest" process we care about. In this
119  // case, we can get the 32-bit CONTEXT from the TEB (Thread Environment
120  // Block) of the 64-bit process.
121  auto teb_mem = GetMemory(td.teb, sizeof(TEB64));
122  if (teb_mem.empty())
123  return {};
124 
125  const TEB64 *wow64teb;
126  Status error = consumeObject(teb_mem, wow64teb);
127  if (error.Fail())
128  return {};
129 
130  // Slot 1 of the thread-local storage in the 64-bit TEB points to a structure
131  // that includes the 32-bit CONTEXT (after a ULONG). See:
132  // https://msdn.microsoft.com/en-us/library/ms681670.aspx
133  auto context =
134  GetMemory(wow64teb->tls_slots[1] + 4, sizeof(MinidumpContext_x86_32));
135  if (context.size() < sizeof(MinidumpContext_x86_32))
136  return {};
137 
138  return context;
139  // NOTE: We don't currently use the TEB for anything else. If we
140  // need it in the future, the 32-bit TEB is located according to the address
141  // stored in the first slot of the 64-bit TEB (wow64teb.Reserved1[0]).
142 }
143 
145  if (m_arch.IsValid())
146  return m_arch;
147 
148  // Set the architecture in m_arch
149  llvm::Expected<const SystemInfo &> system_info = m_file->getSystemInfo();
150 
151  if (!system_info) {
153  system_info.takeError(),
154  "Failed to read SystemInfo stream: {0}");
155  return m_arch;
156  }
157 
158  // TODO what to do about big endiand flavors of arm ?
159  // TODO set the arm subarch stuff if the minidump has info about it
160 
161  llvm::Triple triple;
162  triple.setVendor(llvm::Triple::VendorType::UnknownVendor);
163 
164  switch (system_info->ProcessorArch) {
165  case ProcessorArchitecture::X86:
166  triple.setArch(llvm::Triple::ArchType::x86);
167  break;
168  case ProcessorArchitecture::AMD64:
169  triple.setArch(llvm::Triple::ArchType::x86_64);
170  break;
171  case ProcessorArchitecture::ARM:
172  triple.setArch(llvm::Triple::ArchType::arm);
173  break;
174  case ProcessorArchitecture::ARM64:
175  triple.setArch(llvm::Triple::ArchType::aarch64);
176  break;
177  default:
178  triple.setArch(llvm::Triple::ArchType::UnknownArch);
179  break;
180  }
181 
182  // TODO add all of the OSes that Minidump/breakpad distinguishes?
183  switch (system_info->PlatformId) {
184  case OSPlatform::Win32S:
185  case OSPlatform::Win32Windows:
186  case OSPlatform::Win32NT:
187  case OSPlatform::Win32CE:
188  triple.setOS(llvm::Triple::OSType::Win32);
189  break;
190  case OSPlatform::Linux:
191  triple.setOS(llvm::Triple::OSType::Linux);
192  break;
193  case OSPlatform::MacOSX:
194  triple.setOS(llvm::Triple::OSType::MacOSX);
195  triple.setVendor(llvm::Triple::Apple);
196  break;
197  case OSPlatform::IOS:
198  triple.setOS(llvm::Triple::OSType::IOS);
199  triple.setVendor(llvm::Triple::Apple);
200  break;
201  case OSPlatform::Android:
202  triple.setOS(llvm::Triple::OSType::Linux);
203  triple.setEnvironment(llvm::Triple::EnvironmentType::Android);
204  break;
205  default: {
206  triple.setOS(llvm::Triple::OSType::UnknownOS);
207  auto ExpectedCSD = m_file->getString(system_info->CSDVersionRVA);
208  if (!ExpectedCSD) {
210  ExpectedCSD.takeError(),
211  "Failed to CSD Version string: {0}");
212  } else {
213  if (ExpectedCSD->find("Linux") != std::string::npos)
214  triple.setOS(llvm::Triple::OSType::Linux);
215  }
216  break;
217  }
218  }
219  m_arch.SetTriple(triple);
220  return m_arch;
221 }
222 
224  llvm::ArrayRef<uint8_t> data = GetStream(StreamType::MiscInfo);
225 
226  if (data.size() == 0)
227  return nullptr;
228 
229  return MinidumpMiscInfo::Parse(data);
230 }
231 
232 llvm::Optional<LinuxProcStatus> MinidumpParser::GetLinuxProcStatus() {
233  llvm::ArrayRef<uint8_t> data = GetStream(StreamType::LinuxProcStatus);
234 
235  if (data.size() == 0)
236  return llvm::None;
237 
238  return LinuxProcStatus::Parse(data);
239 }
240 
241 llvm::Optional<lldb::pid_t> MinidumpParser::GetPid() {
242  const MinidumpMiscInfo *misc_info = GetMiscInfo();
243  if (misc_info != nullptr) {
244  return misc_info->GetPid();
245  }
246 
247  llvm::Optional<LinuxProcStatus> proc_status = GetLinuxProcStatus();
248  if (proc_status.hasValue()) {
249  return proc_status->GetPid();
250  }
251 
252  return llvm::None;
253 }
254 
255 llvm::ArrayRef<minidump::Module> MinidumpParser::GetModuleList() {
256  auto ExpectedModules = GetMinidumpFile().getModuleList();
257  if (ExpectedModules)
258  return *ExpectedModules;
259 
261  ExpectedModules.takeError(),
262  "Failed to read module list: {0}");
263  return {};
264 }
265 
266 std::vector<const minidump::Module *> MinidumpParser::GetFilteredModuleList() {
268  auto ExpectedModules = GetMinidumpFile().getModuleList();
269  if (!ExpectedModules) {
270  LLDB_LOG_ERROR(log, ExpectedModules.takeError(),
271  "Failed to read module list: {0}");
272  return {};
273  }
274 
275  // map module_name -> filtered_modules index
276  typedef llvm::StringMap<size_t> MapType;
277  MapType module_name_to_filtered_index;
278 
279  std::vector<const minidump::Module *> filtered_modules;
280 
281  for (const auto &module : *ExpectedModules) {
282  auto ExpectedName = m_file->getString(module.ModuleNameRVA);
283  if (!ExpectedName) {
284  LLDB_LOG_ERROR(log, ExpectedName.takeError(),
285  "Failed to module name: {0}");
286  continue;
287  }
288 
289  MapType::iterator iter;
290  bool inserted;
291  // See if we have inserted this module aready into filtered_modules. If we
292  // haven't insert an entry into module_name_to_filtered_index with the
293  // index where we will insert it if it isn't in the vector already.
294  std::tie(iter, inserted) = module_name_to_filtered_index.try_emplace(
295  *ExpectedName, filtered_modules.size());
296 
297  if (inserted) {
298  // This module has not been seen yet, insert it into filtered_modules at
299  // the index that was inserted into module_name_to_filtered_index using
300  // "filtered_modules.size()" above.
301  filtered_modules.push_back(&module);
302  } else {
303  // This module has been seen. Modules are sometimes mentioned multiple
304  // times when they are mapped discontiguously, so find the module with
305  // the lowest "base_of_image" and use that as the filtered module.
306  auto dup_module = filtered_modules[iter->second];
307  if (module.BaseOfImage < dup_module->BaseOfImage)
308  filtered_modules[iter->second] = &module;
309  }
310  }
311  return filtered_modules;
312 }
313 
315  llvm::ArrayRef<uint8_t> data = GetStream(StreamType::Exception);
316 
317  if (data.size() == 0)
318  return nullptr;
319 
320  return MinidumpExceptionStream::Parse(data);
321 }
322 
323 llvm::Optional<minidump::Range>
325  llvm::ArrayRef<uint8_t> data = GetStream(StreamType::MemoryList);
326  llvm::ArrayRef<uint8_t> data64 = GetStream(StreamType::Memory64List);
327 
328  if (data.empty() && data64.empty())
329  return llvm::None;
330 
331  if (!data.empty()) {
332  llvm::ArrayRef<MinidumpMemoryDescriptor> memory_list =
334 
335  if (memory_list.empty())
336  return llvm::None;
337 
338  for (const auto &memory_desc : memory_list) {
339  const LocationDescriptor &loc_desc = memory_desc.memory;
340  const lldb::addr_t range_start = memory_desc.start_of_memory_range;
341  const size_t range_size = loc_desc.DataSize;
342 
343  if (loc_desc.RVA + loc_desc.DataSize > GetData().size())
344  return llvm::None;
345 
346  if (range_start <= addr && addr < range_start + range_size) {
347  return minidump::Range(range_start,
348  GetData().slice(loc_desc.RVA, range_size));
349  }
350  }
351  }
352 
353  // Some Minidumps have a Memory64ListStream that captures all the heap memory
354  // (full-memory Minidumps). We can't exactly use the same loop as above,
355  // because the Minidump uses slightly different data structures to describe
356  // those
357 
358  if (!data64.empty()) {
359  llvm::ArrayRef<MinidumpMemoryDescriptor64> memory64_list;
360  uint64_t base_rva;
361  std::tie(memory64_list, base_rva) =
363 
364  if (memory64_list.empty())
365  return llvm::None;
366 
367  for (const auto &memory_desc64 : memory64_list) {
368  const lldb::addr_t range_start = memory_desc64.start_of_memory_range;
369  const size_t range_size = memory_desc64.data_size;
370 
371  if (base_rva + range_size > GetData().size())
372  return llvm::None;
373 
374  if (range_start <= addr && addr < range_start + range_size) {
375  return minidump::Range(range_start,
376  GetData().slice(base_rva, range_size));
377  }
378  base_rva += range_size;
379  }
380  }
381 
382  return llvm::None;
383 }
384 
385 llvm::ArrayRef<uint8_t> MinidumpParser::GetMemory(lldb::addr_t addr,
386  size_t size) {
387  // I don't have a sense of how frequently this is called or how many memory
388  // ranges a Minidump typically has, so I'm not sure if searching for the
389  // appropriate range linearly each time is stupid. Perhaps we should build
390  // an index for faster lookups.
391  llvm::Optional<minidump::Range> range = FindMemoryRange(addr);
392  if (!range)
393  return {};
394 
395  // There's at least some overlap between the beginning of the desired range
396  // (addr) and the current range. Figure out where the overlap begins and how
397  // much overlap there is.
398 
399  const size_t offset = addr - range->start;
400 
401  if (addr < range->start || offset >= range->range_ref.size())
402  return {};
403 
404  const size_t overlap = std::min(size, range->range_ref.size() - offset);
405  return range->range_ref.slice(offset, overlap);
406 }
407 
408 static bool
410  std::vector<MemoryRegionInfo> &regions) {
411  auto data = parser.GetStream(StreamType::LinuxMaps);
412  if (data.empty())
413  return false;
414  ParseLinuxMapRegions(llvm::toStringRef(data),
415  [&](const lldb_private::MemoryRegionInfo &region,
416  const lldb_private::Status &status) -> bool {
417  if (status.Success())
418  regions.push_back(region);
419  return true;
420  });
421  return !regions.empty();
422 }
423 
424 static bool
426  std::vector<MemoryRegionInfo> &regions) {
427  auto data = parser.GetStream(StreamType::MemoryInfoList);
428  if (data.empty())
429  return false;
430  auto mem_info_list = MinidumpMemoryInfo::ParseMemoryInfoList(data);
431  if (mem_info_list.empty())
432  return false;
433  constexpr auto yes = MemoryRegionInfo::eYes;
434  constexpr auto no = MemoryRegionInfo::eNo;
435  regions.reserve(mem_info_list.size());
436  for (const auto &entry : mem_info_list) {
437  MemoryRegionInfo region;
438  region.GetRange().SetRangeBase(entry->base_address);
439  region.GetRange().SetByteSize(entry->region_size);
440  region.SetReadable(entry->isReadable() ? yes : no);
441  region.SetWritable(entry->isWritable() ? yes : no);
442  region.SetExecutable(entry->isExecutable() ? yes : no);
443  region.SetMapped(entry->isMapped() ? yes : no);
444  regions.push_back(region);
445  }
446  return !regions.empty();
447 }
448 
449 static bool
451  std::vector<MemoryRegionInfo> &regions) {
452  auto data = parser.GetStream(StreamType::MemoryList);
453  if (data.empty())
454  return false;
455  auto memory_list = MinidumpMemoryDescriptor::ParseMemoryList(data);
456  if (memory_list.empty())
457  return false;
458  regions.reserve(memory_list.size());
459  for (const auto &memory_desc : memory_list) {
460  if (memory_desc.memory.DataSize == 0)
461  continue;
462  MemoryRegionInfo region;
463  region.GetRange().SetRangeBase(memory_desc.start_of_memory_range);
464  region.GetRange().SetByteSize(memory_desc.memory.DataSize);
467  regions.push_back(region);
468  }
469  regions.shrink_to_fit();
470  return !regions.empty();
471 }
472 
473 static bool
475  std::vector<MemoryRegionInfo> &regions) {
476  llvm::ArrayRef<uint8_t> data =
477  parser.GetStream(StreamType::Memory64List);
478  if (data.empty())
479  return false;
480  llvm::ArrayRef<MinidumpMemoryDescriptor64> memory64_list;
481  uint64_t base_rva;
482  std::tie(memory64_list, base_rva) =
484 
485  if (memory64_list.empty())
486  return false;
487 
488  regions.reserve(memory64_list.size());
489  for (const auto &memory_desc : memory64_list) {
490  if (memory_desc.data_size == 0)
491  continue;
492  MemoryRegionInfo region;
493  region.GetRange().SetRangeBase(memory_desc.start_of_memory_range);
494  region.GetRange().SetByteSize(memory_desc.data_size);
497  regions.push_back(region);
498  }
499  regions.shrink_to_fit();
500  return !regions.empty();
501 }
502 
504 MinidumpParser::FindMemoryRegion(lldb::addr_t load_addr) const {
505  auto begin = m_regions.begin();
506  auto end = m_regions.end();
507  auto pos = std::lower_bound(begin, end, load_addr);
508  if (pos != end && pos->GetRange().Contains(load_addr))
509  return *pos;
510 
511  MemoryRegionInfo region;
512  if (pos == begin)
513  region.GetRange().SetRangeBase(0);
514  else {
515  auto prev = pos - 1;
516  if (prev->GetRange().Contains(load_addr))
517  return *prev;
518  region.GetRange().SetRangeBase(prev->GetRange().GetRangeEnd());
519  }
520  if (pos == end)
521  region.GetRange().SetRangeEnd(UINT64_MAX);
522  else
523  region.GetRange().SetRangeEnd(pos->GetRange().GetRangeBase());
528  return region;
529 }
530 
533  if (!m_parsed_regions)
535  return FindMemoryRegion(load_addr);
536 }
537 
539  if (!m_parsed_regions) {
540  m_parsed_regions = true;
541  // We haven't cached our memory regions yet we will create the region cache
542  // once. We create the region cache using the best source. We start with
543  // the linux maps since they are the most complete and have names for the
544  // regions. Next we try the MemoryInfoList since it has
545  // read/write/execute/map data, and then fall back to the MemoryList and
546  // Memory64List to just get a list of the memory that is mapped in this
547  // core file
548  if (!CreateRegionsCacheFromLinuxMaps(*this, m_regions))
549  if (!CreateRegionsCacheFromMemoryInfoList(*this, m_regions))
550  if (!CreateRegionsCacheFromMemoryList(*this, m_regions))
551  CreateRegionsCacheFromMemory64List(*this, m_regions);
552  llvm::sort(m_regions.begin(), m_regions.end());
553  }
554  return m_regions;
555 }
556 
557 #define ENUM_TO_CSTR(ST) \
558  case StreamType::ST: \
559  return #ST
560 
561 llvm::StringRef
562 MinidumpParser::GetStreamTypeAsString(StreamType stream_type) {
563  switch (stream_type) {
564  ENUM_TO_CSTR(Unused);
567  ENUM_TO_CSTR(MemoryList);
568  ENUM_TO_CSTR(Exception);
569  ENUM_TO_CSTR(SystemInfo);
570  ENUM_TO_CSTR(ThreadExList);
571  ENUM_TO_CSTR(Memory64List);
572  ENUM_TO_CSTR(CommentA);
573  ENUM_TO_CSTR(CommentW);
574  ENUM_TO_CSTR(HandleData);
575  ENUM_TO_CSTR(FunctionTable);
576  ENUM_TO_CSTR(UnloadedModuleList);
577  ENUM_TO_CSTR(MiscInfo);
578  ENUM_TO_CSTR(MemoryInfoList);
579  ENUM_TO_CSTR(ThreadInfoList);
580  ENUM_TO_CSTR(HandleOperationList);
582  ENUM_TO_CSTR(JavascriptData);
583  ENUM_TO_CSTR(SystemMemoryInfo);
584  ENUM_TO_CSTR(ProcessVMCounters);
585  ENUM_TO_CSTR(LastReserved);
586  ENUM_TO_CSTR(BreakpadInfo);
587  ENUM_TO_CSTR(AssertionInfo);
588  ENUM_TO_CSTR(LinuxCPUInfo);
590  ENUM_TO_CSTR(LinuxLSBRelease);
591  ENUM_TO_CSTR(LinuxCMDLine);
592  ENUM_TO_CSTR(LinuxEnviron);
593  ENUM_TO_CSTR(LinuxAuxv);
594  ENUM_TO_CSTR(LinuxMaps);
595  ENUM_TO_CSTR(LinuxDSODebug);
596  ENUM_TO_CSTR(LinuxProcStat);
597  ENUM_TO_CSTR(LinuxProcUptime);
598  ENUM_TO_CSTR(LinuxProcFD);
599  ENUM_TO_CSTR(FacebookAppCustomData);
600  ENUM_TO_CSTR(FacebookBuildID);
601  ENUM_TO_CSTR(FacebookAppVersionName);
602  ENUM_TO_CSTR(FacebookJavaStack);
603  ENUM_TO_CSTR(FacebookDalvikInfo);
604  ENUM_TO_CSTR(FacebookUnwindSymbols);
605  ENUM_TO_CSTR(FacebookDumpErrorLog);
606  ENUM_TO_CSTR(FacebookAppStateLog);
607  ENUM_TO_CSTR(FacebookAbortReason);
608  ENUM_TO_CSTR(FacebookThreadName);
609  ENUM_TO_CSTR(FacebookLogcat);
610  }
611  return "unknown stream type";
612 }
const MemoryRegionInfos & GetMemoryRegions()
llvm::support::ulittle64_t tls_slots[64]
#define LIBLLDB_LOG_PROCESS
Definition: Logging.h:15
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
void SetExecutable(OptionalBool val)
llvm::ArrayRef< uint8_t > GetStream(StreamType stream_type)
llvm::Optional< LinuxProcStatus > GetLinuxProcStatus()
bool SetTriple(const llvm::Triple &triple)
Architecture triple setter.
Definition: ArchSpec.cpp:797
llvm::ArrayRef< uint8_t > GetMemory(lldb::addr_t addr, size_t size)
llvm::support::ulittle16_t Data2
Definition: MinidumpTypes.h:49
llvm::support::ulittle64_t teb
static UUID fromOptionalData(const void *bytes, uint32_t num_bytes)
Creates a UUID from the data pointed to by the bytes argument.
Definition: UUID.h:43
An architecture specification class.
Definition: ArchSpec.h:32
llvm::ArrayRef< minidump::Module > GetModuleList()
llvm::support::ulittle32_t Data1
Definition: MinidumpTypes.h:48
void SetMapped(OptionalBool val)
#define LIBLLDB_LOG_MODULES
Definition: Logging.h:35
llvm::Optional< Range > FindMemoryRange(lldb::addr_t addr)
void ParseLinuxMapRegions(llvm::StringRef linux_map, LinuxMapCallback const &callback)
bool IsValid() const
Tests if this ArchSpec is valid.
Definition: ArchSpec.h:329
void SetRangeEnd(BaseType end)
Definition: RangeMap.h:64
#define LLDB_LOG_ERROR(log, error,...)
Definition: Log.h:225
const MinidumpMiscInfo * GetMiscInfo()
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:431
llvm::ArrayRef< MinidumpThread > GetThreads()
llvm::ArrayRef< uint8_t > GetData()
llvm::Optional< lldb::pid_t > GetPid() const
llvm::Optional< lldb::pid_t > GetPid()
A collection class for Module objects.
Definition: ModuleList.h:91
struct lldb_private::minidump::CvRecordPdb70::@83 Uuid
llvm::ArrayRef< uint8_t > GetThreadContext(const LocationDescriptor &location)
std::vector< const minidump::Module * > GetFilteredModuleList()
static llvm::ArrayRef< MinidumpThread > ParseThreadList(llvm::ArrayRef< uint8_t > &data)
bool Success() const
Test for success condition.
Definition: Status.cpp:287
Status consumeObject(llvm::ArrayRef< uint8_t > &Buffer, const T *&Object)
Definition: MinidumpTypes.h:66
static bool CreateRegionsCacheFromMemoryInfoList(MinidumpParser &parser, std::vector< MemoryRegionInfo > &regions)
static bool CreateRegionsCacheFromLinuxMaps(MinidumpParser &parser, std::vector< MemoryRegionInfo > &regions)
static llvm::StringRef GetStreamTypeAsString(StreamType stream_type)
static std::pair< llvm::ArrayRef< MinidumpMemoryDescriptor64 >, uint64_t > ParseMemory64List(llvm::ArrayRef< uint8_t > &data)
static const MinidumpExceptionStream * Parse(llvm::ArrayRef< uint8_t > &data)
static bool CreateRegionsCacheFromMemory64List(MinidumpParser &parser, std::vector< MemoryRegionInfo > &regions)
llvm::ArrayRef< uint8_t > GetThreadContextWow64(const MinidumpThread &td)
static llvm::ArrayRef< MinidumpMemoryDescriptor > ParseMemoryList(llvm::ArrayRef< uint8_t > &data)
void SetByteSize(SizeType s)
Definition: RangeMap.h:73
llvm::support::ulittle16_t Data3
Definition: MinidumpTypes.h:50
uint64_t addr_t
Definition: lldb-types.h:83
void SetReadable(OptionalBool val)
static llvm::Expected< MinidumpParser > Create(const lldb::DataBufferSP &data_buf_sp)
bool Fail() const
Test for error condition.
Definition: Status.cpp:181
Log * GetLogIfAnyCategoriesSet(uint32_t mask)
Definition: Logging.cpp:61
#define ENUM_TO_CSTR(ST)
UUID GetModuleUUID(const minidump::Module *module)
llvm::support::ulittle32_t Age
Definition: MinidumpTypes.h:53
void SetRangeBase(BaseType b)
Definition: RangeMap.h:48
void SetWritable(OptionalBool val)
const MinidumpExceptionStream * GetExceptionStream()
static const MinidumpMiscInfo * Parse(llvm::ArrayRef< uint8_t > &data)
static llvm::Optional< LinuxProcStatus > Parse(llvm::ArrayRef< uint8_t > &data)
MemoryRegionInfo GetMemoryRegionInfo(lldb::addr_t load_addr)
#define UINT64_MAX
Definition: lldb-defines.h:35
static bool CreateRegionsCacheFromMemoryList(MinidumpParser &parser, std::vector< MemoryRegionInfo > &regions)
llvm::object::MinidumpFile & GetMinidumpFile()
An error handling class.
Definition: Status.h:44
static std::vector< const MinidumpMemoryInfo * > ParseMemoryInfoList(llvm::ArrayRef< uint8_t > &data)