clayborg updated this revision to Diff 147354.
clayborg added a comment.

Fix issues found by Zach.


https://reviews.llvm.org/D47021

Files:
  include/lldb/Target/PathMappingList.h
  lldb.xcodeproj/project.pbxproj
  source/Target/PathMappingList.cpp
  source/Target/Target.cpp
  unittests/Utility/CMakeLists.txt
  unittests/Utility/PathMappingListTest.cpp

Index: unittests/Utility/PathMappingListTest.cpp
===================================================================
--- unittests/Utility/PathMappingListTest.cpp
+++ unittests/Utility/PathMappingListTest.cpp
@@ -0,0 +1,101 @@
+//===-- NameMatchesTest.cpp -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/PathMappingList.h"
+#include "lldb/Utility/FileSpec.h"
+#include "gtest/gtest.h"
+#include <utility>
+
+using namespace lldb_private;
+
+namespace {
+  struct Matches {
+    ConstString original;
+    ConstString remapped;
+    Matches(const char *o, const char *r) : original(o),
+        remapped(r) {}
+  };
+}
+
+TEST(PathMappingListTest, RelativeTests) {
+  PathMappingList map;
+  map.Append(ConstString("."), ConstString("/tmp"), false);
+  Matches tests[] = {
+    {".", "/tmp"},
+    {"./", "/tmp"},
+    {"./////", "/tmp"},
+    {"./foo.c", "/tmp/foo.c"},
+    {"./bar/foo.c", "/tmp/bar/foo.c"}
+  };
+  ConstString actual_remapped;
+  EXPECT_FALSE(map.RemapPath(ConstString("/foo"), actual_remapped));
+  for (const auto &m: tests) {
+    FileSpec orig_spec(m.original.GetCString(), false);
+    std::string orig_normalized = orig_spec.GetPath();
+    EXPECT_TRUE(map.RemapPath(m.original, actual_remapped));
+    EXPECT_TRUE(actual_remapped == m.remapped);
+    FileSpec remapped_spec(m.remapped.GetCString(), false);
+    FileSpec unmapped_spec;
+    EXPECT_TRUE(map.ReverseRemapPath(remapped_spec, unmapped_spec));
+    std::string unmapped_path = unmapped_spec.GetPath();
+    EXPECT_TRUE(unmapped_path == orig_normalized);
+  }
+}
+
+TEST(PathMappingListTest, AbsoluteTests) {
+  PathMappingList map;
+  map.Append(ConstString("/old"), ConstString("/new"), false);
+  Matches tests[] = {
+    {"/old", "/new"},
+    {"/old/", "/new"},
+    {"/old/foo/.", "/new/foo"},
+    {"/old/foo.c", "/new/foo.c"},
+    {"/old/foo.c/.", "/new/foo.c"},
+    {"/old/./foo.c", "/new/foo.c"},
+  };
+  ConstString actual_remapped;
+  // Make sure that the path
+  for (const auto &m: tests) {
+    FileSpec orig_spec(m.original.GetCString(), false);
+    std::string orig_normalized = orig_spec.GetPath();
+    EXPECT_TRUE(map.RemapPath(m.original, actual_remapped));
+    EXPECT_TRUE(actual_remapped == m.remapped);
+    FileSpec remapped_spec(m.remapped.GetCString(), false);
+    FileSpec unmapped_spec;
+    EXPECT_TRUE(map.ReverseRemapPath(remapped_spec, unmapped_spec));
+    std::string unmapped_path = unmapped_spec.GetPath();
+    EXPECT_TRUE(unmapped_path == orig_normalized);
+  }
+}
+
+TEST(PathMappingListTest, RemapEverything) {
+  PathMappingList map;
+  map.Append(ConstString(""), ConstString("/new"), false);
+  Matches tests[] = {
+    {"/old", "/new/old"},
+    {"/old/", "/new/old"},
+    {"/old/foo/.", "/new/old/foo"},
+    {"/old/foo.c", "/new/old/foo.c"},
+    {"/old/foo.c/.", "/new/old/foo.c"},
+    {"/old/./foo.c", "/new/old/foo.c"},
+  };
+  ConstString actual_remapped;
+  // Make sure that the path
+  for (const auto &m: tests) {
+    FileSpec orig_spec(m.original.GetCString(), false);
+    std::string orig_normalized = orig_spec.GetPath();
+    EXPECT_TRUE(map.RemapPath(m.original, actual_remapped));
+    EXPECT_TRUE(actual_remapped == m.remapped);
+    FileSpec remapped_spec(m.remapped.GetCString(), false);
+    FileSpec unmapped_spec;
+    EXPECT_TRUE(map.ReverseRemapPath(remapped_spec, unmapped_spec));
+    std::string unmapped_path = unmapped_spec.GetPath();
+    EXPECT_TRUE(unmapped_path == orig_normalized);
+  }
+}
Index: unittests/Utility/CMakeLists.txt
===================================================================
--- unittests/Utility/CMakeLists.txt
+++ unittests/Utility/CMakeLists.txt
@@ -8,6 +8,7 @@
   JSONTest.cpp
   LogTest.cpp
   NameMatchesTest.cpp
