diff --git a/lldb/include/lldb/Core/FileSpec.h b/lldb/include/lldb/Core/FileSpec.h index bca7c4adf53a..9738f8f6f8b2 100644 --- a/lldb/include/lldb/Core/FileSpec.h +++ b/lldb/include/lldb/Core/FileSpec.h @@ -273,21 +273,20 @@ public: /// 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 @@ public: /// @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 @@ protected: //------------------------------------------------------------------ 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. }; //---------------------------------------------------------------------- diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index a810d3304b3c..2821a4c80a06 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -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", diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp index ad86ccf3f7f1..ba2fea029409 100644 --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -386,7 +386,7 @@ SBTarget::reset (const lldb::TargetSP& target_sp) SBBreakpoint SBTarget::BreakpointCreateByLocation (const char *file, uint32_t line) { - return SBBreakpoint(BreakpointCreateByLocation (SBFileSpec (file), line)); + return SBBreakpoint(BreakpointCreateByLocation (SBFileSpec (file, false), line)); } SBBreakpoint diff --git a/lldb/source/Core/FileSpec.cpp b/lldb/source/Core/FileSpec.cpp index c0129915dec8..f99fcd03ff03 100644 --- a/lldb/source/Core/FileSpec.cpp +++ b/lldb/source/Core/FileSpec.cpp @@ -176,7 +176,8 @@ FileSpec::FileSpec() : //------------------------------------------------------------------ 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 char *pathname, bool resolve_path) : //------------------------------------------------------------------ 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 @@ FileSpec::operator= (const FileSpec& rhs) { m_directory = rhs.m_directory; m_filename = rhs.m_filename; + m_is_resolved = rhs.m_is_resolved; } return *this; } @@ -229,10 +232,11 @@ FileSpec::operator= (const FileSpec& rhs) // 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 @@ FileSpec::SetFile(const char *pathname, bool resolve) 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 @@ FileSpec::operator!() const 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 @@ FileSpec::operator== (const FileSpec& rhs) const 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 @@ FileSpec::ResolveExecutableLocation () 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