[Lldb-commits] [lldb] r118387 - in /lldb/trunk: include/lldb/Core/FileSpec.h lldb.xcodeproj/project.pbxproj source/API/SBTarget.cpp source/Core/FileSpec.cpp

Greg Clayton gclayton at apple.com
Sun Nov 7 16:28:40 PST 2010


Author: gclayton
Date: Sun Nov  7 18:28:40 2010
New Revision: 118387

URL: http://llvm.org/viewvc/llvm-project?rev=118387&view=rev
Log:
Fixed FileSpec's operator == to deal with equivalent paths such as "/tmp/a.c"
and "/private/tmp/a.c". This was done by adding a "mutable bool m_is_resolved;"
member to FileSpec and then modifying the equal operator to check if the
filenames are equal, and if they are, then check the directories. If they are
not equal, then both paths are checked to see if they have been resolved. If
they have been resolved, we resolve the paths in temporary FileSpec objects
and set each of the m_is_resolved bools to try (for lhs and rhs) if the paths
match what is contained in the path. This allows us to do more intelligent
compares without having to resolve all paths found in the debug info (which
can quickly get costly if the files are on remote NFS mounts).


Modified:
    lldb/trunk/include/lldb/Core/FileSpec.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/API/SBTarget.cpp
    lldb/trunk/source/Core/FileSpec.cpp

Modified: lldb/trunk/include/lldb/Core/FileSpec.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/FileSpec.h?rev=118387&r1=118386&r2=118387&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/FileSpec.h (original)
+++ lldb/trunk/include/lldb/Core/FileSpec.h Sun Nov  7 18:28:40 2010
@@ -273,21 +273,20 @@
     /// Call into the Host to see if it can help find the file (e.g. by
     /// searching paths set in the environment, etc.).
     ///
-    /// If found, sets the value of m_directory to the directory where the file was found.
+    /// If found, sets the value of m_directory to the directory where 
+    /// the file was found.
     ///
     /// @return
-    ///     \b true if was able to find the file using expanded search methods, \b false otherwise.
+    ///     \b true if was able to find the file using expanded search 
+    ///     methods, \b false otherwise.
     //------------------------------------------------------------------
     bool
     ResolveExecutableLocation ();
     
-    
     //------------------------------------------------------------------
-    /// Canonicalize this file path (basically running the static Resolve method on it).
-    /// Useful if you asked us not to resolve the file path when you set the file.
-    ///
-    /// @return
-    ///     None.
+    /// Canonicalize this file path (basically running the static 
+    /// FileSpec::Resolve method on it). Useful if you asked us not to 
+    /// resolve the file path when you set the file.
     //------------------------------------------------------------------
     bool
     ResolvePath ();
@@ -450,13 +449,37 @@
     /// @param[in] path
     ///     A full, partial, or relative path to a file.
     ///
-    /// @param[in] resolve
+    /// @param[in] resolve_path
     ///     If \b true, then we will try to resolve links the path using
     ///     the static FileSpec::Resolve.
     //------------------------------------------------------------------
     void
-    SetFile (const char *path, bool resolve);
+    SetFile (const char *path, bool resolve_path);
 
+    bool
+    IsResolved () const
+    {
+        return m_is_resolved;
+    }
+
+    //------------------------------------------------------------------
+    /// Set if the file path has been resolved or not.
+    ///
+    /// If you know a file path is already resolved and avoided passing
+    /// a \b true parameter for any functions that take a "bool 
+    /// resolve_path" parameter, you can set the value manually using
+    /// this call to make sure we don't try and resolve it later, or try
+    /// and resolve a path that has already been resolved.
+    ///
+    /// @param[in] is_resolved
+    ///     A boolean value that will replace the current value that
+    ///     indicates if the paths in this object have been resolved.
+    //------------------------------------------------------------------
+    void
+    SetIsResolved (bool is_resolved)
+    {
+        m_is_resolved = is_resolved;
+    }
     //------------------------------------------------------------------
     /// Read the file into an array of strings, one per line.
     ///
@@ -527,6 +550,7 @@
     //------------------------------------------------------------------
     ConstString m_directory;    ///< The uniqued directory path
     ConstString m_filename;     ///< The uniqued filename path
+    mutable bool m_is_resolved; ///< True if this path has been resolved.
 };
 
 //----------------------------------------------------------------------

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=118387&r1=118386&r2=118387&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Sun Nov  7 18:28:40 2010
@@ -2912,7 +2912,10 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				ALWAYS_SEARCH_USER_PATHS = NO;
-				ARCHS = "$(ARCHS_STANDARD_64_BIT)";
+				ARCHS = (
+					x86_64,
+					i386,
+				);
 				GCC_C_LANGUAGE_STANDARD = gnu99;
 				GCC_OPTIMIZATION_LEVEL = 0;
 				GCC_PREPROCESSOR_DEFINITIONS = (
@@ -3021,7 +3024,6 @@
 				);
 				LLVM_BUILD_DIR = "$(SRCROOT)/llvm";
 				LLVM_CONFIGURATION = "Debug+Asserts";
