LLDB  mainline
MinidumpParser.cpp
Go to the documentation of this file.
1 //===-- MinidumpParser.cpp ------------------------------------------------===//
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 UUID::CvRecordPdb70 *pdb70_uuid = nullptr;
66  Status error = consumeObject(cv_record, pdb70_uuid);
67  if (error.Fail())
68  return UUID();
69  if (GetArchitecture().GetTriple().isOSBinFormatELF()) {
70  if (pdb70_uuid->Age != 0)
71  return UUID::fromOptionalData(pdb70_uuid, sizeof(*pdb70_uuid));
72  return UUID::fromOptionalData(&pdb70_uuid->Uuid,
73  sizeof(pdb70_uuid->Uuid));
74  }
75  return UUID::fromCvRecord(*pdb70_uuid);
76  } else if (cv_signature == CvSignature::ElfBuildId)
77  return UUID::fromOptionalData(cv_record);
78 
79  return UUID();
80 }
81 
82 llvm::ArrayRef<minidump::Thread> MinidumpParser::GetThreads() {
83  auto ExpectedThreads = GetMinidumpFile().getThreadList();
84  if (ExpectedThreads)
85  return *ExpectedThreads;
86 
88  ExpectedThreads.takeError(),
89  "Failed to read thread list: {0}");
90  return {};
91 }
92 
93 llvm::ArrayRef<uint8_t>
94 MinidumpParser::GetThreadContext(const LocationDescriptor &location) {
95  if (location.RVA + location.DataSize > GetData().size())
96  return {};
97  return GetData().slice(location.RVA, location.DataSize);
98 }
99 
100 llvm::ArrayRef<uint8_t>
101 MinidumpParser::GetThreadContext(const minidump::Thread &td) {
102  return GetThreadContext(td.Context);
103 }
104 
105 llvm::ArrayRef<uint8_t>
106 MinidumpParser::GetThreadContextWow64(const minidump::Thread &td) {
107  // On Windows, a 32-bit process can run on a 64-bit machine under WOW64. If
108  // the minidump was captured with a 64-bit debugger, then the CONTEXT we just
109  // grabbed from the mini_dump_thread is the one for the 64-bit "native"
110  // process rather than the 32-bit "guest" process we care about. In this
111  // case, we can get the 32-bit CONTEXT from the TEB (Thread Environment
112  // Block) of the 64-bit process.
113  auto teb_mem = GetMemory(td.EnvironmentBlock, sizeof(TEB64));
114  if (teb_mem.empty())
115  return {};
116 
117  const TEB64 *wow64teb;
118  Status error = consumeObject(teb_mem, wow64teb);
119  if (error.Fail())
120  return {};
121 
122  // Slot 1 of the thread-local storage in the 64-bit TEB points to a structure
123  // that includes the 32-bit CONTEXT (after a ULONG). See:
124  // https://msdn.microsoft.com/en-us/library/ms681670.aspx
125  auto context =
126  GetMemory(wow64teb->tls_slots[1] + 4, sizeof(MinidumpContext_x86_32));
127  if (context.size() < sizeof(MinidumpContext_x86_32))
128  return {};
129 
130  return context;
131  // NOTE: We don't currently use the TEB for anything else. If we
132  // need it in the future, the 32-bit TEB is located according to the address
133  // stored in the first slot of the 64-bit TEB (wow64teb.Reserved1[0]).
134 }
135 
137  if (m_arch.IsValid())
138  return m_arch;
139 
140  // Set the architecture in m_arch
141  llvm::Expected<const SystemInfo &> system_info = m_file->getSystemInfo();
142 
143  if (!system_info) {
145  system_info.takeError(),
146  "Failed to read SystemInfo stream: {0}");
147  return m_arch;
148  }
149 
150  // TODO what to do about big endiand flavors of arm ?
151  // TODO set the arm subarch stuff if the minidump has info about it
152 
153  llvm::Triple triple;
154  triple.setVendor(llvm::Triple::VendorType::UnknownVendor);
155 
156  switch (system_info->ProcessorArch) {
157  case ProcessorArchitecture::X86:
158  triple.setArch(llvm::Triple::ArchType::x86);
159  break;
160  case ProcessorArchitecture::AMD64:
161  triple.setArch(llvm::Triple::ArchType::x86_64);
162  break;
163  case ProcessorArchitecture::ARM:
164  triple.setArch(llvm::Triple::ArchType::arm);
165  break;
166  case ProcessorArchitecture::ARM64:
167  case ProcessorArchitecture::BP_ARM64:
168  triple.setArch(llvm::Triple::ArchType::aarch64);
169  break;
170  default:
171  triple.setArch(llvm::Triple::ArchType::UnknownArch);
172  break;
173  }
174 
175  // TODO add all of the OSes that Minidump/breakpad distinguishes?
176  switch (system_info->PlatformId) {
177  case OSPlatform::Win32S:
178  case OSPlatform::Win32Windows:
179  case OSPlatform::Win32NT:
180  case OSPlatform::Win32CE:
181  triple.setOS(llvm::Triple::OSType::Win32);
182  triple.setVendor(llvm::Triple::VendorType::PC);
183  break;
184  case OSPlatform::Linux:
185  triple.setOS(llvm::Triple::OSType::Linux);
186  break;
187  case OSPlatform::MacOSX:
188  triple.setOS(llvm::Triple::OSType::MacOSX);
189  triple.setVendor(llvm::Triple::Apple);
190  break;
191  case OSPlatform::IOS:
192  triple.setOS(llvm::Triple::OSType::IOS);
193  triple.setVendor(llvm::Triple::Apple);
194  break;
195  case OSPlatform::Android:
196  triple.setOS(llvm::Triple::OSType::Linux);
197  triple.setEnvironment(llvm::Triple::EnvironmentType::Android);
198  break;
199  default: {
200  triple.setOS(llvm::Triple::OSType::UnknownOS);
201  auto ExpectedCSD = m_file->getString(system_info->CSDVersionRVA);
202  if (!ExpectedCSD) {
204  ExpectedCSD.takeError(),
205  "Failed to CSD Version string: {0}");
206  } else {
207  if (ExpectedCSD->find("Linux") != std::string::npos)
208  triple.setOS(llvm::Triple::OSType::Linux);
209  }
210  break;
211  }
212  }
213  m_arch.SetTriple(triple);
214  return m_arch;
215 }
216 
218  llvm::ArrayRef<uint8_t> data = GetStream(StreamType::MiscInfo);
219 
220  if (data.size() == 0)
221  return nullptr;
222 
223  return MinidumpMiscInfo::Parse(data);
224 }
225 
226 llvm::Optional<LinuxProcStatus> MinidumpParser::GetLinuxProcStatus() {
227  llvm::ArrayRef<uint8_t> data = GetStream(StreamType::LinuxProcStatus);
228 
229  if (data.size() == 0)
230  return llvm::None;
231 
232  return LinuxProcStatus::Parse(data);
233 }
234 
235 llvm::Optional<lldb::pid_t> MinidumpParser::GetPid() {
236  const MinidumpMiscInfo *misc_info = GetMiscInfo();
237  if (misc_info != nullptr) {
238  return misc_info->GetPid();
239  }
240 
241  llvm::Optional<LinuxProcStatus> proc_status = GetLinuxProcStatus();
242  if (proc_status.hasValue()) {
243  return proc_status->GetPid();
244  }
245 
246  return llvm::None;
247 }
248 
249 llvm::ArrayRef<minidump::Module> MinidumpParser::GetModuleList() {
250  auto ExpectedModules = GetMinidumpFile().getModuleList();
251  if (ExpectedModules)
252  return *ExpectedModules;
253 
255  ExpectedModules.takeError(),
256  "Failed to read module list: {0}");
257  return {};
258 }
259 
260 static bool
262  std::vector<MemoryRegionInfo> &regions) {
263  auto data = parser.GetStream(StreamType::LinuxMaps);
264  if (data.empty())
265  return false;
266 
269  llvm::toStringRef(data),
270  [&regions, &log](llvm::Expected<MemoryRegionInfo> region) -> bool {
271  if (region)
272  regions.push_back(*region);
273  else
274  LLDB_LOG_ERROR(log, region.takeError(),
275  "Reading memory region from minidump failed: {0}");
276  return true;
277  });
278  return !regions.empty();
279 }
280 
281 /// Check for the memory regions starting at \a load_addr for a contiguous
282 /// section that has execute permissions that matches the module path.
283 ///
284 /// When we load a breakpad generated minidump file, we might have the
285 /// /proc/<pid>/maps text for a process that details the memory map of the
286 /// process that the minidump is describing. This checks the sorted memory
287 /// regions for a section that has execute permissions. A sample maps files
288 /// might look like:
289 ///
290 /// 00400000-00401000 r--p 00000000 fd:01 2838574 /tmp/a.out
291 /// 00401000-00402000 r-xp 00001000 fd:01 2838574 /tmp/a.out
292 /// 00402000-00403000 r--p 00002000 fd:01 2838574 /tmp/a.out
293 /// 00403000-00404000 r--p 00002000 fd:01 2838574 /tmp/a.out
294 /// 00404000-00405000 rw-p 00003000 fd:01 2838574 /tmp/a.out
295 /// ...
296 ///
297 /// This function should return true when given 0x00400000 and "/tmp/a.out"
298 /// is passed in as the path since it has a consecutive memory region for
299 /// "/tmp/a.out" that has execute permissions at 0x00401000. This will help us
300 /// differentiate if a file has been memory mapped into a process for reading
301 /// and breakpad ends up saving a minidump file that has two module entries for
302 /// a given file: one that is read only for the entire file, and then one that
303 /// is the real executable that is loaded into memory for execution. For memory
304 /// mapped files they will typically show up and r--p permissions and a range
305 /// matcning the entire range of the file on disk:
306 ///
307 /// 00800000-00805000 r--p 00000000 fd:01 2838574 /tmp/a.out
308 /// 00805000-00806000 r-xp 00001000 fd:01 1234567 /usr/lib/libc.so
309 ///
310 /// This function should return false when asked about 0x00800000 with
311 /// "/tmp/a.out" as the path.
312 ///
313 /// \param[in] path
314 /// The path to the module to check for in the memory regions. Only sequential
315 /// memory regions whose paths match this path will be considered when looking
316 /// for execute permissions.
317 ///
318 /// \param[in] regions
319 /// A sorted list of memory regions obtained from a call to
320 /// CreateRegionsCacheFromLinuxMaps.
321 ///
322 /// \param[in] base_of_image
323 /// The load address of this module from BaseOfImage in the modules list.
324 ///
325 /// \return
326 /// True if a contiguous region of memory belonging to the module with a
327 /// matching path exists that has executable permissions. Returns false if
328 /// \a regions is empty or if there are no regions with execute permissions
329 /// that match \a path.
330 
332  const MemoryRegionInfos &regions,
333  lldb::addr_t base_of_image) {
334  if (regions.empty())
335  return false;
336  lldb::addr_t addr = base_of_image;
338  while (region.GetName() == path) {
339  if (region.GetExecutable() == MemoryRegionInfo::eYes)
340  return true;
341  addr += region.GetRange().GetByteSize();
342  region = MinidumpParser::GetMemoryRegionInfo(regions, addr);
343  }
344  return false;
345 }
346 
347 std::vector<const minidump::Module *> MinidumpParser::GetFilteredModuleList() {
349  auto ExpectedModules = GetMinidumpFile().getModuleList();
350  if (!ExpectedModules) {
351  LLDB_LOG_ERROR(log, ExpectedModules.takeError(),
352  "Failed to read module list: {0}");
353  return {};
354  }
355 
356  // Create memory regions from the linux maps only. We do this to avoid issues
357  // with breakpad generated minidumps where if someone has mmap'ed a shared
358  // library into memory to accesss its data in the object file, we can get a
359  // minidump with two mappings for a binary: one whose base image points to a
360  // memory region that is read + execute and one that is read only.
361  MemoryRegionInfos linux_regions;
362  if (CreateRegionsCacheFromLinuxMaps(*this, linux_regions))
363  llvm::sort(linux_regions);
364 
365  // map module_name -> filtered_modules index
366  typedef llvm::StringMap<size_t> MapType;
367  MapType module_name_to_filtered_index;
368 
369  std::vector<const minidump::Module *> filtered_modules;
370 
371  for (const auto &module : *ExpectedModules) {
372  auto ExpectedName = m_file->getString(module.ModuleNameRVA);
373  if (!ExpectedName) {
374  LLDB_LOG_ERROR(log, ExpectedName.takeError(),
375  "Failed to get module name: {0}");
376  continue;
377  }
378 
379  MapType::iterator iter;
380  bool inserted;
381  // See if we have inserted this module aready into filtered_modules. If we
382  // haven't insert an entry into module_name_to_filtered_index with the
383  // index where we will insert it if it isn't in the vector already.
384  std::tie(iter, inserted) = module_name_to_filtered_index.try_emplace(
385  *ExpectedName, filtered_modules.size());
386 
387  if (inserted) {
388  // This module has not been seen yet, insert it into filtered_modules at
389  // the index that was inserted into module_name_to_filtered_index using
390  // "filtered_modules.size()" above.
391  filtered_modules.push_back(&module);
392  } else {
393  // We have a duplicate module entry. Check the linux regions to see if
394  // either module is not really a mapped executable. If one but not the
395  // other is a real mapped executable, prefer the executable one. This
396  // can happen when a process mmap's in the file for an executable in
397  // order to read bytes from the executable file. A memory region mapping
398  // will exist for the mmap'ed version and for the loaded executable, but
399  // only one will have a consecutive region that is executable in the
400  // memory regions.
401  auto dup_module = filtered_modules[iter->second];
402  ConstString name(*ExpectedName);
403  bool is_executable =
404  CheckForLinuxExecutable(name, linux_regions, module.BaseOfImage);
405  bool dup_is_executable =
406  CheckForLinuxExecutable(name, linux_regions, dup_module->BaseOfImage);
407 
408  if (is_executable != dup_is_executable) {
409  if (is_executable)
410  filtered_modules[iter->second] = &module;
411  continue;
412  }
413  // This module has been seen. Modules are sometimes mentioned multiple
414  // times when they are mapped discontiguously, so find the module with
415  // the lowest "base_of_image" and use that as the filtered module.
416  if (module.BaseOfImage < dup_module->BaseOfImage)
417  filtered_modules[iter->second] = &module;
418  }
419  }
420  return filtered_modules;
421 }
422 
423 const minidump::ExceptionStream *MinidumpParser::GetExceptionStream() {
424  auto ExpectedStream = GetMinidumpFile().getExceptionStream();
425  if (ExpectedStream)
426  return &*ExpectedStream;
427 
429  ExpectedStream.takeError(),
430  "Failed to read minidump exception stream: {0}");
431  return nullptr;
432 }
433 
434 llvm::Optional<minidump::Range>
436  llvm::ArrayRef<uint8_t> data64 = GetStream(StreamType::Memory64List);
438 
439  auto ExpectedMemory = GetMinidumpFile().getMemoryList();
440  if (!ExpectedMemory) {
441  LLDB_LOG_ERROR(log, ExpectedMemory.takeError(),
442  "Failed to read memory list: {0}");
443  } else {
444  for (const auto &memory_desc : *ExpectedMemory) {
445  const LocationDescriptor &loc_desc = memory_desc.Memory;
446  const lldb::addr_t range_start = memory_desc.StartOfMemoryRange;
447  const size_t range_size = loc_desc.DataSize;
448 
449  if (loc_desc.RVA + loc_desc.DataSize > GetData().size())
450  return llvm::None;
451 
452  if (range_start <= addr && addr < range_start + range_size) {
453  auto ExpectedSlice = GetMinidumpFile().getRawData(loc_desc);
454  if (!ExpectedSlice) {
455  LLDB_LOG_ERROR(log, ExpectedSlice.takeError(),
456  "Failed to get memory slice: {0}");
457  return llvm::None;
458  }
459  return minidump::Range(range_start, *ExpectedSlice);
460  }
461  }
462  }
463 
464  // Some Minidumps have a Memory64ListStream that captures all the heap memory
465  // (full-memory Minidumps). We can't exactly use the same loop as above,
466  // because the Minidump uses slightly different data structures to describe
467  // those
468 
469  if (!data64.empty()) {
470  llvm::ArrayRef<MinidumpMemoryDescriptor64> memory64_list;
471  uint64_t base_rva;
472  std::tie(memory64_list, base_rva) =
474 
475  if (memory64_list.empty())
476  return llvm::None;
477 
478  for (const auto &memory_desc64 : memory64_list) {
479  const lldb::addr_t range_start = memory_desc64.start_of_memory_range;
480  const size_t range_size = memory_desc64.data_size;
481 
482  if (base_rva + range_size > GetData().size())
483  return llvm::None;
484 
485  if (range_start <= addr && addr < range_start + range_size) {
486  return minidump::Range(range_start,
487  GetData().slice(base_rva, range_size));
488  }
489  base_rva += range_size;
490  }
491  }
492 
493  return llvm::None;
494 }
495 
496 llvm::ArrayRef<uint8_t> MinidumpParser::GetMemory(lldb::addr_t addr,
497  size_t size) {
498  // I don't have a sense of how frequently this is called or how many memory
499  // ranges a Minidump typically has, so I'm not sure if searching for the
500  // appropriate range linearly each time is stupid. Perhaps we should build
501  // an index for faster lookups.
502  llvm::Optional<minidump::Range> range = FindMemoryRange(addr);
503  if (!range)
504  return {};
505 
506  // There's at least some overlap between the beginning of the desired range
507  // (addr) and the current range. Figure out where the overlap begins and how
508  // much overlap there is.
509 
510  const size_t offset = addr - range->start;
511 
512  if (addr < range->start || offset >= range->range_ref.size())
513  return {};
514 
515  const size_t overlap = std::min(size, range->range_ref.size() - offset);
516  return range->range_ref.slice(offset, overlap);
517 }
518 
519 static bool
521  std::vector<MemoryRegionInfo> &regions) {
523  auto ExpectedInfo = parser.GetMinidumpFile().getMemoryInfoList();
524  if (!ExpectedInfo) {
525  LLDB_LOG_ERROR(log, ExpectedInfo.takeError(),
526  "Failed to read memory info list: {0}");
527  return false;
528  }
529  constexpr auto yes = MemoryRegionInfo::eYes;
530  constexpr auto no = MemoryRegionInfo::eNo;
531  for (const MemoryInfo &entry : *ExpectedInfo) {
532  MemoryRegionInfo region;
533  region.GetRange().SetRangeBase(entry.BaseAddress);
534  region.GetRange().SetByteSize(entry.RegionSize);
535 
536  MemoryProtection prot = entry.Protect;
537  region.SetReadable(bool(prot & MemoryProtection::NoAccess) ? no : yes);
538  region.SetWritable(
539  bool(prot & (MemoryProtection::ReadWrite | MemoryProtection::WriteCopy |
540  MemoryProtection::ExecuteReadWrite |
541  MemoryProtection::ExeciteWriteCopy))
542  ? yes
543  : no);
544  region.SetExecutable(
545  bool(prot & (MemoryProtection::Execute | MemoryProtection::ExecuteRead |
546  MemoryProtection::ExecuteReadWrite |
547  MemoryProtection::ExeciteWriteCopy))
548  ? yes
549  : no);
550  region.SetMapped(entry.State != MemoryState::Free ? yes : no);
551  regions.push_back(region);
552  }
553  return !regions.empty();
554 }
555 
556 static bool
558  std::vector<MemoryRegionInfo> &regions) {
560  auto ExpectedMemory = parser.GetMinidumpFile().getMemoryList();
561  if (!ExpectedMemory) {
562  LLDB_LOG_ERROR(log, ExpectedMemory.takeError(),
563  "Failed to read memory list: {0}");
564  return false;
565  }
566  regions.reserve(ExpectedMemory->size());
567  for (const MemoryDescriptor &memory_desc : *ExpectedMemory) {
568  if (memory_desc.Memory.DataSize == 0)
569  continue;
570  MemoryRegionInfo region;
571  region.GetRange().SetRangeBase(memory_desc.StartOfMemoryRange);
572  region.GetRange().SetByteSize(memory_desc.Memory.DataSize);
575  regions.push_back(region);
576  }
577  regions.shrink_to_fit();
578  return !regions.empty();
579 }
580 
581 static bool
583  std::vector<MemoryRegionInfo> &regions) {
584  llvm::ArrayRef<uint8_t> data =
585  parser.GetStream(StreamType::Memory64List);
586  if (data.empty())
587  return false;
588  llvm::ArrayRef<MinidumpMemoryDescriptor64> memory64_list;
589  uint64_t base_rva;
590  std::tie(memory64_list, base_rva) =
592 
593  if (memory64_list.empty())
594  return false;
595 
596  regions.reserve(memory64_list.size());
597  for (const auto &memory_desc : memory64_list) {
598  if (memory_desc.data_size == 0)
599  continue;
600  MemoryRegionInfo region;
601  region.GetRange().SetRangeBase(memory_desc.start_of_memory_range);
602  region.GetRange().SetByteSize(memory_desc.data_size);
605  regions.push_back(region);
606  }
607  regions.shrink_to_fit();
608  return !regions.empty();
609 }
610 
611 std::pair<MemoryRegionInfos, bool> MinidumpParser::BuildMemoryRegions() {
612  // We create the region cache using the best source. We start with
613  // the linux maps since they are the most complete and have names for the
614  // regions. Next we try the MemoryInfoList since it has
615  // read/write/execute/map data, and then fall back to the MemoryList and
616  // Memory64List to just get a list of the memory that is mapped in this
617  // core file
618  MemoryRegionInfos result;
619  const auto &return_sorted = [&](bool is_complete) {
620  llvm::sort(result);
621  return std::make_pair(std::move(result), is_complete);
622  };
623  if (CreateRegionsCacheFromLinuxMaps(*this, result))
624  return return_sorted(true);
625  if (CreateRegionsCacheFromMemoryInfoList(*this, result))
626  return return_sorted(true);
627  if (CreateRegionsCacheFromMemoryList(*this, result))
628  return return_sorted(false);
629  CreateRegionsCacheFromMemory64List(*this, result);
630  return return_sorted(false);
631 }
632 
633 #define ENUM_TO_CSTR(ST) \
634  case StreamType::ST: \
635  return #ST
636 
637 llvm::StringRef
638 MinidumpParser::GetStreamTypeAsString(StreamType stream_type) {
639  switch (stream_type) {
640  ENUM_TO_CSTR(Unused);
643  ENUM_TO_CSTR(MemoryList);
644  ENUM_TO_CSTR(Exception);
645  ENUM_TO_CSTR(SystemInfo);
646  ENUM_TO_CSTR(ThreadExList);
647  ENUM_TO_CSTR(Memory64List);
648  ENUM_TO_CSTR(CommentA);
649  ENUM_TO_CSTR(CommentW);
650  ENUM_TO_CSTR(HandleData);
651  ENUM_TO_CSTR(FunctionTable);
652  ENUM_TO_CSTR(UnloadedModuleList);
653  ENUM_TO_CSTR(MiscInfo);
654  ENUM_TO_CSTR(MemoryInfoList);
655  ENUM_TO_CSTR(ThreadInfoList);
656  ENUM_TO_CSTR(HandleOperationList);
657  ENUM_TO_CSTR(Token);
658  ENUM_TO_CSTR(JavascriptData);
659  ENUM_TO_CSTR(SystemMemoryInfo);
660  ENUM_TO_CSTR(ProcessVMCounters);
661  ENUM_TO_CSTR(LastReserved);
662  ENUM_TO_CSTR(BreakpadInfo);
663  ENUM_TO_CSTR(AssertionInfo);
664  ENUM_TO_CSTR(LinuxCPUInfo);
666  ENUM_TO_CSTR(LinuxLSBRelease);
667  ENUM_TO_CSTR(LinuxCMDLine);
668  ENUM_TO_CSTR(LinuxEnviron);
669  ENUM_TO_CSTR(LinuxAuxv);
670  ENUM_TO_CSTR(LinuxMaps);
671  ENUM_TO_CSTR(LinuxDSODebug);
672  ENUM_TO_CSTR(LinuxProcStat);
673  ENUM_TO_CSTR(LinuxProcUptime);
674  ENUM_TO_CSTR(LinuxProcFD);
675  ENUM_TO_CSTR(FacebookAppCustomData);
676  ENUM_TO_CSTR(FacebookBuildID);
677  ENUM_TO_CSTR(FacebookAppVersionName);
678  ENUM_TO_CSTR(FacebookJavaStack);
679  ENUM_TO_CSTR(FacebookDalvikInfo);
680  ENUM_TO_CSTR(FacebookUnwindSymbols);
681  ENUM_TO_CSTR(FacebookDumpErrorLog);
682  ENUM_TO_CSTR(FacebookAppStateLog);
683  ENUM_TO_CSTR(FacebookAbortReason);
684  ENUM_TO_CSTR(FacebookThreadName);
685  ENUM_TO_CSTR(FacebookLogcat);
686  }
687  return "unknown stream type";
688 }
689 
692  lldb::addr_t load_addr) {
693  MemoryRegionInfo region;
694  auto pos = llvm::upper_bound(regions, load_addr);
695  if (pos != regions.begin() &&
696  std::prev(pos)->GetRange().Contains(load_addr)) {
697  return *std::prev(pos);
698  }
699 
700  if (pos == regions.begin())
701  region.GetRange().SetRangeBase(0);
702  else
703  region.GetRange().SetRangeBase(std::prev(pos)->GetRange().GetRangeEnd());
704 
705  if (pos == regions.end())
706  region.GetRange().SetRangeEnd(UINT64_MAX);
707  else
708  region.GetRange().SetRangeEnd(pos->GetRange().GetRangeBase());
709 
714  return region;
715 }
lldb_private::UUID::CvRecordPdb70::Age
llvm::support::ulittle32_t Age
Definition: UUID.h:36
lldb_private::UUID
Definition: UUID.h:23
lldb_private::minidump::CvSignature::ElfBuildId
@ ElfBuildId
lldb_private::minidump::MinidumpMiscInfo
Definition: MinidumpTypes.h:75
lldb_private::ArchSpec
Definition: ArchSpec.h:33
RegisterContextMinidump_x86_32.h
lldb_private::UUID::CvRecordPdb70::Uuid
struct lldb_private::UUID::CvRecordPdb70::@45 Uuid
lldb_private::minidump::MinidumpMemoryDescriptor64::ParseMemory64List
static std::pair< llvm::ArrayRef< MinidumpMemoryDescriptor64 >, uint64_t > ParseMemory64List(llvm::ArrayRef< uint8_t > &data)
Definition: MinidumpTypes.cpp:61
lldb_private::minidump::MinidumpParser::GetLinuxProcStatus
llvm::Optional< LinuxProcStatus > GetLinuxProcStatus()
Definition: MinidumpParser.cpp:226
lldb_private::minidump::MinidumpParser::GetFilteredModuleList
std::vector< const minidump::Module * > GetFilteredModuleList()
Definition: MinidumpParser.cpp:347
lldb_private::minidump::MinidumpParser::GetExceptionStream
const llvm::minidump::ExceptionStream * GetExceptionStream()
Definition: MinidumpParser.cpp:423
LIBLLDB_LOG_MODULES
#define LIBLLDB_LOG_MODULES
Definition: Logging.h:35
lldb_private::minidump::MinidumpParser::m_arch
ArchSpec m_arch
Definition: MinidumpParser.h:108
lldb_private::minidump::MinidumpParser::FindMemoryRange
llvm::Optional< Range > FindMemoryRange(lldb::addr_t addr)
Definition: MinidumpParser.cpp:435
lldb_private::ParseLinuxMapRegions
void ParseLinuxMapRegions(llvm::StringRef linux_map, LinuxMapCallback const &callback)
Definition: LinuxProcMaps.cpp:114
lldb_private::minidump::MinidumpParser::GetModuleUUID
UUID GetModuleUUID(const minidump::Module *module)
Definition: MinidumpParser.cpp:51
lldb_private::minidump::MinidumpParser::GetPid
llvm::Optional< lldb::pid_t > GetPid()
Definition: MinidumpParser.cpp:235
lldb_private::minidump::TEB64::tls_slots
llvm::support::ulittle64_t tls_slots[64]
Definition: minidump/NtStructures.h:30
lldb_private::minidump::MinidumpMiscInfo::GetPid
llvm::Optional< lldb::pid_t > GetPid() const
Definition: MinidumpTypes.cpp:27
lldb_private::minidump::MinidumpParser::GetThreadContext
llvm::ArrayRef< uint8_t > GetThreadContext(const LocationDescriptor &location)
Definition: MinidumpParser.cpp:94
lldb_private::MemoryRegionInfo
Definition: MemoryRegionInfo.h:21
lldb_private::minidump::TEB64
Definition: minidump/NtStructures.h:25
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::MemoryRegionInfo::SetReadable
void SetReadable(OptionalBool val)
Definition: MemoryRegionInfo.h:54
lldb_private::minidump::MinidumpParser::GetArchitecture
ArchSpec GetArchitecture()
Definition: MinidumpParser.cpp:136
LIBLLDB_LOG_EXPRESSIONS
#define LIBLLDB_LOG_EXPRESSIONS
Definition: Logging.h:22
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::Range::SetRangeEnd
void SetRangeEnd(BaseType end)
Definition: RangeMap.h:64
MinidumpParser.h
LLDBAssert.h
lldb_private::MemoryRegionInfo::GetExecutable
OptionalBool GetExecutable() const
Definition: MemoryRegionInfo.h:46
lldb_private::minidump::MinidumpParser::GetStream
llvm::ArrayRef< uint8_t > GetStream(StreamType stream_type)
Definition: MinidumpParser.cpp:46
lldb_private::ModuleList
Definition: ModuleList.h:72
Log.h
lldb_private::MemoryRegionInfo::SetExecutable
void SetExecutable(OptionalBool val)
Definition: MemoryRegionInfo.h:58
lldb_private::minidump::MinidumpParser::GetStreamTypeAsString
static llvm::StringRef GetStreamTypeAsString(StreamType stream_type)
Definition: MinidumpParser.cpp:638
lldb_private::minidump::MinidumpParser
Definition: MinidumpParser.h:50
lldb_private::ArchSpec::SetTriple
bool SetTriple(const llvm::Triple &triple)
Architecture triple setter.
Definition: ArchSpec.cpp:739
lldb_private::minidump::LinuxProcStatus
Definition: MinidumpTypes.h:92
lldb_private::minidump::MinidumpParser::GetMinidumpFile
llvm::object::MinidumpFile & GetMinidumpFile()
Definition: MinidumpParser.h:97
lldb_private::MemoryRegionInfo::eYes
@ eYes
Definition: MemoryRegionInfo.h:25
lldb_private::MemoryRegionInfos
Definition: MemoryRegionInfo.h:164
lldb_private::minidump::LinuxProcStatus::Parse
static llvm::Optional< LinuxProcStatus > Parse(llvm::ArrayRef< uint8_t > &data)
Definition: MinidumpTypes.cpp:38
lldb_private::ThreadList
Definition: ThreadList.h:26
lldb_private::minidump::MinidumpParser::GetThreads
llvm::ArrayRef< minidump::Thread > GetThreads()
Definition: MinidumpParser.cpp:82
lldb_private::ConstString
Definition: ConstString.h:40
lldb_private::minidump::MinidumpParser::m_data_sp
lldb::DataBufferSP m_data_sp
Definition: MinidumpParser.h:106
CreateRegionsCacheFromLinuxMaps
static bool CreateRegionsCacheFromLinuxMaps(MinidumpParser &parser, std::vector< MemoryRegionInfo > &regions)
Definition: MinidumpParser.cpp:261
lldb_private::minidump::MinidumpParser::GetData
llvm::ArrayRef< uint8_t > GetData()
Definition: MinidumpParser.cpp:41
lldb_private::GetLogIfAllCategoriesSet
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:58
lldb_private::MemoryRegionInfo::GetName
ConstString GetName() const
Definition: MemoryRegionInfo.h:50
CreateRegionsCacheFromMemory64List
static bool CreateRegionsCacheFromMemory64List(MinidumpParser &parser, std::vector< MemoryRegionInfo > &regions)
Definition: MinidumpParser.cpp:582
lldb_private::MemoryRegionInfo::eNo
@ eNo
Definition: MemoryRegionInfo.h:25
lldb_private::ArchSpec::IsValid
bool IsValid() const
Tests if this ArchSpec is valid.
Definition: ArchSpec.h:342
lldb_private::minidump::MinidumpParser::m_file
std::unique_ptr< llvm::object::MinidumpFile > m_file
Definition: MinidumpParser.h:107
lldb_private::minidump::CvSignature::Pdb70
@ Pdb70
lldb_private::MemoryRegionInfo::SetWritable
void SetWritable(OptionalBool val)
Definition: MemoryRegionInfo.h:56
CreateRegionsCacheFromMemoryInfoList
static bool CreateRegionsCacheFromMemoryInfoList(MinidumpParser &parser, std::vector< MemoryRegionInfo > &regions)
Definition: MinidumpParser.cpp:520
lldb_private::minidump::MinidumpParser::GetThreadContextWow64
llvm::ArrayRef< uint8_t > GetThreadContextWow64(const minidump::Thread &td)
Definition: MinidumpParser.cpp:106
lldb_private::Status
Definition: Status.h:44
lldb_private::minidump::MinidumpContext_x86_32
Definition: RegisterContextMinidump_x86_32.h:57
lldb_private::minidump::MinidumpParser::GetModuleList
llvm::ArrayRef< minidump::Module > GetModuleList()
Definition: MinidumpParser.cpp:249
uint32_t
lldb_private::minidump::MinidumpMiscInfo::Parse
static const MinidumpMiscInfo * Parse(llvm::ArrayRef< uint8_t > &data)
Definition: MinidumpTypes.cpp:18
lldb_private::UUID::CvRecordPdb70
Definition: UUID.h:29
CreateRegionsCacheFromMemoryList
static bool CreateRegionsCacheFromMemoryList(MinidumpParser &parser, std::vector< MemoryRegionInfo > &regions)
Definition: MinidumpParser.cpp:557
CheckForLinuxExecutable
static bool CheckForLinuxExecutable(ConstString path, const MemoryRegionInfos &regions, lldb::addr_t base_of_image)
Check for the memory regions starting at load_addr for a contiguous section that has execute permissi...
Definition: MinidumpParser.cpp:331
lldb_private::MemoryRegionInfo::SetMapped
void SetMapped(OptionalBool val)
Definition: MemoryRegionInfo.h:60
lldb_private::Range::SetRangeBase
void SetRangeBase(BaseType b)
Definition: RangeMap.h:48
NtStructures.h
lldb_private::Range::GetByteSize
SizeType GetByteSize() const
Definition: RangeMap.h:71
lldb_private::Range::SetByteSize
void SetByteSize(SizeType s)
Definition: RangeMap.h:73
lldb_private::minidump::consumeObject
Status consumeObject(llvm::ArrayRef< uint8_t > &Buffer, const T *&Object)
Definition: MinidumpTypes.h:50
lldb_private::minidump::MinidumpParser::GetMiscInfo
const MinidumpMiscInfo * GetMiscInfo()
Definition: MinidumpParser.cpp:217
ENUM_TO_CSTR
#define ENUM_TO_CSTR(ST)
Definition: MinidumpParser.cpp:633
lldb_private::UUID::fromCvRecord
static UUID fromCvRecord(CvRecordPdb70 debug_info)
Create a UUID from CvRecordPdb70.
Definition: UUID.cpp:38
lldb_private::MemoryRegionInfo::GetRange
RangeType & GetRange()
Definition: MemoryRegionInfo.h:36
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::minidump::MinidumpParser::GetMemoryRegionInfo
static MemoryRegionInfo GetMemoryRegionInfo(const MemoryRegionInfos &regions, lldb::addr_t load_addr)
Definition: MinidumpParser.cpp:691
lldb_private::minidump::Range
Definition: MinidumpParser.h:37
lldb_private::minidump::MinidumpParser::Create
static llvm::Expected< MinidumpParser > Create(const lldb::DataBufferSP &data_buf_sp)
Definition: MinidumpParser.cpp:28
LinuxProcMaps.h
lldb_private::minidump::MinidumpParser::BuildMemoryRegions
std::pair< MemoryRegionInfos, bool > BuildMemoryRegions()
Returns a list of memory regions and a flag indicating whether the list is complete (includes all reg...
Definition: MinidumpParser.cpp:611
lldb_private::Log
Definition: Log.h:49
lldb_private::GetLogIfAnyCategoriesSet
Log * GetLogIfAnyCategoriesSet(uint32_t mask)
Definition: Logging.cpp:62
lldb_private::UUID::fromOptionalData
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:57
lldb_private::minidump::MinidumpParser::GetMemory
llvm::ArrayRef< uint8_t > GetMemory(lldb::addr_t addr, size_t size)
Definition: MinidumpParser.cpp:496
LIBLLDB_LOG_PROCESS
#define LIBLLDB_LOG_PROCESS
Definition: Logging.h:15
LIBLLDB_LOG_THREAD
#define LIBLLDB_LOG_THREAD
Definition: Logging.h:16
LLDB_LOG_ERROR
#define LLDB_LOG_ERROR(log, error,...)
Definition: Log.h:265
lldb_private::minidump::MinidumpParser::MinidumpParser
MinidumpParser(lldb::DataBufferSP data_sp, std::unique_ptr< llvm::object::MinidumpFile > file)
Definition: MinidumpParser.cpp:37
UINT64_MAX
#define UINT64_MAX
Definition: lldb-defines.h:35
lldb_private::minidump::CvSignature
CvSignature
Definition: MinidumpTypes.h:38