dvlahovski created this revision.
dvlahovski added reviewers: labath, zturner.
dvlahovski added a subscriber: lldb-commits.
Herald added a subscriber: beanz.

Added parsing of the MiscInfo data stream.
The main member of it that we care about is the process_id
On Linux generated Minidump (from breakpad) we don't have
the MiscInfo, we have the /proc/$pid/status from where we can get the
pid.
Also parsing the module list - the list of all of the loaded
modules/shared libraries.
Finally - parsing the exception stream.

I have unit tests for all of that.
Also added some tests using a Minidump generated from Windows tools (not
from breakpad)

https://reviews.llvm.org/D24385

Files:
  source/Plugins/Process/minidump/MinidumpParser.cpp
  source/Plugins/Process/minidump/MinidumpParser.h
  source/Plugins/Process/minidump/MinidumpTypes.cpp
  source/Plugins/Process/minidump/MinidumpTypes.h
  unittests/Process/minidump/CMakeLists.txt
  unittests/Process/minidump/Inputs/fizzbuzz_no_heap.dmp
  unittests/Process/minidump/MinidumpParserTest.cpp

Index: unittests/Process/minidump/MinidumpParserTest.cpp
===================================================================
--- unittests/Process/minidump/MinidumpParserTest.cpp
+++ unittests/Process/minidump/MinidumpParserTest.cpp
@@ -44,10 +44,8 @@
     llvm::SmallString<128> filename = inputs_folder;
     llvm::sys::path::append(filename, minidump_filename);
     FileSpec minidump_file(filename.c_str(), false);
-    lldb::DataBufferSP data_sp(
-        minidump_file.MemoryMapFileContents(0, load_size));
-    llvm::Optional<MinidumpParser> optional_parser =
-        MinidumpParser::Create(data_sp);
+    lldb::DataBufferSP data_sp(minidump_file.MemoryMapFileContents(0, load_size));
+    llvm::Optional<MinidumpParser> optional_parser = MinidumpParser::Create(data_sp);
     ASSERT_TRUE(optional_parser.hasValue());
     parser.reset(new MinidumpParser(optional_parser.getValue()));
     ASSERT_GT(parser->GetByteSize(), 0UL);
@@ -80,12 +78,65 @@
 TEST_F(MinidumpParserTest, GetArchitecture) {
   SetUpData("linux-x86_64.dmp");
   ASSERT_EQ(llvm::Triple::ArchType::x86_64,
-            parser->GetArchitecture().GetTriple().getArch());
+            parser->GetArchitecture().GetMachine());
 }
 
 TEST_F(MinidumpParserTest, GetMiscInfo) {
   SetUpData("linux-x86_64.dmp");
   const MinidumpMiscInfo *misc_info = parser->GetMiscInfo();
   ASSERT_EQ(nullptr, misc_info);
-  // linux breakpad generated minidump files don't have misc info stream
+}
+
+TEST_F(MinidumpParserTest, GetLinuxProcStatus) {
+  SetUpData("linux-x86_64.dmp");
+  llvm::Optional<LinuxProcStatus> proc_status = parser->GetLinuxProcStatus();
+  ASSERT_TRUE(proc_status.hasValue());
+}
+
+TEST_F(MinidumpParserTest, GetPid) {
+  SetUpData("linux-x86_64.dmp");
+  llvm::Optional<pid_t> pid = parser->GetPid();
+  ASSERT_TRUE(pid.hasValue());
+  ASSERT_EQ(16001, pid.getValue());
+}
+
+TEST_F(MinidumpParserTest, GetModuleList) {
+  SetUpData("linux-x86_64.dmp");
+  llvm::Optional<std::vector<const MinidumpModule *>> modules = parser->GetModuleList();
+  ASSERT_TRUE(modules.hasValue());
+  ASSERT_EQ(8UL, modules->size());
+  //TODO check for specific modules here
+}
+
+TEST_F(MinidumpParserTest, GetExceptionStream) {
+  SetUpData("linux-x86_64.dmp");
+  llvm::Optional<llvm::ArrayRef<uint8_t>> data = parser->GetStream(MinidumpStreamType::Exception);
+  ASSERT_TRUE(data.hasValue());
+}
+
+
+// Windows Minidump tests
+// fizzbuzz_no_heap.dmp is copied from the WinMiniDump tests
+TEST_F(MinidumpParserTest, GetArchitectureWindows) {
+  SetUpData("fizzbuzz_no_heap.dmp");
+  ASSERT_EQ(llvm::Triple::ArchType::x86, parser->GetArchitecture().GetMachine());
+}
+
+TEST_F(MinidumpParserTest, GetLinuxProcStatusWindows) {
+  SetUpData("fizzbuzz_no_heap.dmp");
+  llvm::Optional<LinuxProcStatus> proc_status = parser->GetLinuxProcStatus();
+  ASSERT_FALSE(proc_status.hasValue());
+}
+
+TEST_F(MinidumpParserTest, GetMiscInfoWindows) {
+  SetUpData("fizzbuzz_no_heap.dmp");
+  const MinidumpMiscInfo *misc_info = parser->GetMiscInfo();
+  ASSERT_TRUE(misc_info != nullptr);
+}
+
+TEST_F(MinidumpParserTest, GetPidWindows) {
+  SetUpData("fizzbuzz_no_heap.dmp");
+  llvm::Optional<pid_t> pid = parser->GetPid();
+  ASSERT_TRUE(pid.hasValue());
+  ASSERT_EQ(4440, pid.getValue());
 }