+  PathMappingListTest.cpp
   StatusTest.cpp
   StringExtractorTest.cpp
   StructuredDataTest.cpp
Index: source/Target/Target.cpp
===================================================================
--- source/Target/Target.cpp
+++ source/Target/Target.cpp
@@ -328,11 +328,7 @@
                                       bool hardware,
                                       LazyBool move_to_nearest_code) {
   FileSpec remapped_file;
-  ConstString remapped_path;
-  if (GetSourcePathMap().ReverseRemapPath(ConstString(file.GetPath().c_str()),
-                                          remapped_path))
-    remapped_file.SetFile(remapped_path.AsCString(), false);
-  else
+  if (!GetSourcePathMap().ReverseRemapPath(file, remapped_file))
     remapped_file = file;
 
   if (check_inlines == eLazyBoolCalculate) {
Index: source/Target/PathMappingList.cpp
===================================================================
--- source/Target/PathMappingList.cpp
+++ source/Target/PathMappingList.cpp
@@ -14,6 +14,7 @@
 
 // Other libraries and framework includes
 // Project includes
+#include "lldb/lldb-private-enumerations.h"
 #include "lldb/Host/PosixApi.h"
 #include "lldb/Target/PathMappingList.h"
 #include "lldb/Utility/FileSpec.h"
@@ -23,6 +24,26 @@
 using namespace lldb;
 using namespace lldb_private;
 
+namespace {
+  // We must normalize our path pairs that we store because if we don't then
+  // things won't always work. We found a case where if we did:
+  // (lldb) settings set target.source-map . /tmp
+  // We would store a path pairs of "." and "/tmp" as raw strings. If the debug
+  // info contains "./foo/bar.c", the path will get normalized to "foo/bar.c".
+  // When PathMappingList::RemapPath() is called, it expects the path to start
+  // with the raw path pair, which doesn't work anymore because the paths have
+  // been normalized when the debug info was loaded. So we need to store
+  // nomalized path pairs to ensure things match up.
+  ConstString NormalizePath(const ConstString &path) {
+    // Don't change nothing into ".", nothing will remap all files to the
+    // other path
+    if (!path)
+      return path;
+    // If we use "path" to construct a FileSpec, it will normalize the path for
+    // us. We then grab the string and turn it back into a ConstString.
+    return ConstString(FileSpec(path.GetCString(), false).GetPath());
+  }
+}
 //----------------------------------------------------------------------
 // PathMappingList constructor
 //----------------------------------------------------------------------
@@ -52,7 +73,7 @@
 void PathMappingList::Append(const ConstString &path,
                              const ConstString &replacement, bool notify) {
   ++m_mod_id;
-  m_pairs.push_back(pair(path, replacement));
+  m_pairs.emplace_back(pair(NormalizePath(path), NormalizePath(replacement)));
   if (notify && m_callback)
     m_callback(*this, m_callback_baton);
 }
@@ -77,7 +98,8 @@
     insert_iter = m_pairs.end();
   else
     insert_iter = m_pairs.begin() + index;
-  m_pairs.insert(insert_iter, pair(path, replacement));
+  m_pairs.insert(insert_iter, pair(NormalizePath(path),
+                                   NormalizePath(replacement)));
   if (notify && m_callback)
     m_callback(*this, m_callback_baton);
 }
@@ -88,7 +110,7 @@
   if (index >= m_pairs.size())
     return false;
   ++m_mod_id;
-  m_pairs[index] = pair(path, replacement);
+  m_pairs[index] = pair(NormalizePath(path), NormalizePath(replacement));
   if (notify && m_callback)
     m_callback(*this, m_callback_baton);
   return true;
@@ -134,58 +156,47 @@
 
 bool PathMappingList::RemapPath(const ConstString &path,
                                 ConstString &new_path) const {
-  const char *path_cstr = path.GetCString();
-  // CLEANUP: Convert this function to use StringRefs internally instead
-  // of raw c-strings.
-  if (!path_cstr)
-    return false;
-
-  const_iterator pos, end = m_pairs.end();
-  for (pos = m_pairs.begin(); pos != end; ++pos) {
-    const size_t prefixLen = pos->first.GetLength();
-
-    if (::strncmp(pos->first.GetCString(), path_cstr, prefixLen) == 0) {
-      std::string new_path_str(pos->second.GetCString());
-      new_path_str.append(path.GetCString() + prefixLen);
-      new_path.SetCString(new_path_str.c_str());
-      return true;
-    }
+  std::string remapped;
+  if (RemapPath(path.GetStringRef(), remapped)) {
+    new_path.SetCStringWithLength(remapped.c_str(), remapped.size());
+    return true;
   }
   return false;
 }
 
 bool PathMappingList::RemapPath(llvm::StringRef path,
                                 std::string &new_path) const {
   if (m_pairs.empty() || path.empty())
     return false;
-
-  const_iterator pos, end = m_pairs.end();
-  for (pos = m_pairs.begin(); pos != end; ++pos) {
-    if (!path.consume_front(pos->first.GetStringRef()))
+  
+  for (const auto &it : m_pairs) {
+    if (!path.consume_front(it.first.GetStringRef()))
       continue;
-
-    new_path = pos->second.GetStringRef();
-    new_path.append(path);
+    FileSpec remapped(it.second.GetStringRef(), false);
+    remapped.AppendPathComponent(path);
+    new_path = remapped.GetPath();
     return true;
   }
   return false;
 }
 
-bool PathMappingList::ReverseRemapPath(const ConstString &path,
-                                       ConstString &new_path) const {
-  const char *path_cstr = path.GetCString();
-  if (!path_cstr)
-    return false;
-
+bool PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) const {
+  std::string path = file.GetPath();
+  llvm::StringRef path_ref(path);
   for (const auto &it : m_pairs) {
-    // FIXME: This should be using FileSpec API's to do the path appending.
-    const size_t prefixLen = it.second.GetLength();
-    if (::strncmp(it.second.GetCString(), path_cstr, prefixLen) == 0) {
-      std::string new_path_str(it.first.GetCString());
-      new_path_str.append(path.GetCString() + prefixLen);
-      new_path.SetCString(new_path_str.c_str());
-      return true;
+    if (!path_ref.consume_front(it.second.GetStringRef()))
+      continue;
+    llvm::StringRef first(it.first.GetStringRef());
+    if (first.empty()) {
+      // If our original path was "", then the new path is just the suffix.
+      // If we call fixed.SetFile("", false) we will end up with "." as the
+      // path and any path we appended would end up being relative.
+      fixed.SetFile(path_ref, false);
+    } else {
+      fixed.SetFile(first, false);
+      fixed.AppendPathComponent(path_ref);
     }
+    return true;
   }
   return false;
 }
@@ -277,7 +288,8 @@
   return false;
 }
 
-uint32_t PathMappingList::FindIndexForPath(const ConstString &path) const {
+uint32_t PathMappingList::FindIndexForPath(const ConstString &orig_path) const {
+  const ConstString path = NormalizePath(orig_path);
   const_iterator pos;
   const_iterator begin = m_pairs.begin();
   const_iterator end = m_pairs.end();
Index: lldb.xcodeproj/project.pbxproj
===================================================================
--- lldb.xcodeproj/project.pbxproj
+++ lldb.xcodeproj/project.pbxproj
@@ -211,6 +211,7 @@
 		264A58EE1A7DBCAD00A6B1B0 /* OptionValueFormatEntity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264A58ED1A7DBCAD00A6B1B0 /* OptionValueFormatEntity.cpp */; };
 		264A97BF133918BC0017F0BE /* PlatformRemoteGDBServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264A97BD133918BC0017F0BE /* PlatformRemoteGDBServer.cpp */; };
 		264D8D5013661BD7003A368F /* UnwindAssembly.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264D8D4F13661BD7003A368F /* UnwindAssembly.cpp */; };
+		264FA56720A608F900134FA2 /* PathMappingListTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 264FA56620A608F900134FA2 /* PathMappingListTest.cpp */; };
 		265192C61BA8E905002F08F6 /* CompilerDecl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 265192C51BA8E905002F08F6 /* CompilerDecl.cpp */; };
 		265205A813D3E3F700132FE2 /* RegisterContextKDP_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 265205A213D3E3F700132FE2 /* RegisterContextKDP_arm.cpp */; };
 		265205AA13D3E3F700132FE2 /* RegisterContextKDP_i386.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 265205A413D3E3F700132FE2 /* RegisterContextKDP_i386.cpp */; };
