Index: lldb/trunk/include/lldb/Core/Module.h =================================================================== --- lldb/trunk/include/lldb/Core/Module.h +++ lldb/trunk/include/lldb/Core/Module.h @@ -1065,9 +1065,9 @@ ///is used by the ObjectFile and and ///ObjectFile instances for the debug info - std::atomic m_did_load_objfile; - std::atomic m_did_load_symbol_vendor; - std::atomic m_did_parse_uuid; + std::atomic m_did_load_objfile{false}; + std::atomic m_did_load_symbol_vendor{false}; + std::atomic m_did_parse_uuid{false}; mutable bool m_file_has_changed : 1, m_first_file_changed_log : 1; /// See if the module was modified after it /// was initially opened. Index: lldb/trunk/include/lldb/Core/ModuleSpec.h =================================================================== --- lldb/trunk/include/lldb/Core/ModuleSpec.h +++ lldb/trunk/include/lldb/Core/ModuleSpec.h @@ -21,6 +21,7 @@ #include "lldb/Core/Stream.h" #include "lldb/Core/UUID.h" #include "lldb/Host/FileSpec.h" +#include "lldb/Host/TimeValue.h" #include "lldb/Target/PathMappingList.h" namespace lldb_private { Index: lldb/trunk/include/lldb/Core/SourceManager.h =================================================================== --- lldb/trunk/include/lldb/Core/SourceManager.h +++ lldb/trunk/include/lldb/Core/SourceManager.h @@ -19,6 +19,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Host/FileSpec.h" +#include "lldb/Host/TimeValue.h" #include "lldb/lldb-private.h" namespace lldb_private { @@ -33,7 +34,7 @@ public: File(const FileSpec &file_spec, Target *target); File(const FileSpec &file_spec, lldb::DebuggerSP debugger_sp); - ~File(); + ~File() = default; void UpdateIfNeeded(); @@ -72,9 +73,10 @@ // m_file_spec_orig) TimeValue m_mod_time; // Keep the modification time that this file data is // valid for - uint32_t m_source_map_mod_id; // If the target uses path remappings, be sure - // to clear our notion of a source file if the - // path modification ID changes + + // If the target uses path remappings, be sure to clear our notion of a + // source file if the path modification ID changes + uint32_t m_source_map_mod_id = 0; lldb::DataBufferSP m_data_sp; typedef std::vector LineOffsets; LineOffsets m_offsets; Index: lldb/trunk/include/lldb/Host/FileSpec.h =================================================================== --- lldb/trunk/include/lldb/Host/FileSpec.h +++ lldb/trunk/include/lldb/Host/FileSpec.h @@ -19,7 +19,6 @@ // Project includes #include "lldb/Core/ConstString.h" #include "lldb/Core/STLUtils.h" -#include "lldb/Host/TimeValue.h" #include "lldb/lldb-private.h" namespace lldb_private { @@ -377,8 +376,6 @@ //------------------------------------------------------------------ bool IsAbsolute() const; - TimeValue GetModificationTime() const; - //------------------------------------------------------------------ /// Extract the full path to the file. /// Index: lldb/trunk/include/lldb/Host/FileSystem.h =================================================================== --- lldb/trunk/include/lldb/Host/FileSystem.h +++ lldb/trunk/include/lldb/Host/FileSystem.h @@ -10,14 +10,15 @@ #ifndef liblldb_Host_FileSystem_h #define liblldb_Host_FileSystem_h -#include -#include -#include +#include "lldb/Core/Error.h" +#include "lldb/Host/FileSpec.h" +#include "llvm/Support/Chrono.h" #include "lldb/lldb-types.h" -#include "lldb/Core/Error.h" -#include "lldb/Host/FileSpec.h" +#include +#include +#include namespace lldb_private { class FileSystem { @@ -65,6 +66,8 @@ /// Wraps ::stat in a platform-independent way. static int Stat(const char *path, struct stat *stats); + + static llvm::sys::TimePoint<> GetModificationTime(const FileSpec &file_spec); }; } Index: lldb/trunk/include/lldb/Host/TimeValue.h =================================================================== --- lldb/trunk/include/lldb/Host/TimeValue.h +++ lldb/trunk/include/lldb/Host/TimeValue.h @@ -10,15 +10,14 @@ #ifndef liblldb_TimeValue_h_ #define liblldb_TimeValue_h_ -// C Includes #include "lldb/Host/PosixApi.h" -#include -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-private.h" +#include + +#include + namespace lldb_private { class TimeValue { @@ -35,6 +34,10 @@ TimeValue(const TimeValue &rhs); TimeValue(const struct timespec &ts); explicit TimeValue(uint32_t seconds, uint64_t nanos = 0); + TimeValue(std::chrono::time_point + point) + : m_nano_seconds(point.time_since_epoch().count()) {} ~TimeValue(); //------------------------------------------------------------------ Index: lldb/trunk/include/lldb/Interpreter/OptionValueFileSpec.h =================================================================== --- lldb/trunk/include/lldb/Interpreter/OptionValueFileSpec.h +++ lldb/trunk/include/lldb/Interpreter/OptionValueFileSpec.h @@ -10,13 +10,11 @@ #ifndef liblldb_OptionValueFileSpec_h_ #define liblldb_OptionValueFileSpec_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Host/FileSpec.h" #include "lldb/Interpreter/OptionValue.h" +#include "lldb/Host/FileSpec.h" +#include "lldb/Host/TimeValue.h" + namespace lldb_private { class OptionValueFileSpec : public OptionValue { Index: lldb/trunk/source/Core/Module.cpp =================================================================== --- lldb/trunk/source/Core/Module.cpp +++ lldb/trunk/source/Core/Module.cpp @@ -30,6 +30,7 @@ #include "lldb/Core/Section.h" #include "lldb/Core/StreamString.h" #include "lldb/Core/Timer.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/Symbols.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -139,12 +140,7 @@ #endif Module::Module(const ModuleSpec &module_spec) - : m_mutex(), m_mod_time(), m_arch(), m_uuid(), m_file(), m_platform_file(), - m_remote_install_file(), m_symfile_spec(), m_object_name(), - m_object_offset(), m_object_mod_time(), m_objfile_sp(), m_symfile_ap(), - m_type_system_map(), m_source_mappings(), m_sections_ap(), - m_did_load_objfile(false), m_did_load_symbol_vendor(false), - m_did_parse_uuid(false), m_file_has_changed(false), + : m_object_offset(0), m_file_has_changed(false), m_first_file_changed_log(false) { // Scope for locker below... { @@ -186,9 +182,10 @@ return; if (module_spec.GetFileSpec()) - m_mod_time = module_spec.GetFileSpec().GetModificationTime(); + m_mod_time = FileSystem::GetModificationTime(module_spec.GetFileSpec()); else if (matching_module_spec.GetFileSpec()) - m_mod_time = matching_module_spec.GetFileSpec().GetModificationTime(); + m_mod_time = + FileSystem::GetModificationTime(matching_module_spec.GetFileSpec()); // Copy the architecture from the actual spec if we got one back, else use the // one that was specified @@ -233,12 +230,8 @@ Module::Module(const FileSpec &file_spec, const ArchSpec &arch, const ConstString *object_name, lldb::offset_t object_offset, const TimeValue *object_mod_time_ptr) - : m_mutex(), m_mod_time(file_spec.GetModificationTime()), m_arch(arch), - m_uuid(), m_file(file_spec), m_platform_file(), m_remote_install_file(), - m_symfile_spec(), m_object_name(), m_object_offset(object_offset), - m_object_mod_time(), m_objfile_sp(), m_symfile_ap(), m_type_system_map(), - m_source_mappings(), m_sections_ap(), m_did_load_objfile(false), - m_did_load_symbol_vendor(false), m_did_parse_uuid(false), + : m_mod_time(FileSystem::GetModificationTime(file_spec)), m_arch(arch), + m_file(file_spec), m_object_offset(object_offset), m_file_has_changed(false), m_first_file_changed_log(false) { // Scope for locker below... { @@ -264,12 +257,7 @@ } Module::Module() - : m_mutex(), m_mod_time(), m_arch(), m_uuid(), m_file(), m_platform_file(), - m_remote_install_file(), m_symfile_spec(), m_object_name(), - m_object_offset(0), m_object_mod_time(), m_objfile_sp(), m_symfile_ap(), - m_type_system_map(), m_source_mappings(), m_sections_ap(), - m_did_load_objfile(false), m_did_load_symbol_vendor(false), - m_did_parse_uuid(false), m_file_has_changed(false), + : m_object_offset(0), m_file_has_changed(false), m_first_file_changed_log(false) { std::lock_guard guard( GetAllocationModuleCollectionMutex()); @@ -1076,7 +1064,7 @@ // Container objects whose paths do not specify a file directly can call // this function to correct the file and object names. m_file = file; - m_mod_time = file.GetModificationTime(); + m_mod_time = FileSystem::GetModificationTime(file); m_object_name = object_name; } @@ -1138,7 +1126,8 @@ bool Module::FileHasChanged() const { if (!m_file_has_changed) - m_file_has_changed = (m_file.GetModificationTime() != m_mod_time); + m_file_has_changed = + (FileSystem::GetModificationTime(m_file) != m_mod_time); return m_file_has_changed; } Index: lldb/trunk/source/Core/ModuleList.cpp =================================================================== --- lldb/trunk/source/Core/ModuleList.cpp +++ lldb/trunk/source/Core/ModuleList.cpp @@ -19,6 +19,7 @@ #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/Symbols.h" #include "lldb/Symbol/ObjectFile.h" @@ -855,8 +856,8 @@ // If we didn't have a UUID in mind when looking for the object file, // then we should make sure the modification time hasn't changed! if (platform_module_spec.GetUUIDPtr() == nullptr) { - TimeValue file_spec_mod_time( - located_binary_modulespec.GetFileSpec().GetModificationTime()); + TimeValue file_spec_mod_time(FileSystem::GetModificationTime( + located_binary_modulespec.GetFileSpec())); if (file_spec_mod_time.IsValid()) { if (file_spec_mod_time != module_sp->GetModificationTime()) { if (old_module_sp_ptr) Index: lldb/trunk/source/Core/SourceManager.cpp =================================================================== --- lldb/trunk/source/Core/SourceManager.cpp +++ lldb/trunk/source/Core/SourceManager.cpp @@ -18,6 +18,7 @@ #include "lldb/Core/Module.h" #include "lldb/Core/RegularExpression.h" #include "lldb/Core/Stream.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/SymbolContext.h" @@ -330,22 +331,19 @@ SourceManager::File::File(const FileSpec &file_spec, lldb::DebuggerSP debugger_sp) : m_file_spec_orig(file_spec), m_file_spec(file_spec), - m_mod_time(file_spec.GetModificationTime()), m_source_map_mod_id(0), - m_data_sp(), m_offsets(), m_debugger_wp(debugger_sp) { + m_mod_time(FileSystem::GetModificationTime(file_spec)), + m_debugger_wp(debugger_sp) { CommonInitializer(file_spec, nullptr); } SourceManager::File::File(const FileSpec &file_spec, Target *target) : m_file_spec_orig(file_spec), m_file_spec(file_spec), - m_mod_time(file_spec.GetModificationTime()), m_source_map_mod_id(0), - m_data_sp(), m_offsets(), + m_mod_time(FileSystem::GetModificationTime(file_spec)), m_debugger_wp(target ? target->GetDebugger().shared_from_this() : DebuggerSP()) { CommonInitializer(file_spec, target); } -SourceManager::File::~File() {} - void SourceManager::File::CommonInitializer(const FileSpec &file_spec, Target *target) { if (!m_mod_time.IsValid()) { @@ -384,7 +382,7 @@ SymbolContext sc; sc_list.GetContextAtIndex(0, sc); m_file_spec = sc.comp_unit; - m_mod_time = m_file_spec.GetModificationTime(); + m_mod_time = FileSystem::GetModificationTime(m_file_spec); } } } @@ -399,7 +397,7 @@ if (target->GetSourcePathMap().FindFile(m_file_spec, new_file_spec) || target->GetImages().FindSourceFile(m_file_spec, new_file_spec)) { m_file_spec = new_file_spec; - m_mod_time = m_file_spec.GetModificationTime(); + m_mod_time = FileSystem::GetModificationTime(m_file_spec); } } } @@ -479,7 +477,7 @@ // TODO: use host API to sign up for file modifications to anything in our // source cache and only update when we determine a file has been updated. // For now we check each time we want to display info for the file. - TimeValue curr_mod_time(m_file_spec.GetModificationTime()); + TimeValue curr_mod_time(FileSystem::GetModificationTime(m_file_spec)); if (curr_mod_time.IsValid() && m_mod_time != curr_mod_time) { m_mod_time = curr_mod_time; Index: lldb/trunk/source/Host/common/FileSpec.cpp =================================================================== --- lldb/trunk/source/Host/common/FileSpec.cpp +++ lldb/trunk/source/Host/common/FileSpec.cpp @@ -745,14 +745,6 @@ return file_permissions; } -TimeValue FileSpec::GetModificationTime() const { - TimeValue mod_time; - struct stat file_stats; - if (GetFileStats(this, &file_stats)) - mod_time.OffsetWithSeconds(file_stats.st_mtime); - return mod_time; -} - //------------------------------------------------------------------ // Directory string get accessor. //------------------------------------------------------------------ Index: lldb/trunk/source/Host/common/FileSystem.cpp =================================================================== --- lldb/trunk/source/Host/common/FileSystem.cpp +++ lldb/trunk/source/Host/common/FileSystem.cpp @@ -9,6 +9,7 @@ #include "lldb/Host/FileSystem.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/MD5.h" #include @@ -90,3 +91,12 @@ digest_str = result_str.c_str(); return true; } + +llvm::sys::TimePoint<> +FileSystem::GetModificationTime(const FileSpec &file_spec) { + llvm::sys::fs::file_status status; + std::error_code ec = llvm::sys::fs::status(file_spec.GetPath(), status); + if (ec) + return llvm::sys::TimePoint<>(); + return status.getLastModificationTime(); +} Index: lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp =================================================================== --- lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp +++ lldb/trunk/source/Interpreter/OptionValueFileSpec.cpp @@ -9,12 +9,9 @@ #include "lldb/Interpreter/OptionValueFileSpec.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/State.h" #include "lldb/DataFormatters/FormatManager.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Interpreter/Args.h" #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -120,7 +117,8 @@ const lldb::DataBufferSP & OptionValueFileSpec::GetFileContents(bool null_terminate) { if (m_current_value) { - const TimeValue file_mod_time = m_current_value.GetModificationTime(); + const TimeValue file_mod_time = + FileSystem::GetModificationTime(m_current_value); if (m_data_sp && m_data_mod_time == file_mod_time) return m_data_sp; if (null_terminate) Index: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp =================================================================== --- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp +++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderDarwin.cpp @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +#include "DynamicLoaderDarwin.h" + #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/DataBuffer.h" #include "lldb/Core/DataBufferHeap.h" @@ -18,6 +20,7 @@ #include "lldb/Core/Section.h" #include "lldb/Core/State.h" #include "lldb/Expression/DiagnosticManager.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" @@ -30,8 +33,6 @@ #include "lldb/Target/ThreadPlanCallFunction.h" #include "lldb/Target/ThreadPlanRunToAddress.h" -#include "DynamicLoaderDarwin.h" - //#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN #ifdef ENABLE_DEBUG_PRINTF #include @@ -114,7 +115,7 @@ // No UUID, we must rely upon the cached module modification // time and the modification time of the file on disk if (module_sp->GetModificationTime() != - module_sp->GetFileSpec().GetModificationTime()) + FileSystem::GetModificationTime(module_sp->GetFileSpec())) module_sp.reset(); } Index: lldb/trunk/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp =================================================================== --- lldb/trunk/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp +++ lldb/trunk/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp @@ -34,6 +34,7 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Core/Stream.h" #include "lldb/Core/Timer.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Symbol/ObjectFile.h" using namespace lldb; @@ -452,7 +453,7 @@ data.SetData(data_sp, data_offset, data_sp->GetByteSize()); if (file && data_sp && ObjectContainerBSDArchive::MagicBytesMatch(data)) { const size_t initial_count = specs.GetSize(); - TimeValue file_mod_time = file.GetModificationTime(); + TimeValue file_mod_time = FileSystem::GetModificationTime(file); Archive::shared_ptr archive_sp(Archive::FindCachedArchive( file, ArchSpec(), file_mod_time, file_offset)); bool set_archive_arch = false; Index: lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp =================================================================== --- lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp +++ lldb/trunk/source/Plugins/Platform/Android/AdbClient.cpp @@ -22,6 +22,7 @@ #include "lldb/Core/StreamString.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/FileSpec.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/PosixApi.h" #include @@ -475,8 +476,11 @@ if (error.Fail()) return Error("Failed to send file chunk: %s", error.AsCString()); } - error = SendSyncRequest(kDONE, local_file.GetModificationTime().seconds(), - nullptr); + error = SendSyncRequest( + kDONE, std::chrono::duration_cast( + FileSystem::GetModificationTime(local_file).time_since_epoch()) + .count(), + nullptr); if (error.Fail()) return error; Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -14,6 +14,7 @@ #include #include "lldb/Core/RangeMap.h" +#include "lldb/Host/TimeValue.h" #include "lldb/Symbol/SymbolFile.h" #include "UniqueDWARFASTType.h" Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -21,6 +21,7 @@ #include "lldb/Core/RangeMap.h" #include "lldb/Core/RegularExpression.h" #include "lldb/Core/Section.h" +#include "lldb/Host/FileSystem.h" //#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT #if defined(DEBUG_OSO_DMAP) @@ -424,7 +425,7 @@ FileSpec oso_file(oso_path, false); ConstString oso_object; if (oso_file.Exists()) { - TimeValue oso_mod_time(oso_file.GetModificationTime()); + TimeValue oso_mod_time(FileSystem::GetModificationTime(oso_file)); if (oso_mod_time != comp_unit_info->oso_mod_time) { obj_file->GetModule()->ReportError( "debug map object file '%s' has changed (actual time is " Index: lldb/trunk/unittests/Host/CMakeLists.txt =================================================================== --- lldb/trunk/unittests/Host/CMakeLists.txt +++ lldb/trunk/unittests/Host/CMakeLists.txt @@ -1,5 +1,6 @@ add_lldb_unittest(HostTests FileSpecTest.cpp + FileSystemTest.cpp SocketAddressTest.cpp SocketTest.cpp SymbolsTest.cpp Index: lldb/trunk/unittests/Host/FileSystemTest.cpp =================================================================== --- lldb/trunk/unittests/Host/FileSystemTest.cpp +++ lldb/trunk/unittests/Host/FileSystemTest.cpp @@ -0,0 +1,32 @@ +//===-- FileSystemTest.cpp --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" + +#include "lldb/Host/FileSystem.h" + +extern const char *TestMainArgv0; + +using namespace lldb_private; + +TEST(FileSystemTest, FileAndDirectoryComponents) { + using namespace std::chrono; + + const bool resolve = true; +#ifdef _WIN32 + FileSpec fs1("C:\\FILE\\THAT\\DOES\\NOT\\EXIST.TXT", !resolve); +#else + FileSpec fs1("/file/that/does/not/exist.txt", !resolve); +#endif + FileSpec fs2(TestMainArgv0, resolve); + + EXPECT_EQ(system_clock::time_point(), FileSystem::GetModificationTime(fs1)); + EXPECT_LT(system_clock::time_point() + hours(24 * 365 * 20), + FileSystem::GetModificationTime(fs2)); +}