Index: unittests/Process/minidump/CMakeLists.txt
===================================================================
--- unittests/Process/minidump/CMakeLists.txt
+++ unittests/Process/minidump/CMakeLists.txt
@@ -3,6 +3,7 @@
   )
 
 set(test_inputs
-   linux-x86_64.dmp)
+   linux-x86_64.dmp
+   fizzbuzz_no_heap.dmp)
 
 add_unittest_inputs(LLDBMinidumpTests "${test_inputs}")
Index: source/Plugins/Process/minidump/MinidumpTypes.h
===================================================================
--- source/Plugins/Process/minidump/MinidumpTypes.h
+++ source/Plugins/Process/minidump/MinidumpTypes.h
@@ -18,6 +18,9 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/BitmaskEnum.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/Endian.h"
 
 // C includes
@@ -148,6 +151,12 @@
   LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ IDIVT)
 };
 
+enum class MinidumpMiscInfoFlags : uint32_t {
+  ProcessID = (1 << 0),
+  ProcessTimes = (1 << 1),
+  LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ ProcessTimes)
+};
+
 template <typename T>
 Error consumeObject(llvm::ArrayRef<uint8_t> &Buffer, const T *&Object) {
   Error error;
@@ -161,6 +170,8 @@
   return error;
 }
 