@@ -1722,6 +1723,7 @@
 		264AD83911095BBD00E0B039 /* CommandObjectLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectLog.h; path = source/Commands/CommandObjectLog.h; sourceTree = "<group>"; };
 		264D8D4E13661BCC003A368F /* UnwindAssembly.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = UnwindAssembly.h; path = include/lldb/Target/UnwindAssembly.h; sourceTree = "<group>"; };
 		264D8D4F13661BD7003A368F /* UnwindAssembly.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UnwindAssembly.cpp; path = source/Target/UnwindAssembly.cpp; sourceTree = "<group>"; };
+		264FA56620A608F900134FA2 /* PathMappingListTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PathMappingListTest.cpp; sourceTree = "<group>"; };
 		265192C41BA8E8F8002F08F6 /* CompilerDecl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CompilerDecl.h; path = include/lldb/Symbol/CompilerDecl.h; sourceTree = "<group>"; };
 		265192C51BA8E905002F08F6 /* CompilerDecl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompilerDecl.cpp; path = source/Symbol/CompilerDecl.cpp; sourceTree = "<group>"; };
 		265205A213D3E3F700132FE2 /* RegisterContextKDP_arm.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegisterContextKDP_arm.cpp; sourceTree = "<group>"; };
@@ -3473,6 +3475,7 @@
 				9A3D43C81F3150D200EB767C /* ConstStringTest.cpp */,
 				23CB14FD1D66CD2400EDDDE1 /* FileSpecTest.cpp */,
 				9A3D43C71F3150D200EB767C /* LogTest.cpp */,
