diff --git a/lldb/include/lldb/Core/SourceManager.h b/lldb/include/lldb/Core/SourceManager.h --- a/lldb/include/lldb/Core/SourceManager.h +++ b/lldb/include/lldb/Core/SourceManager.h @@ -86,6 +86,9 @@ private: void CommonInitializer(const FileSpec &file_spec, Target *target); + + bool IsNewerThanCurrentModule(llvm::sys::TimePoint<> time); + void Update(llvm::sys::TimePoint<> mod_time); }; typedef std::shared_ptr FileSP; diff --git a/lldb/source/Core/SourceManager.cpp b/lldb/source/Core/SourceManager.cpp --- a/lldb/source/Core/SourceManager.cpp +++ b/lldb/source/Core/SourceManager.cpp @@ -21,7 +21,10 @@ #include "lldb/Symbol/LineEntry.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/PathMappingList.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" #include "lldb/Utility/AnsiTerminal.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataBuffer.h" @@ -436,7 +439,8 @@ sc_list.GetContextAtIndex(0, sc); if (sc.comp_unit) m_file_spec = sc.comp_unit->GetPrimaryFile(); - m_mod_time = FileSystem::Instance().GetModificationTime(m_file_spec); + m_mod_time = + FileSystem::Instance().GetModificationTime(m_file_spec); } } } @@ -531,12 +535,64 @@ // For now we check each time we want to display info for the file. auto curr_mod_time = FileSystem::Instance().GetModificationTime(m_file_spec); + // If the source file is newer than the executable don't update, + // otherwise the source file being displayed will be different from + // the executable being ran. + // (We only want to update if the executable has been recompiled) + if (IsNewerThanCurrentModule(curr_mod_time)) + // TODO: maybe issue a: + // 'warning: Source file is more recent than executable.' ? + return; + if (curr_mod_time != llvm::sys::TimePoint<>() && m_mod_time != curr_mod_time) { - m_mod_time = curr_mod_time; - m_data_sp = FileSystem::Instance().CreateDataBuffer(m_file_spec); - m_offsets.clear(); + Update(curr_mod_time); + } +} + +bool SourceManager::File::IsNewerThanCurrentModule( + llvm::sys::TimePoint<> time) { + DebuggerSP debugger_sp(m_debugger_wp.lock()); + if (!debugger_sp) + return false; + + lldb::TargetSP target_sp(debugger_sp->GetSelectedTarget()); + if (!target_sp) + return false; + + lldb::ProcessSP process_sp(target_sp->CalculateProcess()); + if (!process_sp) + return false; + + ThreadList &thread_list(process_sp->GetThreadList()); + + lldb::ThreadSP thread_sp(thread_list.GetSelectedThread()); + if (!thread_sp) + return false; + + lldb::StackFrameSP stackframe_sp(thread_sp->GetSelectedFrame()); + if (!stackframe_sp) + return false; + + const Address pc_addr(stackframe_sp->GetFrameCodeAddress()); + + lldb::ModuleSP current_module(pc_addr.GetModule()); + if (!current_module) + return false; + + auto current_module_mod_time = current_module->GetModificationTime(); + + if (time <= current_module_mod_time) { + return false; } + + return true; +} + +void SourceManager::File::Update(llvm::sys::TimePoint<> modification_time) { + m_data_sp = FileSystem::Instance().CreateDataBuffer(m_file_spec); + m_offsets.clear(); + m_mod_time = modification_time; } size_t SourceManager::File::DisplaySourceLines(uint32_t line,