+llvm::StringRef consumeString(llvm::ArrayRef<uint8_t> &Buffer);
+
 // Reference:
 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680378(v=vs.85).aspx
 struct MinidumpHeader {
@@ -206,6 +217,13 @@
 static_assert(sizeof(MinidumpDirectory) == 12,
               "sizeof MinidumpDirectory is not correct!");
 
+struct MinidumpString {
+  std::string buffer;
+
+  static llvm::Optional<const MinidumpString>
+  Parse(llvm::ArrayRef<uint8_t> &data);
+};
+
 // Reference:
 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680517(v=vs.85).aspx
 struct MinidumpThread {
@@ -272,23 +290,98 @@
 static_assert(sizeof(MinidumpSystemInfo) == 56,
               "sizeof MinidumpSystemInfo is not correct!");
 
-// TODO check flags to see what's valid
 // TODO misc2, misc3 ?
 // Reference:
 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680389(v=vs.85).aspx
 struct MinidumpMiscInfo {
   llvm::support::ulittle32_t size;
-  llvm::support::ulittle32_t flags1;
+  llvm::support::ulittle32_t flags1; // represent what info in the struct is valid
   llvm::support::ulittle32_t process_id;
   llvm::support::ulittle32_t process_create_time;
   llvm::support::ulittle32_t process_user_time;
   llvm::support::ulittle32_t process_kernel_time;
 
   static const MinidumpMiscInfo *Parse(llvm::ArrayRef<uint8_t> &data);
+
+  static llvm::Optional<pid_t> GetPid(const MinidumpMiscInfo &misc_info);
 };
 static_assert(sizeof(MinidumpMiscInfo) == 24,
               "sizeof MinidumpMiscInfo is not correct!");
 
+// The /proc/pid/status is saved as an ascii string in the file
+struct LinuxProcStatus {
+  llvm::StringRef proc_status;
+
+  static LinuxProcStatus Parse(llvm::ArrayRef<uint8_t> &data);
+
+  static llvm::Optional<pid_t> GetPid(const LinuxProcStatus &misc_info);
+};
+
+// MinidumpModule stuff
+struct MinidumpVSFixedFileInfo {
+  llvm::support::ulittle32_t signature;
+  llvm::support::ulittle32_t struct_version;
+  llvm::support::ulittle32_t file_version_hi;
+  llvm::support::ulittle32_t file_version_lo;
+  llvm::support::ulittle32_t product_version_hi;
+  llvm::support::ulittle32_t product_version_lo;
+  llvm::support::ulittle32_t file_flags_mask; // Identifies valid bits in fileFlags
+  llvm::support::ulittle32_t file_flags;
+  llvm::support::ulittle32_t file_os;
+  llvm::support::ulittle32_t file_type;
+  llvm::support::ulittle32_t file_subtype;
+  llvm::support::ulittle32_t file_date_hi;
+  llvm::support::ulittle32_t file_date_lo;
+};
+static_assert(sizeof(MinidumpVSFixedFileInfo) == 52,
+              "sizeof MinidumpVSFixedFileInfo is not correct!");
+
+struct MinidumpModule {
+  llvm::support::ulittle64_t base_of_image;
+  llvm::support::ulittle32_t size_of_image;
+  llvm::support::ulittle32_t checksum;
+  llvm::support::ulittle32_t time_date_stamp;
+  llvm::support::ulittle32_t module_name_rva;
+  MinidumpVSFixedFileInfo version_info;
+  MinidumpLocationDescriptor CV_record;
+  MinidumpLocationDescriptor misc_record;
+  llvm::support::ulittle32_t reserved0[2];
+  llvm::support::ulittle32_t reserved1[2];
+
+  static const MinidumpModule *Parse(llvm::ArrayRef<uint8_t> &data);
+
+  static llvm::Optional<std::vector<const MinidumpModule *>>
+  ParseModuleList(llvm::ArrayRef<uint8_t> &data);
+};
+static_assert(sizeof(MinidumpModule) == 108,
+              "sizeof MinidumpVSFixedFileInfo is not correct!");
+
+// Exception stuff
+struct MinidumpException {
+  enum {
+    MaxParams = 15,
+  };
+
+  llvm::support::ulittle32_t exception_code;
+  llvm::support::ulittle32_t exception_flags;
+  llvm::support::ulittle64_t exception_record;
+  llvm::support::ulittle64_t exception_address;
+  llvm::support::ulittle32_t number_parameters;
+  llvm::support::ulittle32_t unused_alignment;
+  llvm::support::ulittle64_t exception_information[MaxParams];
+};
+static_assert(sizeof(MinidumpException) == 152, "sizeof MinidumpException is not correct!");
+
+struct MinidumpExceptionStream {
+  llvm::support::ulittle32_t thread_id;
+  llvm::support::ulittle32_t alignment;
+  MinidumpException exception_record;
+  MinidumpLocationDescriptor thread_context;
+
+  static const MinidumpExceptionStream * Parse(llvm::ArrayRef<uint8_t> &data);
+};
+static_assert(sizeof(MinidumpExceptionStream) == 168, "sizeof MinidumpExceptionStream is not correct!");
+
 } // namespace minidump
 } // namespace lldb_private
 #endif // liblldb_MinidumpTypes_h_