-				ONLY_ACTIVE_ARCH = YES;
 				OTHER_CFLAGS = (
 					"-DFOR_DYLD=0",
 					"-DSUPPORT_REMOTE_UNWINDING",

Modified: lldb/trunk/source/API/SBTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=118387&r1=118386&r2=118387&view=diff
==============================================================================
--- lldb/trunk/source/API/SBTarget.cpp (original)
+++ lldb/trunk/source/API/SBTarget.cpp Sun Nov  7 18:28:40 2010
@@ -386,7 +386,7 @@
 SBBreakpoint
 SBTarget::BreakpointCreateByLocation (const char *file, uint32_t line)
 {
-    return SBBreakpoint(BreakpointCreateByLocation (SBFileSpec (file), line));
+    return SBBreakpoint(BreakpointCreateByLocation (SBFileSpec (file, false), line));
 }
 
 SBBreakpoint

Modified: lldb/trunk/source/Core/FileSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/FileSpec.cpp?rev=118387&r1=118386&r2=118387&view=diff
==============================================================================
--- lldb/trunk/source/Core/FileSpec.cpp (original)
+++ lldb/trunk/source/Core/FileSpec.cpp Sun Nov  7 18:28:40 2010
@@ -176,7 +176,8 @@
 //------------------------------------------------------------------
 FileSpec::FileSpec(const char *pathname, bool resolve_path) :
     m_directory(),
-    m_filename()
+    m_filename(),
+    m_is_resolved(false)
 {
     if (pathname && pathname[0])
         SetFile(pathname, resolve_path);
@@ -187,7 +188,8 @@
 //------------------------------------------------------------------
 FileSpec::FileSpec(const FileSpec& rhs) :
     m_directory (rhs.m_directory),
-    m_filename (rhs.m_filename)
+    m_filename (rhs.m_filename),
+    m_is_resolved (rhs.m_is_resolved)
 {
 }
 
@@ -219,6 +221,7 @@
     {
         m_directory = rhs.m_directory;
         m_filename = rhs.m_filename;
+        m_is_resolved = rhs.m_is_resolved;
     }
     return *this;
 }
@@ -229,10 +232,11 @@
 // string values for quick comparison and efficient memory usage.
 //------------------------------------------------------------------
 void
-FileSpec::SetFile(const char *pathname, bool resolve)
+FileSpec::SetFile (const char *pathname, bool resolve)
 {
     m_filename.Clear();
     m_directory.Clear();
+    m_is_resolved = false;
     if (pathname == NULL || pathname[0] == '\0')
         return;
 
@@ -242,13 +246,16 @@
     if (resolve)
     {
         path_fit = (FileSpec::Resolve (pathname, resolved_path, sizeof(resolved_path)) < sizeof(resolved_path) - 1);
+        m_is_resolved = path_fit;
     }
     else
     {
-        if (strlen (pathname) > sizeof(resolved_path) - 1)
+        // Copy the path because "basename" and "dirname" want to muck with the
+        // path buffer
+        if (::strlen (pathname) > sizeof(resolved_path) - 1)
             path_fit = false;
         else
-            strcpy (resolved_path, pathname);
+            ::strcpy (resolved_path, pathname);
     }
 
     
@@ -317,7 +324,60 @@
 bool
 FileSpec::operator== (const FileSpec& rhs) const
 {
-    return m_directory == rhs.m_directory && m_filename == rhs.m_filename;
+    if (m_filename == rhs.m_filename)
+    {
+        if (m_directory == rhs.m_directory)
+            return true;
+        
+        // TODO: determine if we want to keep this code in here.
+        // The code below was added to handle a case where we were
+        // trying to set a file and line breakpoint and one path
+        // was resolved, and the other not and the directory was
+        // in a mount point that resolved to a more complete path:
+        // "/tmp/a.c" == "/private/tmp/a.c". I might end up pulling
+        // this out...
+        if (IsResolved() && rhs.IsResolved())
+        {
+            // Both paths are resolved, no need to look further...
+            return false;
+        }
+        
+        FileSpec resolved_lhs(*this);
+
+        // If "this" isn't resolved, resolve it
+        if (!IsResolved())
+        {
+            if (resolved_lhs.ResolvePath())
+            {
+                // This path wasn't resolved but now it is. Check if the resolved
+                // directory is the same as our unresolved directory, and if so, 
+                // we can mark this object as resolved to avoid more future resolves
+                m_is_resolved = (m_directory == resolved_lhs.m_directory);
+            }
+            else
+                return false;
+        }
+        
+        FileSpec resolved_rhs(rhs);
+        if (!rhs.IsResolved())
+        {
+            if (resolved_rhs.ResolvePath())
+            {
+                // rhs's path wasn't resolved but now it is. Check if the resolved
+                // directory is the same as rhs's unresolved directory, and if so, 
+                // we can mark this object as resolved to avoid more future resolves
+                rhs.m_is_resolved = (m_directory == resolved_rhs.m_directory);
+            }
+            else
+                return false;
+        }
+
+        // If we reach this point in the code we were able to resolve both paths
+        // and since we only resolve the paths if the basenames are equal, then
+        // we can just check if both directories are equal...
+        return resolved_lhs.GetDirectory() == resolved_rhs.GetDirectory();
+    }
+    return false;
 }
 
 //------------------------------------------------------------------
@@ -326,7 +386,7 @@
 bool
 FileSpec::operator!= (const FileSpec& rhs) const
 {
-    return m_filename != rhs.m_filename || m_directory != rhs.m_directory;
+    return !(*this == rhs);
 }
 
 //------------------------------------------------------------------
@@ -469,12 +529,15 @@
 bool
 FileSpec::ResolvePath ()
 {
-    char path_buf[PATH_MAX];
-    
+    if (m_is_resolved)
+        return true;    // We have already resolved this path
+
+    char path_buf[PATH_MAX];    
     if (!GetPath (path_buf, PATH_MAX))
         return false;
+    // SetFile(...) will set m_is_resolved correctly if it can resolve the path
     SetFile (path_buf, true);
-    return true;
+    return m_is_resolved; 
 }
 
 uint64_t





More information about the lldb-commits mailing list