36#include "llvm/ADT/Twine.h"
68 return std::string(llvm::formatv(
"{0}", checksum.
digest()));
78 : m_last_support_file_nsp(std::make_shared<
SupportFile>()), m_last_line(0),
79 m_last_count(0), m_default_set(false), m_target_wp(),
80 m_debugger_wp(debugger_sp) {}
86 FileSpec file_spec = support_file_nsp->GetSpecOnly();
95 if (!debugger_sp || !debugger_sp->GetUseSourceCache()) {
96 LLDB_LOG(log,
"Source file caching disabled: creating new source file: {0}",
99 return std::make_shared<File>(support_file_nsp, target_sp);
100 return std::make_shared<File>(support_file_nsp, debugger_sp);
109 process_sp->GetSourceFileCache().FindSourceFile(file_spec)) {
110 LLDB_LOG(log,
"Found source file in the process cache: {0}", file_spec);
111 if (file_sp->PathRemappingIsStale()) {
112 LLDB_LOG(log,
"Path remapping is stale: removing file from caches: {0}",
117 debugger_sp->GetSourceFileCache().RemoveSourceFile(file_sp);
118 process_sp->GetSourceFileCache().RemoveSourceFile(file_sp);
128 FileSP file_sp = debugger_sp->GetSourceFileCache().FindSourceFile(file_spec);
133 LLDB_LOG(log,
"Found source file in the debugger cache: {0}", file_spec);
136 if (file_sp && file_sp->PathRemappingIsStale()) {
137 LLDB_LOG(log,
"Path remapping is stale: {0}", file_spec);
142 if (file_sp && file_sp->ModificationTimeIsStale()) {
143 LLDB_LOG(log,
"Modification time is stale: {0}", file_spec);
149 file_sp->GetSupportFile()->GetSpecOnly())) {
150 LLDB_LOG(log,
"File doesn't exist on disk: {0}", file_spec);
157 LLDB_LOG(log,
"Creating and caching new source file: {0}", file_spec);
161 file_sp = std::make_shared<File>(support_file_nsp, target_sp);
163 file_sp = std::make_shared<File>(support_file_nsp, debugger_sp);
167 debugger_sp->GetSourceFileCache().AddSourceFile(file_spec, file_sp);
169 process_sp->GetSourceFileCache().AddSourceFile(file_spec, file_sp);
181 if (!debugger_sp->GetUseColor())
184 return debugger_sp->GetHighlightSource();
195 if (!debugger_sp->GetUseColor())
201 const auto value = debugger_sp->GetStopShowColumn();
214 const auto value = debugger_sp->GetStopShowColumn();
224 return debugger_sp && debugger_sp->GetUseColor();
228 uint32_t start_line, uint32_t count, uint32_t curr_line, uint32_t column,
229 const char *current_line_cstr,
Stream *s,
236 if (start_line == 0) {
250 const uint32_t end_line = start_line + count - 1;
251 for (uint32_t line = start_line; line <= end_line; ++line) {
252 if (!last_file_sp->LineIsValid(line)) {
262 prefix = llvm::formatv(
"[{0}]", bp_count);
268 snprintf(buffer,
sizeof(buffer),
"%2.2s",
269 (line == curr_line) ? current_line_cstr :
"");
270 std::string current_line_highlight(buffer);
275 (debugger_sp->GetStopShowLineMarkerAnsiPrefix() +
276 current_line_highlight +
277 debugger_sp->GetStopShowLineMarkerAnsiSuffix())
281 s->
Printf(
"%s%s %-4u\t", prefix.c_str(), current_line_highlight.c_str(),
287 std::optional<size_t> columnToHighlight;
288 if (line == curr_line && column)
289 columnToHighlight = column - 1;
291 size_t this_line_size =
292 last_file_sp->DisplaySourceLines(line, columnToHighlight, 0, 0, s);
293 if (column != 0 && line == curr_line &&
296 std::string src_line;
297 last_file_sp->GetLine(line, src_line);
300 for (
size_t i = 0; i + 1 < column && i < src_line.length(); ++i)
301 s->
PutChar(src_line[i] ==
'\t' ?
'\t' :
' ');
305 if (this_line_size == 0) {
312 last_file_sp->GetSupportFile()->GetChecksum();
313 Checksum on_disk_checksum = last_file_sp->GetChecksum();
314 if (line_table_checksum && line_table_checksum != on_disk_checksum)
317 "{0}: source file checksum mismatch between line table "
318 "({1}) and file on disk ({2})",
319 last_file_sp->GetSupportFile()->GetSpecOnly().GetFilename(),
321 std::nullopt, &last_file_sp->GetChecksumWarningOnceFlag());
328 uint32_t context_before, uint32_t context_after,
329 const char *current_line_cstr,
Stream *s,
331 assert(support_file_nsp &&
"SupportFile must be valid");
335 uint32_t count = context_before + context_after + 1;
336 if (line > context_before)
337 start_line = line - context_before;
342 if (last_file_sp.get() != file_sp.get()) {
349 start_line, count, line, column, current_line_cstr, s, bp_locs);
357 const bool have_default_file_line = last_file_sp &&
m_last_line > 0;
379 }
else if (have_default_file_line)
384 const uint32_t column = 0;
393 assert(support_file_nsp &&
"SupportFile must be valid");
406std::optional<SourceManager::SupportFileAndLine>
419 Module *executable_ptr = target_sp->GetExecutableModulePointer();
420 if (executable_ptr) {
429 lldb::eFunctionNameTypeFull,
430 function_options, sc_list);
434 if (sc.function->GetAddress().CalculateSymbolContextLineEntry(
452 std::vector<uint32_t> &match_lines) {
457 return file_sp->FindLinesMatchingRegex(regex, start_line, end_line,
469 : m_support_file_nsp(std::make_shared<
SupportFile>()), m_checksum(),
471 m_debugger_wp(target_sp ? target_sp->GetDebugger().shared_from_this()
483 static constexpr auto g_progress_delay = std::chrono::milliseconds(500);
485 std::future<void> future = std::async(std::launch::async, [=]() {
489 std::optional<Progress> progress;
490 if (future.wait_for(g_progress_delay) == std::future_status::timeout) {
491 Debugger *debugger = target_sp ? &target_sp->GetDebugger() :
nullptr;
492 progress.emplace(
"Loading source file",
493 support_file_nsp->GetSpecOnly().GetFilename().GetString(),
513 FileSpec file_spec = support_file_nsp->GetSpecOnly();
515 bool check_inlines =
false;
518 target_sp->GetImages().ResolveSymbolContextForFilePath(
520 SymbolContextItem(eSymbolContextModule |
521 eSymbolContextCompUnit),
523 bool got_multiple =
false;
524 if (num_matches != 0) {
525 if (num_matches > 1) {
530 if (test_cu != sc.comp_unit)
534 test_cu = sc.comp_unit;
550 FileSpec file_spec = support_file_nsp->GetSpecOnly();
555 auto remapped = target_sp->GetSourcePathMap().FindFile(file_spec);
558 if (target_sp->GetImages().FindSourceFile(file_spec, new_spec))
563 *remapped, support_file_nsp->GetChecksum()));
578 FileSpec file_spec = support_file_nsp->GetSpecOnly();
581 std::make_shared<SupportFile>(file_spec, support_file_nsp->GetChecksum());
609 if (line_offset < m_data_sp->GetByteSize())
610 return (
const char *)
m_data_sp->GetBytes() + line_offset;
615 bool include_newline_chars) {
624 if (end_offset > start_offset) {
625 uint32_t length = end_offset - start_offset;
626 if (!include_newline_chars) {
627 const char *line_start =
628 (
const char *)
m_data_sp->GetBytes() + start_offset;
630 const char last_char = line_start[length - 1];
631 if ((last_char ==
'\r') || (last_char ==
'\n'))
657 return curr_mod_time != llvm::sys::TimePoint<>() &&
664 target_sp->GetSourcePathMap().GetModificationID();
669 std::optional<size_t> column,
670 uint32_t context_before,
671 uint32_t context_after,
693 style.
selected.
Set(debugger_sp->GetStopShowColumnAnsiPrefix(),
694 debugger_sp->GetStopShowColumnAnsiSuffix());
703 const uint32_t start_line =
704 line <= context_before ? 1 : line - context_before;
705 const uint32_t start_line_offset =
GetLineOffset(start_line);
707 const uint32_t end_line = line + context_after;
710 end_line_offset =
m_data_sp->GetByteSize();
712 assert(start_line_offset <= end_line_offset);
713 if (start_line_offset < end_line_offset) {
714 size_t count = end_line_offset - start_line_offset;
715 const uint8_t *cstr =
m_data_sp->GetBytes() + start_line_offset;
717 auto ref = llvm::StringRef(
reinterpret_cast<const char *
>(cstr), count);
719 h.Highlight(style, ref, column,
"", *s);
731 std::vector<uint32_t> &match_lines) {
737 if (start_line > end_line)
740 for (uint32_t line_no = start_line; line_no < end_line; line_no++) {
745 match_lines.push_back(line_no);
770 const char *start = (
const char *)
m_data_sp->GetBytes();
772 const char *end = start +
m_data_sp->GetByteSize();
780 for (s = start; s < end; ++s) {
786 if (curr_ch != next_ch)
794 if (
m_offsets.back() <
size_t(end - start))
801 assert(
"Not implemented yet" &&
false);
806 assert(
"Not implemented yet" &&
false);
820 buffer.assign((
const char *)
m_data_sp->GetBytes() + start_offset,
821 end_offset - start_offset);
828 llvm::sys::ScopedWriter guard(
m_mutex);
830 assert(file_sp &&
"invalid FileSP");
833 const FileSpec &resolved_file_spec = file_sp->GetSupportFile()->GetSpecOnly();
834 if (file_spec != resolved_file_spec)
839 llvm::sys::ScopedWriter guard(
m_mutex);
841 assert(file_sp &&
"invalid FileSP");
847 if (it->second == file_sp)
860 if (file_sp != pos->second)
867 llvm::sys::ScopedReader guard(
m_mutex);
869 FileCache::const_iterator pos =
m_file_cache.find(file_spec);
877 stream <<
"Modification time MD5 Checksum (on-disk) MD5 Checksum (line table) Lines Path\n";
878 stream <<
"------------------- -------------------------------- -------------------------------- -------- --------------------------------\n";
883 FileSP file = entry.second;
884 stream.
Format(
"{0:%Y-%m-%d %H:%M:%S} {1,32} {2,32} {3,8:d} {4}\n",
885 file->GetTimestamp(),
toString(file->GetChecksum()),
886 toString(file->GetSupportFile()->GetChecksum()),
887 file->GetNumLines(), entry.first.GetPath());
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
static void resolve_tilde(FileSpec &file_spec)
static bool should_highlight_source(DebuggerSP debugger_sp)
static bool is_newline_char(char ch)
static bool should_show_stop_column_with_caret(DebuggerSP debugger_sp)
static bool should_show_stop_line_with_ansi(DebuggerSP debugger_sp)
static bool should_show_stop_column_with_ansi(DebuggerSP debugger_sp)
std::string digest() const
A class that describes a compilation unit.
SupportFileNSP GetPrimarySupportFile() const
Return the primary source file associated with this compile unit.
Represents a generic declaration context in a program.
A uniqued constant string class.
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
const char * GetCString() const
Get the string value as a C string.
A class to manage flag bits.
static void ReportWarning(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report warning events.
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
const ConstString & GetFilename() const
Filename string const get accessor.
const ConstString & GetDirectory() const
Directory string const get accessor.
void Resolve(llvm::SmallVectorImpl< char > &path)
Resolve path to make it canonical.
llvm::sys::TimePoint GetModificationTime(const FileSpec &file_spec) const
Returns the modification time of the given file.
static FileSystem & Instance()
std::shared_ptr< DataBuffer > CreateDataBuffer(const llvm::Twine &path, uint64_t size=0, uint64_t offset=0)
Create memory buffer from path.
void Set(llvm::StringRef prefix, llvm::StringRef suffix)
Sets the prefix and suffix strings.
Manages the available highlighters.
const Highlighter & getHighlighterFor(lldb::LanguageType language_type, llvm::StringRef path) const
Queries all known highlighter for one that can highlight some source code.
A class that describes an executable image and its associated object and symbol files.
void FindFunctions(llvm::ArrayRef< LookupInfo > lookup_infos, const CompilerDeclContext &parent_decl_ctx, const ModuleFunctionSearchOptions &options, SymbolContextList &sc_list)
Find functions by a vector of lookup infos.
bool Execute(llvm::StringRef string, llvm::SmallVectorImpl< llvm::StringRef > *matches=nullptr) const
Execute a regular expression match using the compiled regular expression that is already in this obje...
lldb::TargetWP m_target_wp
bool ModificationTimeIsStale() const
void CommonInitializerImpl(SupportFileNSP support_file_nsp, lldb::TargetSP target_sp)
llvm::sys::TimePoint m_mod_time
File(SupportFileNSP support_file_nsp, lldb::TargetSP target_sp)
uint32_t GetSourceMapModificationID() const
void FindLinesMatchingRegex(RegularExpression ®ex, uint32_t start_line, uint32_t end_line, std::vector< uint32_t > &match_lines)
void CommonInitializer(SupportFileNSP support_file_nsp, lldb::TargetSP target_sp)
const char * PeekLineData(uint32_t line)
bool LineIsValid(uint32_t line)
SupportFileNSP GetSupportFile() const
Checksum m_checksum
Keep track of the on-disk checksum.
bool PathRemappingIsStale() const
uint32_t GetLineLength(uint32_t line, bool include_newline_chars)
bool CalculateLineOffsets(uint32_t line=UINT32_MAX)
lldb::DataBufferSP m_data_sp
SupportFileNSP m_support_file_nsp
The support file.
lldb::DebuggerWP m_debugger_wp
bool GetLine(uint32_t line_no, std::string &buffer)
uint32_t GetLineOffset(uint32_t line)
uint32_t m_source_map_mod_id
size_t DisplaySourceLines(uint32_t line, std::optional< size_t > column, uint32_t context_before, uint32_t context_after, Stream *s)
void SetSupportFile(SupportFileNSP support_file_nsp)
Set file and update modification time.
void AddSourceFileImpl(const FileSpec &file_spec, FileSP file_sp)
void RemoveSourceFile(const FileSP &file_sp)
FileSP FindSourceFile(const FileSpec &file_spec) const
llvm::sys::RWMutex m_mutex
void Dump(Stream &stream) const
void AddSourceFile(const FileSpec &file_spec, FileSP file_sp)
void FindLinesMatchingRegex(SupportFileNSP support_file_nsp, RegularExpression ®ex, uint32_t start_line, uint32_t end_line, std::vector< uint32_t > &match_lines)
size_t DisplaySourceLinesWithLineNumbersUsingLastFile(uint32_t start_line, uint32_t count, uint32_t curr_line, uint32_t column, const char *current_line_cstr, Stream *s, const SymbolContextList *bp_locs=nullptr)
std::shared_ptr< File > FileSP
std::optional< SupportFileAndLine > GetDefaultFileAndLine()
bool AtLastLine(bool reverse)
SourceManager(const lldb::DebuggerSP &debugger_sp)
A source manager can be made with a valid Target, in which case it can use the path remappings to fin...
lldb::DebuggerWP m_debugger_wp
FileSP GetFile(SupportFileNSP support_file_nsp)
size_t DisplaySourceLinesWithLineNumbers(SupportFileNSP support_file_nsp, uint32_t line, uint32_t column, uint32_t context_before, uint32_t context_after, const char *current_line_cstr, Stream *s, const SymbolContextList *bp_locs=nullptr)
lldb::TargetWP m_target_wp
bool SetDefaultFileAndLine(SupportFileNSP support_file_nsp, uint32_t line)
SupportFileNSP m_last_support_file_nsp
size_t DisplayMoreWithLineNumbers(Stream *s, uint32_t count, bool reverse, const SymbolContextList *bp_locs=nullptr)
A stream class that can stream formatted output to a file.
void Format(const char *format, Args &&... args)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t EOL()
Output and End of Line character to the stream.
size_t GetWrittenBytes() const
Wraps a FileSpec and an optional Checksum.
Defines a list of symbol context objects.
bool GetContextAtIndex(size_t idx, SymbolContext &sc) const
Get accessor for a symbol context at index idx.
uint32_t NumLineEntriesWithLine(uint32_t line) const
Defines a symbol context baton that can be handed other debug core functions.
CompileUnit * comp_unit
The CompileUnit for a given query.
std::string FormatAnsiTerminalCodes(llvm::StringRef format, bool do_color=true)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
NonNullSharedPtr< lldb_private::SupportFile > SupportFileNSP
bool operator==(const Address &lhs, const Address &rhs)
const char * toString(AppleArm64ExceptionClass EC)
@ eLanguageTypeUnknown
Unknown or invalid language value.
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Debugger > DebuggerSP
@ eStopShowColumnAnsiOrCaret
std::shared_ptr< lldb_private::Target > TargetSP
Represents style that the highlighter should apply to the given source code.
static HighlightStyle MakeVimStyle()
Returns a HighlightStyle that is based on vim's default highlight style.
ColorStyle selected
The style for the token which is below the cursor of the user.
A line table entry class.
uint32_t line
The source line number, or LLDB_INVALID_LINE_NUMBER if there is no line number information.
SupportFileNSP file_sp
The source file, possibly mapped by the target.source-map setting.
Options used by Module::FindFunctions.
bool include_inlines
Include inlined functions.
bool include_symbols
Include the symbol table.