Index: source/Plugins/Process/minidump/MinidumpTypes.cpp
===================================================================
--- source/Plugins/Process/minidump/MinidumpTypes.cpp
+++ source/Plugins/Process/minidump/MinidumpTypes.cpp
@@ -9,25 +9,25 @@
 
 // Project includes
 #include "MinidumpTypes.h"
-#include "MinidumpParser.h"
 
 // Other libraries and framework includes
 // C includes
 // C++ includes
 
 using namespace lldb_private;
 using namespace minidump;
 
+llvm::StringRef
+lldb_private::minidump::consumeString(llvm::ArrayRef<uint8_t> &Buffer) {
+  return llvm::StringRef(reinterpret_cast<const char *>(Buffer.data()), Buffer.size());
+}
+
 const MinidumpHeader *MinidumpHeader::Parse(llvm::ArrayRef<uint8_t> &data) {
   const MinidumpHeader *header = nullptr;
   Error error = consumeObject(data, header);
 
-  const MinidumpHeaderConstants signature =
-      static_cast<const MinidumpHeaderConstants>(
-          static_cast<const uint32_t>(header->signature));
-  const MinidumpHeaderConstants version =
-      static_cast<const MinidumpHeaderConstants>(
-          static_cast<const uint32_t>(header->version) & 0x0000ffff);
+  const MinidumpHeaderConstants signature = static_cast<const MinidumpHeaderConstants>(static_cast<const uint32_t>(header->signature));
+  const MinidumpHeaderConstants version = static_cast<const MinidumpHeaderConstants>(static_cast<const uint32_t>(header->version) & 0x0000ffff);
   // the high 16 bits of the version field are implementation specific
 
   if (error.Fail() || signature != MinidumpHeaderConstants::Signature ||
@@ -40,6 +40,31 @@
   return header;
 }
 
+// Minidump string
+llvm::Optional<const MinidumpString>
+MinidumpString::Parse(llvm::ArrayRef<uint8_t> &data) {
+  std::string result;
+
+  const uint32_t *source_length;
+  Error error = consumeObject(data, source_length);
+  if (error.Fail() || *source_length > data.size())
+    return llvm::None;
+
+  auto source_start = reinterpret_cast<const UTF16 *>(data.data());
+  const auto source_end = source_start + (*source_length);
+  result.resize(UNI_MAX_UTF8_BYTES_PER_CODE_POINT * (*source_length)); // worst case length
+  auto result_start = reinterpret_cast<UTF8 *>(&result[0]);
+  const auto result_end = result_start + result.size();
+  ConvertUTF16toUTF8(&source_start, source_end, &result_start, result_end, strictConversion);
+  const auto result_size = std::distance(reinterpret_cast<UTF8 *>(&result[0]), result_start);
+  result.resize(result_size); // shrink to actual length
+
+  MinidumpString str;
+  str.buffer = result;
+
+  return str;
+}
+
 // MinidumpThread
 const MinidumpThread *MinidumpThread::Parse(llvm::ArrayRef<uint8_t> &data) {
   const MinidumpThread *thread = nullptr;
@@ -82,11 +107,84 @@
 }
 
 // MinidumpMiscInfo
-const MinidumpMiscInfo *MinidumpMiscInfo::Parse(llvm::ArrayRef<uint8_t> &data) {
+const MinidumpMiscInfo * MinidumpMiscInfo::Parse(llvm::ArrayRef<uint8_t> &data) {
   const MinidumpMiscInfo *misc_info;
   Error error = consumeObject(data, misc_info);
   if (error.Fail())
     return nullptr;
 
   return misc_info;
 }
+
+llvm::Optional<pid_t>
+MinidumpMiscInfo::GetPid(const MinidumpMiscInfo &misc_info) {
+  uint32_t pid_flag = static_cast<const uint32_t>(MinidumpMiscInfoFlags::ProcessID);
+  if (misc_info.flags1 & pid_flag)
+    return llvm::Optional<pid_t>(misc_info.process_id);
+
+  return llvm::None;
+}
+
+// Linux Proc Status
+LinuxProcStatus LinuxProcStatus::Parse(llvm::ArrayRef<uint8_t> &data) {
+  LinuxProcStatus result;
+  result.proc_status = consumeString(data);
+  return result;
+}
+
+llvm::Optional<pid_t>
+LinuxProcStatus::GetPid(const LinuxProcStatus &proc_status) {
+  pid_t pid;
+  llvm::SmallVector<llvm::StringRef, 42> lines;
+  proc_status.proc_status.split(lines, '\n', 42);
+  for (auto line : lines) {
+    if (line.consume_front("Pid:")) {
+      line = line.trim();
+      if (!line.getAsInteger(10, pid))
+        return llvm::Optional<pid_t>(pid);
+    }
+  }
+
+  return llvm::None;
+}
+
+// Module stuff
+const MinidumpModule * MinidumpModule::Parse(llvm::ArrayRef<uint8_t> &data) {
+  const MinidumpModule *module = nullptr;
+  Error error = consumeObject(data, module);
+  if (error.Fail())
+    return nullptr;
+
+  return module;
+}
+
+llvm::Optional<std::vector<const MinidumpModule *>>
+MinidumpModule::ParseModuleList(llvm::ArrayRef<uint8_t> &data) {
+  std::vector<const MinidumpModule *> module_list;
+
+  const llvm::support::ulittle32_t *modules_count;
+  Error error = consumeObject(data, modules_count);
+  if (error.Fail())
+    return llvm::None;
+
+  const MinidumpModule *module;
+  for (uint32_t i = 0; i < *modules_count; ++i) {
+    module = MinidumpModule::Parse(data);
+    if (module == nullptr)
+      return llvm::None;
+    module_list.push_back(module);
+  }
+
+  return llvm::Optional<std::vector<const MinidumpModule *>>(module_list);
+}
+
+// Exception stuff
+const MinidumpExceptionStream *
+MinidumpExceptionStream::Parse(llvm::ArrayRef<uint8_t> &data) {
+  const MinidumpExceptionStream *exception_stream = nullptr;
+  Error error = consumeObject(data, exception_stream);
+  if (error.Fail())
+    return nullptr;
+
+  return exception_stream;
+}
Index: source/Plugins/Process/minidump/MinidumpParser.h
===================================================================
--- source/Plugins/Process/minidump/MinidumpParser.h
+++ source/Plugins/Process/minidump/MinidumpParser.h
@@ -22,6 +22,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
 
 // C includes
 
@@ -43,14 +44,24 @@
   llvm::Optional<llvm::ArrayRef<uint8_t>>
   GetStream(MinidumpStreamType stream_type);
 
+  llvm::Optional<const MinidumpString> GetMinidumpString(uint32_t rva);
+
   llvm::Optional<std::vector<const MinidumpThread *>> GetThreads();
 
   const MinidumpSystemInfo *GetSystemInfo();
 
   ArchSpec GetArchitecture();
 
   const MinidumpMiscInfo *GetMiscInfo();
 
+  llvm::Optional<LinuxProcStatus> GetLinuxProcStatus();
+
+  llvm::Optional<pid_t> GetPid();
+
+  llvm::Optional<std::vector<const MinidumpModule *>> GetModuleList();
+
+  const MinidumpExceptionStream *GetExceptionStream();
+
 private:
   lldb::DataBufferSP m_data_sp;
   const MinidumpHeader *m_header;
Index: source/Plugins/Process/minidump/MinidumpParser.cpp
===================================================================
--- source/Plugins/Process/minidump/MinidumpParser.cpp
+++ source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -1,5 +1,4 @@
-//===-- MinidumpParser.cpp ---------------------------------------*- C++
-//-*-===//
+//===-- MinidumpParser.cpp ---------------------------------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -34,37 +33,29 @@
 
   lldb::offset_t directory_list_offset = header->stream_directory_rva;
   // check if there is enough data for the parsing of the directory list
-  if ((directory_list_offset +
-       sizeof(MinidumpDirectory) * header->streams_count) >
-      data_buf_sp->GetByteSize()) {
+  if ((directory_list_offset + sizeof(MinidumpDirectory) * header->streams_count) > data_buf_sp->GetByteSize()) {
     return llvm::None;
   }
 
   const MinidumpDirectory *directory = nullptr;
   Error error;
-  llvm::ArrayRef<uint8_t> directory_data(
-      data_buf_sp->GetBytes() + directory_list_offset,
-      sizeof(MinidumpDirectory) * header->streams_count);
+  llvm::ArrayRef<uint8_t> directory_data(data_buf_sp->GetBytes() + directory_list_offset, sizeof(MinidumpDirectory) * header->streams_count);
   llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> directory_map;
 
   for (uint32_t i = 0; i < header->streams_count; ++i) {
     error = consumeObject(directory_data, directory);
     if (error.Fail()) {
       return llvm::None;
     }
-    directory_map[static_cast<const uint32_t>(directory->stream_type)] =
-        directory->location;
+    directory_map[static_cast<const uint32_t>(directory->stream_type)] = directory->location;
   }
 
-  MinidumpParser parser(data_buf_sp, header, directory_map);
-  return llvm::Optional<MinidumpParser>(parser);
+  return MinidumpParser(data_buf_sp, header, directory_map);
 }
 
-MinidumpParser::MinidumpParser(
-    const lldb::DataBufferSP &data_buf_sp, const MinidumpHeader *header,
-    const llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> &directory_map)
-    : m_data_sp(data_buf_sp), m_header(header), m_directory_map(directory_map) {
-}
+MinidumpParser::MinidumpParser(const lldb::DataBufferSP &data_buf_sp, const MinidumpHeader *header, const llvm::DenseMap<uint32_t, MinidumpLocationDescriptor> &directory_map)
+    : m_data_sp(data_buf_sp), m_header(header),
+      m_directory_map(std::move(directory_map)) {}
 
 lldb::offset_t MinidumpParser::GetByteSize() {
   return m_data_sp->GetByteSize();
@@ -80,25 +71,28 @@
   if (iter->second.rva + iter->second.data_size > m_data_sp->GetByteSize())
     return llvm::None;
 
-  llvm::ArrayRef<uint8_t> arr_ref(m_data_sp->GetBytes() + iter->second.rva,
-                                  iter->second.data_size);
+  llvm::ArrayRef<uint8_t> arr_ref(m_data_sp->GetBytes() + iter->second.rva, iter->second.data_size);
   return llvm::Optional<llvm::ArrayRef<uint8_t>>(arr_ref);
 }
 
+llvm::Optional<const MinidumpString>
+MinidumpParser::GetMinidumpString(uint32_t rva) {
+  llvm::ArrayRef<uint8_t> arr_ref(m_data_sp->GetBytes() + rva, m_data_sp->GetByteSize() - rva);
+  return MinidumpString::Parse(arr_ref);
+}
+
 llvm::Optional<std::vector<const MinidumpThread *>>
 MinidumpParser::GetThreads() {
-  llvm::Optional<llvm::ArrayRef<uint8_t>> data =
-      GetStream(MinidumpStreamType::ThreadList);
+  llvm::Optional<llvm::ArrayRef<uint8_t>> data = GetStream(MinidumpStreamType::ThreadList);
 
   if (!data)
     return llvm::None;
 
   return MinidumpThread::ParseThreadList(data.getValue());
 }
 
 const MinidumpSystemInfo *MinidumpParser::GetSystemInfo() {
-  llvm::Optional<llvm::ArrayRef<uint8_t>> data =
-      GetStream(MinidumpStreamType::SystemInfo);
+  llvm::Optional<llvm::ArrayRef<uint8_t>> data = GetStream(MinidumpStreamType::SystemInfo);
 
   if (!data)
     return nullptr;
@@ -122,33 +116,81 @@
   // TODO what to do about big endiand flavors of arm ?
   // TODO set the arm subarch stuff if the minidump has info about it
 
-  const MinidumpCPUArchitecture arch =
-      static_cast<const MinidumpCPUArchitecture>(
-          static_cast<const uint32_t>(system_info->processor_arch));
+  llvm::Triple triple;
+
+  const MinidumpCPUArchitecture arch = static_cast<const MinidumpCPUArchitecture>(static_cast<const uint32_t>(system_info->processor_arch));
+
   switch (arch) {
-  case MinidumpCPUArchitecture::X86:
-    arch_spec.GetTriple().setArch(llvm::Triple::ArchType::x86);
-    break;
-  case MinidumpCPUArchitecture::AMD64:
-    arch_spec.GetTriple().setArch(llvm::Triple::ArchType::x86_64);
-    break;
-  case MinidumpCPUArchitecture::ARM:
-    arch_spec.GetTriple().setArch(llvm::Triple::ArchType::arm);
-    break;
-  case MinidumpCPUArchitecture::ARM64:
-    arch_spec.GetTriple().setArch(llvm::Triple::ArchType::aarch64);
-    break;
+    case MinidumpCPUArchitecture::X86:
+      triple.setArch(llvm::Triple::ArchType::x86);
+      break;
+    case MinidumpCPUArchitecture::AMD64:
+      triple.setArch(llvm::Triple::ArchType::x86_64);
+      break;
+    case MinidumpCPUArchitecture::ARM:
+      triple.setArch(llvm::Triple::ArchType::arm);
+      break;
+    case MinidumpCPUArchitecture::ARM64:
+      triple.setArch(llvm::Triple::ArchType::aarch64);
+      break;
+    default:
+      triple.setArch(llvm::Triple::ArchType::UnknownArch);
+      break;
   }
 
+  triple.setOS(llvm::Triple::OSType::Linux);
+  arch_spec.SetTriple(triple);
+
   return arch_spec;
 }
 
 const MinidumpMiscInfo *MinidumpParser::GetMiscInfo() {
-  llvm::Optional<llvm::ArrayRef<uint8_t>> data =
-      GetStream(MinidumpStreamType::MiscInfo);
+  llvm::Optional<llvm::ArrayRef<uint8_t>> data = GetStream(MinidumpStreamType::MiscInfo);
 
   if (!data)
     return nullptr;
 
   return MinidumpMiscInfo::Parse(data.getValue());
 }
+
+llvm::Optional<LinuxProcStatus> MinidumpParser::GetLinuxProcStatus() {
+  llvm::Optional<llvm::ArrayRef<uint8_t>> data = GetStream(MinidumpStreamType::LinuxProcStatus);
+
+  if (!data)
+    return llvm::None;
+
+  return LinuxProcStatus::Parse(data.getValue());
+}
+
+llvm::Optional<pid_t> MinidumpParser::GetPid() {
+  const MinidumpMiscInfo *misc_info = GetMiscInfo();
+  if (misc_info != nullptr) {
+    return MinidumpMiscInfo::GetPid(*misc_info);
+  }
+
+  llvm::Optional<LinuxProcStatus> proc_status = GetLinuxProcStatus();
+  if (proc_status.hasValue()) {
+    return LinuxProcStatus::GetPid(proc_status.getValue());
+  }
+
+  return llvm::None;
+}
+
+llvm::Optional<std::vector<const MinidumpModule *>>
+MinidumpParser::GetModuleList() {
+  llvm::Optional<llvm::ArrayRef<uint8_t>> data = GetStream(MinidumpStreamType::ModuleList);
+
+  if (!data)
+    return llvm::None;
+
+  return MinidumpModule::ParseModuleList(data.getValue());
+}
+
+const MinidumpExceptionStream * MinidumpParser::GetExceptionStream() {
+  llvm::Optional<llvm::ArrayRef<uint8_t>> data = GetStream(MinidumpStreamType::Exception);
+
+  if (!data)
+    return nullptr;
+
+  return MinidumpExceptionStream::Parse(data.getValue());
+}
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to