+				264FA56620A608F900134FA2 /* PathMappingListTest.cpp */,
 				9A3D43CB1F3150D200EB767C /* NameMatchesTest.cpp */,
 				9A3D43C61F3150D200EB767C /* StatusTest.cpp */,
 				9A3D43CA1F3150D200EB767C /* StructuredDataTest.cpp */,
@@ -7351,6 +7354,7 @@
 				23CB15341D66DA9300EDDDE1 /* CPlusPlusLanguageTest.cpp in Sources */,
 				9A2057381F3B8E7E00F6C293 /* FileSystemTest.cpp in Sources */,
 				9A2057201F3B8D2500F6C293 /* UnixSignalsTest.cpp in Sources */,
+				264FA56720A608F900134FA2 /* PathMappingListTest.cpp in Sources */,
 				AFAFD80A1E57E1B90017A14F /* ModuleCacheTest.cpp in Sources */,
 				9A3D43DA1F3151C400EB767C /* StructuredDataTest.cpp in Sources */,
 				9A2057121F3B824B00F6C293 /* SymbolFileDWARFTests.cpp in Sources */,
Index: include/lldb/Target/PathMappingList.h
===================================================================
--- include/lldb/Target/PathMappingList.h
+++ include/lldb/Target/PathMappingList.h
@@ -90,7 +90,7 @@
   bool RemapPath(llvm::StringRef path, std::string &new_path) const;
   bool RemapPath(const char *, std::string &) const = delete;
 
-  bool ReverseRemapPath(const ConstString &path, ConstString &new_path) const;
+  bool ReverseRemapPath(const FileSpec &file, FileSpec &fixed) const;
 
   //------------------------------------------------------------------
   /// Finds a source file given a file spec using the path remappings.
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to