[Lldb-commits] [lldb] r357977 - Minidump: use string parsing functionality from llvm

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Tue Apr 9 01:28:27 PDT 2019


Author: labath
Date: Tue Apr  9 01:28:27 2019
New Revision: 357977

URL: http://llvm.org/viewvc/llvm-project?rev=357977&view=rev
Log:
Minidump: use string parsing functionality from llvm

Modified:
    lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.cpp
    lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.h
    lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.cpp
    lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.h
    lldb/trunk/source/Plugins/Process/minidump/ProcessMinidump.cpp
    lldb/trunk/unittests/Process/minidump/MinidumpParserTest.cpp

Modified: lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.cpp?rev=357977&r1=357976&r2=357977&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.cpp (original)
+++ lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.cpp Tue Apr  9 01:28:27 2019
@@ -63,14 +63,6 @@ llvm::ArrayRef<uint8_t> MinidumpParser::
       .getValueOr(llvm::ArrayRef<uint8_t>());
 }
 
-llvm::Optional<std::string> MinidumpParser::GetMinidumpString(uint32_t rva) {
-  auto arr_ref = m_data_sp->GetData();
-  if (rva > arr_ref.size())
-    return llvm::None;
-  arr_ref = arr_ref.drop_front(rva);
-  return parseMinidumpString(arr_ref);
-}
-
 UUID MinidumpParser::GetModuleUUID(const MinidumpModule *module) {
   auto cv_record =
       GetData().slice(module->CV_record.RVA, module->CV_record.DataSize);
@@ -244,13 +236,17 @@ ArchSpec MinidumpParser::GetArchitecture
     break;
   default: {
     triple.setOS(llvm::Triple::OSType::UnknownOS);
-    std::string csd_version;
-    if (auto s = GetMinidumpString(system_info->CSDVersionRVA))
-      csd_version = *s;
-    if (csd_version.find("Linux") != std::string::npos)
-      triple.setOS(llvm::Triple::OSType::Linux);
-    break;
+    auto ExpectedCSD = m_file->getString(system_info->CSDVersionRVA);
+    if (!ExpectedCSD) {
+      LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS),
+                     ExpectedCSD.takeError(),
+                     "Failed to CSD Version string: {0}");
+    } else {
+      if (ExpectedCSD->find("Linux") != std::string::npos)
+        triple.setOS(llvm::Triple::OSType::Linux);
     }
+    break;
+  }
   }
   m_arch.SetTriple(triple);
   return m_arch;
@@ -305,24 +301,22 @@ std::vector<const MinidumpModule *> Mini
 
   std::vector<const MinidumpModule *> filtered_modules;
   
-  llvm::Optional<std::string> name;
-  std::string module_name;
-
   for (const auto &module : modules) {
-    name = GetMinidumpString(module.module_name_rva);
-    
-    if (!name)
+    auto ExpectedName = m_file->getString(module.module_name_rva);
+    if (!ExpectedName) {
+      LLDB_LOG_ERROR(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES),
+                     ExpectedName.takeError(),
+                     "Failed to module name: {0}");
       continue;
-    
-    module_name = name.getValue();
-    
+    }
+
     MapType::iterator iter;
     bool inserted;
     // See if we have inserted this module aready into filtered_modules. If we
     // haven't insert an entry into module_name_to_filtered_index with the
     // index where we will insert it if it isn't in the vector already.
     std::tie(iter, inserted) = module_name_to_filtered_index.try_emplace(
-        module_name, filtered_modules.size());
+        *ExpectedName, filtered_modules.size());
 
     if (inserted) {
       // This module has not been seen yet, insert it into filtered_modules at

Modified: lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.h?rev=357977&r1=357976&r2=357977&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.h (original)
+++ lldb/trunk/source/Plugins/Process/minidump/MinidumpParser.h Tue Apr  9 01:28:27 2019
@@ -52,8 +52,6 @@ public:
 
   llvm::ArrayRef<uint8_t> GetStream(StreamType stream_type);
 
-  llvm::Optional<std::string> GetMinidumpString(uint32_t rva);
-
   UUID GetModuleUUID(const MinidumpModule* module);
 
   llvm::ArrayRef<MinidumpThread> GetThreads();

Modified: lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.cpp?rev=357977&r1=357976&r2=357977&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.cpp (original)
+++ lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.cpp Tue Apr  9 01:28:27 2019
@@ -14,43 +14,6 @@
 using namespace lldb_private;
 using namespace minidump;
 
-// Minidump string
-llvm::Optional<std::string>
-lldb_private::minidump::parseMinidumpString(llvm::ArrayRef<uint8_t> &data) {
-  std::string result;
-
-  const llvm::support::ulittle32_t *source_length;
-  Status error = consumeObject(data, source_length);
-
-  if (error.Fail() || *source_length > data.size() || *source_length % 2 != 0)
-    return llvm::None;
-
-  auto *source_start =
-      reinterpret_cast<const llvm::support::ulittle16_t *>(data.data());
-  // source_length is the length of the string in bytes we need the length of
-  // the string in UTF-16 characters/code points (16 bits per char) that's why
-  // it's divided by 2
-  uint32_t utf16_length = *source_length / 2;
-
-  // Correct the endianness and alignment of the string.
-  llvm::SmallVector<llvm::UTF16, 64> utf16(utf16_length, 0);
-  std::copy_n(source_start, utf16_length, utf16.begin());
-
-  const llvm::UTF16 *utf16_start = utf16.begin();
-
-  // resize to worst case length
-  result.resize(UNI_MAX_UTF8_BYTES_PER_CODE_POINT * utf16_length);
-  auto result_start = reinterpret_cast<llvm::UTF8 *>(&result[0]);
-  const auto result_end = result_start + result.size();
-  llvm::ConvertUTF16toUTF8(&utf16_start, utf16.end(), &result_start, result_end,
-                           llvm::strictConversion);
-  const auto result_size =
-      std::distance(reinterpret_cast<llvm::UTF8 *>(&result[0]), result_start);
-  result.resize(result_size); // shrink to actual length
-
-  return result;
-}
-
 // MinidumpThread
 const MinidumpThread *MinidumpThread::Parse(llvm::ArrayRef<uint8_t> &data) {
   const MinidumpThread *thread = nullptr;

Modified: lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.h?rev=357977&r1=357976&r2=357977&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.h (original)
+++ lldb/trunk/source/Plugins/Process/minidump/MinidumpTypes.h Tue Apr  9 01:28:27 2019
@@ -70,11 +70,6 @@ Status consumeObject(llvm::ArrayRef<uint
   return error;
 }
 
-// parse a MinidumpString which is with UTF-16
-// Reference:
-// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680395(v=vs.85).aspx
-llvm::Optional<std::string> parseMinidumpString(llvm::ArrayRef<uint8_t> &data);
-
 // Reference:
 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680384(v=vs.85).aspx
 struct MinidumpMemoryDescriptor {

Modified: lldb/trunk/source/Plugins/Process/minidump/ProcessMinidump.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/minidump/ProcessMinidump.cpp?rev=357977&r1=357976&r2=357977&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/minidump/ProcessMinidump.cpp (original)
+++ lldb/trunk/source/Plugins/Process/minidump/ProcessMinidump.cpp Tue Apr  9 01:28:27 2019
@@ -354,34 +354,21 @@ void ProcessMinidump::ReadModuleList() {
   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES));
 
   for (auto module : filtered_modules) {
-    llvm::Optional<std::string> name =
-        m_minidump_parser->GetMinidumpString(module->module_name_rva);
-
-    if (!name)
-      continue;
-
-    if (log) {
-      log->Printf("ProcessMinidump::%s found module: name: %s %#010" PRIx64
-                  "-%#010" PRIx64 " size: %" PRIu32,
-                  __FUNCTION__, name.getValue().c_str(),
-                  uint64_t(module->base_of_image),
-                  module->base_of_image + module->size_of_image,
-                  uint32_t(module->size_of_image));
-    }
+    std::string name = cantFail(m_minidump_parser->GetMinidumpFile().getString(
+        module->module_name_rva));
+    LLDB_LOG(log, "found module: name: {0} {1:x10}-{2:x10} size: {3}", name,
+             module->base_of_image,
+             module->base_of_image + module->size_of_image,
+             module->size_of_image);
 
     // check if the process is wow64 - a 32 bit windows process running on a
     // 64 bit windows
-    if (llvm::StringRef(name.getValue()).endswith_lower("wow64.dll")) {
+    if (llvm::StringRef(name).endswith_lower("wow64.dll")) {
       m_is_wow64 = true;
     }
 
-    if (log) {
-      log->Printf("ProcessMinidump::%s load module: name: %s", __FUNCTION__,
-                  name.getValue().c_str());
-    }
-
     const auto uuid = m_minidump_parser->GetModuleUUID(module);
-    auto file_spec = FileSpec(name.getValue(), GetArchitecture().GetTriple());
+    auto file_spec = FileSpec(name, GetArchitecture().GetTriple());
     FileSystem::Instance().Resolve(file_spec);
     ModuleSpec module_spec(file_spec, uuid);
     module_spec.GetArchitecture() = GetArchitecture();
@@ -424,11 +411,10 @@ void ProcessMinidump::ReadModuleList() {
       // This enables most LLDB functionality involving address-to-module
       // translations (ex. identifing the module for a stack frame PC) and
       // modules/sections commands (ex. target modules list, ...)
-      if (log) {
-        log->Printf("Unable to locate the matching object file, creating a "
-                    "placeholder module for: %s",
-                    name.getValue().c_str());
-      }
+      LLDB_LOG(log,
+               "Unable to locate the matching object file, creating a "
+               "placeholder module for: {0}",
+               name);
 
       module_sp = Module::CreateModuleFromObjectFile<PlaceholderObjectFile>(
           module_spec, module->base_of_image, module->size_of_image);

Modified: lldb/trunk/unittests/Process/minidump/MinidumpParserTest.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/unittests/Process/minidump/MinidumpParserTest.cpp?rev=357977&r1=357976&r2=357977&view=diff
==============================================================================
--- lldb/trunk/unittests/Process/minidump/MinidumpParserTest.cpp (original)
+++ lldb/trunk/unittests/Process/minidump/MinidumpParserTest.cpp Tue Apr  9 01:28:27 2019
@@ -222,23 +222,28 @@ TEST_F(MinidumpParserTest, GetModuleList
   SetUpData("linux-x86_64.dmp");
   llvm::ArrayRef<MinidumpModule> modules = parser->GetModuleList();
   ASSERT_EQ(8UL, modules.size());
-  std::string module_names[8] = {
-      "/usr/local/google/home/dvlahovski/projects/test_breakpad/a.out",
-      "/lib/x86_64-linux-gnu/libm-2.19.so",
-      "/lib/x86_64-linux-gnu/libc-2.19.so",
-      "/lib/x86_64-linux-gnu/libgcc_s.so.1",
-      "/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19",
-      "/lib/x86_64-linux-gnu/libpthread-2.19.so",
-      "/lib/x86_64-linux-gnu/ld-2.19.so",
-      "linux-gate.so",
+  const auto &getName = [&](size_t i) {
+    return parser->GetMinidumpFile().getString(modules[i].module_name_rva);
   };
 
-  for (int i = 0; i < 8; ++i) {
-    llvm::Optional<std::string> name =
-        parser->GetMinidumpString(modules[i].module_name_rva);
-    ASSERT_TRUE(name.hasValue());
-    EXPECT_EQ(module_names[i], name.getValue());
-  }
+  EXPECT_THAT_EXPECTED(
+      getName(0),
+      llvm::HasValue(
+          "/usr/local/google/home/dvlahovski/projects/test_breakpad/a.out"));
+  EXPECT_THAT_EXPECTED(getName(1),
+                       llvm::HasValue("/lib/x86_64-linux-gnu/libm-2.19.so"));
+  EXPECT_THAT_EXPECTED(getName(2),
+                       llvm::HasValue("/lib/x86_64-linux-gnu/libc-2.19.so"));
+  EXPECT_THAT_EXPECTED(getName(3),
+                       llvm::HasValue("/lib/x86_64-linux-gnu/libgcc_s.so.1"));
+  EXPECT_THAT_EXPECTED(
+      getName(4),
+      llvm::HasValue("/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.19"));
+  EXPECT_THAT_EXPECTED(
+      getName(5), llvm::HasValue("/lib/x86_64-linux-gnu/libpthread-2.19.so"));
+  EXPECT_THAT_EXPECTED(getName(6),
+                       llvm::HasValue("/lib/x86_64-linux-gnu/ld-2.19.so"));
+  EXPECT_THAT_EXPECTED(getName(7), llvm::HasValue("linux-gate.so"));
 }
 
 TEST_F(MinidumpParserTest, GetFilteredModuleList) {
@@ -248,19 +253,12 @@ TEST_F(MinidumpParserTest, GetFilteredMo
       parser->GetFilteredModuleList();
   EXPECT_EQ(10UL, modules.size());
   EXPECT_EQ(9UL, filtered_modules.size());
-  // EXPECT_GT(modules.size(), filtered_modules.size());
-  bool found = false;
-  for (size_t i = 0; i < filtered_modules.size(); ++i) {
-    llvm::Optional<std::string> name =
-        parser->GetMinidumpString(filtered_modules[i]->module_name_rva);
-    ASSERT_TRUE(name.hasValue());
-    if (name.getValue() == "/tmp/test/linux-x86_64_not_crashed") {
-      ASSERT_FALSE(found) << "There should be only one module with this name "
-                             "in the filtered module list";
-      found = true;
-      ASSERT_EQ(0x400000UL, filtered_modules[i]->base_of_image);
-    }
-  }
+  std::vector<std::string> names;
+  for (const MinidumpModule *m : filtered_modules)
+    names.push_back(
+        cantFail(parser->GetMinidumpFile().getString(m->module_name_rva)));
+
+  EXPECT_EQ(1u, llvm::count(names, "/tmp/test/linux-x86_64_not_crashed"));
 }
 
 TEST_F(MinidumpParserTest, GetExceptionStream) {
@@ -500,31 +498,50 @@ TEST_F(MinidumpParserTest, GetModuleList
   SetUpData("fizzbuzz_wow64.dmp");
   llvm::ArrayRef<MinidumpModule> modules = parser->GetModuleList();
   ASSERT_EQ(16UL, modules.size());
-  std::string module_names[16] = {
-      R"(D:\src\llvm\llvm\tools\lldb\packages\Python\lldbsuite\test\functionalities\postmortem\wow64_minidump\fizzbuzz.exe)",
-      R"(C:\Windows\System32\ntdll.dll)",
-      R"(C:\Windows\System32\wow64.dll)",
-      R"(C:\Windows\System32\wow64win.dll)",
-      R"(C:\Windows\System32\wow64cpu.dll)",
-      R"(D:\src\llvm\llvm\tools\lldb\packages\Python\lldbsuite\test\functionalities\postmortem\wow64_minidump\fizzbuzz.exe)",
-      R"(C:\Windows\SysWOW64\ntdll.dll)",
-      R"(C:\Windows\SysWOW64\kernel32.dll)",
-      R"(C:\Windows\SysWOW64\KERNELBASE.dll)",
-      R"(C:\Windows\SysWOW64\advapi32.dll)",
-      R"(C:\Windows\SysWOW64\msvcrt.dll)",
-      R"(C:\Windows\SysWOW64\sechost.dll)",
-      R"(C:\Windows\SysWOW64\rpcrt4.dll)",
-      R"(C:\Windows\SysWOW64\sspicli.dll)",
-      R"(C:\Windows\SysWOW64\CRYPTBASE.dll)",
-      R"(C:\Windows\System32\api-ms-win-core-synch-l1-2-0.DLL)",
+  const auto &getName = [&](size_t i) {
+    return parser->GetMinidumpFile().getString(modules[i].module_name_rva);
   };
 
-  for (int i = 0; i < 16; ++i) {
-    llvm::Optional<std::string> name =
-        parser->GetMinidumpString(modules[i].module_name_rva);
-    ASSERT_TRUE(name.hasValue());
-    EXPECT_EQ(module_names[i], name.getValue());
-  }
+  EXPECT_THAT_EXPECTED(
+      getName(0),
+      llvm::HasValue(
+          R"(D:\src\llvm\llvm\tools\lldb\packages\Python\lldbsuite\test\functionalities\postmortem\wow64_minidump\fizzbuzz.exe)"));
+  EXPECT_THAT_EXPECTED(getName(1), llvm::HasValue(
+                                       R"(C:\Windows\System32\ntdll.dll)"));
+  EXPECT_THAT_EXPECTED(getName(2), llvm::HasValue(
+                                       R"(C:\Windows\System32\wow64.dll)"));
+  EXPECT_THAT_EXPECTED(getName(3), llvm::HasValue(
+                                       R"(C:\Windows\System32\wow64win.dll)"));
+  EXPECT_THAT_EXPECTED(getName(4), llvm::HasValue(
+                                       R"(C:\Windows\System32\wow64cpu.dll)"));
+  EXPECT_THAT_EXPECTED(
+      getName(5),
+      llvm::HasValue(
+          R"(D:\src\llvm\llvm\tools\lldb\packages\Python\lldbsuite\test\functionalities\postmortem\wow64_minidump\fizzbuzz.exe)"));
+  EXPECT_THAT_EXPECTED(getName(6), llvm::HasValue(
+                                       R"(C:\Windows\SysWOW64\ntdll.dll)"));
+  EXPECT_THAT_EXPECTED(getName(7), llvm::HasValue(
+                                       R"(C:\Windows\SysWOW64\kernel32.dll)"));
+  EXPECT_THAT_EXPECTED(getName(8),
+                       llvm::HasValue(
+                           R"(C:\Windows\SysWOW64\KERNELBASE.dll)"));
+  EXPECT_THAT_EXPECTED(getName(9), llvm::HasValue(
+                                       R"(C:\Windows\SysWOW64\advapi32.dll)"));
+  EXPECT_THAT_EXPECTED(getName(10), llvm::HasValue(
+                                        R"(C:\Windows\SysWOW64\msvcrt.dll)"));
+  EXPECT_THAT_EXPECTED(getName(11), llvm::HasValue(
+                                        R"(C:\Windows\SysWOW64\sechost.dll)"));
+  EXPECT_THAT_EXPECTED(getName(12), llvm::HasValue(
+                                        R"(C:\Windows\SysWOW64\rpcrt4.dll)"));
+  EXPECT_THAT_EXPECTED(getName(13), llvm::HasValue(
+                                        R"(C:\Windows\SysWOW64\sspicli.dll)"));
+  EXPECT_THAT_EXPECTED(getName(14),
+                       llvm::HasValue(
+                           R"(C:\Windows\SysWOW64\CRYPTBASE.dll)"));
+  EXPECT_THAT_EXPECTED(
+      getName(15),
+      llvm::HasValue(
+          R"(C:\Windows\System32\api-ms-win-core-synch-l1-2-0.DLL)"));
 }
 
 // Register tests
@@ -658,12 +675,12 @@ TEST_F(MinidumpParserTest, MinidumpModul
   llvm::Optional<std::string> name;
   EXPECT_EQ(2u, filtered_modules.size());
   EXPECT_EQ(0x0000000000002000u, filtered_modules[0]->base_of_image);
-  name = parser->GetMinidumpString(filtered_modules[0]->module_name_rva);
-  ASSERT_TRUE((bool)name);
-  EXPECT_EQ(std::string("/tmp/a"), *name);
+  EXPECT_THAT_EXPECTED(
+      parser->GetMinidumpFile().getString(filtered_modules[0]->module_name_rva),
+      llvm::HasValue("/tmp/a"));
   EXPECT_EQ(0x0000000000001000u, filtered_modules[1]->base_of_image);
-  name = parser->GetMinidumpString(filtered_modules[1]->module_name_rva);
-  ASSERT_TRUE((bool)name);
-  EXPECT_EQ(std::string("/tmp/b"), *name);
+  EXPECT_THAT_EXPECTED(
+      parser->GetMinidumpFile().getString(filtered_modules[1]->module_name_rva),
+      llvm::HasValue("/tmp/b"));
 }
 




More information about the lldb-commits mailing list