diff options
Diffstat (limited to 'lldb/source')
-rw-r--r-- | lldb/source/Commands/CommandObjectBreakpoint.cpp | 9 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectSource.cpp | 73 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectTarget.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Core/AddressResolverFileLine.cpp | 4 | ||||
-rw-r--r-- | lldb/source/Core/FileLineResolver.cpp | 118 | ||||
-rw-r--r-- | lldb/source/Core/SearchFilter.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Core/SourceManager.cpp | 29 | ||||
-rw-r--r-- | lldb/source/Symbol/LineTable.cpp | 35 | ||||
-rw-r--r-- | lldb/source/Symbol/SymbolContext.cpp | 14 |
9 files changed, 248 insertions, 38 deletions
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp index f3a90fefe6d..6a81eefc568 100644 --- a/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -337,13 +337,10 @@ CommandObjectBreakpointSet::Execute } else { - const SymbolContext &context = cur_frame->GetSymbolContext(true); - if (context.line_entry.file) + const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry); + if (sc.line_entry.file) { - file = context.line_entry.file; - } - else if (context.comp_unit != NULL) - { file = context.comp_unit; + file = sc.line_entry.file; } else { diff --git a/lldb/source/Commands/CommandObjectSource.cpp b/lldb/source/Commands/CommandObjectSource.cpp index 4cca0752746..2e4645eb0fd 100644 --- a/lldb/source/Commands/CommandObjectSource.cpp +++ b/lldb/source/Commands/CommandObjectSource.cpp @@ -15,11 +15,12 @@ // Project includes #include "lldb/Interpreter/Args.h" #include "lldb/Core/Debugger.h" +#include "lldb/Core/FileLineResolver.h" +#include "lldb/Core/SourceManager.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Host/FileSpec.h" #include "lldb/Target/Process.h" -#include "lldb/Core/SourceManager.h" #include "lldb/Target/TargetList.h" #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/Options.h" @@ -28,7 +29,7 @@ using namespace lldb; using namespace lldb_private; //------------------------------------------------------------------------- -// CommandObjectSourceList +// CommandObjectSourceInfo //------------------------------------------------------------------------- class CommandObjectSourceInfo : public CommandObject @@ -177,7 +178,7 @@ class CommandObjectSourceList : public CommandObject error.SetErrorStringWithFormat("Invalid line count: '%s'.\n", option_arg); break; - case 'f': + case 'f': file_name = option_arg; break; @@ -186,7 +187,11 @@ class CommandObjectSourceList : public CommandObject break; case 's': - m_modules.push_back (std::string (option_arg)); + modules.push_back (std::string (option_arg)); + break; + + case 'b': + show_bp_locs = true; break; default: error.SetErrorStringWithFormat("Unrecognized short option '%c'.\n", short_option); @@ -204,7 +209,8 @@ class CommandObjectSourceList : public CommandObject symbol_name.clear(); start_line = 0; num_lines = 10; - m_modules.clear(); + show_bp_locs = false; + modules.clear(); } const OptionDefinition* @@ -220,7 +226,8 @@ class CommandObjectSourceList : public CommandObject std::string symbol_name; uint32_t start_line; uint32_t num_lines; - STLStringArray m_modules; + STLStringArray modules; + bool show_bp_locs; }; public: @@ -291,12 +298,12 @@ public: bool append = true; size_t num_matches = 0; - if (m_options.m_modules.size() > 0) + if (m_options.modules.size() > 0) { ModuleList matching_modules; - for (unsigned i = 0, e = m_options.m_modules.size(); i != e; i++) + for (unsigned i = 0, e = m_options.modules.size(); i != e; i++) { - FileSpec module_spec(m_options.m_modules[i].c_str(), false); + FileSpec module_spec(m_options.modules[i].c_str(), false); if (module_spec) { matching_modules.Clear(); @@ -408,8 +415,8 @@ public: m_options.num_lines = end_line - line_no; } - char path_buf[PATH_MAX+1]; - start_file.GetPath(path_buf, PATH_MAX); + char path_buf[PATH_MAX]; + start_file.GetPath(path_buf, sizeof(path_buf)); result.AppendMessageWithFormat("File: %s.\n", path_buf); m_interpreter.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbers (start_file, line_no, @@ -430,7 +437,8 @@ public: // more likely because you typed it once, then typed it again if (m_options.start_line == 0) { - if (m_interpreter.GetDebugger().GetSourceManager().DisplayMoreWithLineNumbers (&result.GetOutputStream())) + if (m_interpreter.GetDebugger().GetSourceManager().DisplayMoreWithLineNumbers (&result.GetOutputStream(), + GetBreakpointLocations ())) { result.SetStatus (eReturnStatusSuccessFinishResult); } @@ -442,7 +450,8 @@ public: 0, // Lines before line to display m_options.num_lines, // Lines after line to display "", // Don't mark "line" - &result.GetOutputStream())) + &result.GetOutputStream(), + GetBreakpointLocations ())) { result.SetStatus (eReturnStatusSuccessFinishResult); } @@ -465,21 +474,21 @@ public: SymbolContextList sc_list; size_t num_matches = 0; - if (m_options.m_modules.size() > 0) + if (m_options.modules.size() > 0) { ModuleList matching_modules; - for (unsigned i = 0, e = m_options.m_modules.size(); i != e; i++) + for (unsigned i = 0, e = m_options.modules.size(); i != e; i++) { - FileSpec module_spec(m_options.m_modules[i].c_str(), false); + FileSpec module_spec(m_options.modules[i].c_str(), false); if (module_spec) { matching_modules.Clear(); target->GetImages().FindModules (&module_spec, NULL, NULL, NULL, matching_modules); num_matches += matching_modules.ResolveSymbolContextForFilePath (filename, - 0, - check_inlines, - eSymbolContextModule | eSymbolContextCompUnit, - sc_list); + 0, + check_inlines, + eSymbolContextModule | eSymbolContextCompUnit, + sc_list); } } } @@ -535,13 +544,24 @@ public: { if (sc.comp_unit) { + if (m_options.show_bp_locs && exe_ctx.target) + { + const bool show_inlines = true; + m_breakpoint_locations.Reset (*sc.comp_unit, 0, show_inlines); + SearchFilter target_search_filter (exe_ctx.target->GetSP()); + target_search_filter.Search (m_breakpoint_locations); + } + else + m_breakpoint_locations.Clear(); + m_interpreter.GetDebugger().GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.comp_unit, m_options.start_line, 0, m_options.num_lines, "", - &result.GetOutputStream()); - + &result.GetOutputStream(), + GetBreakpointLocations ()); + result.SetStatus (eReturnStatusSuccessFinishResult); } else @@ -562,7 +582,15 @@ public: } protected: + const SymbolContextList * + GetBreakpointLocations () + { + if (m_breakpoint_locations.GetFileLineMatches().GetSize() > 0) + return &m_breakpoint_locations.GetFileLineMatches(); + return NULL; + } CommandOptions m_options; + FileLineResolver m_breakpoint_locations; }; @@ -571,6 +599,7 @@ CommandObjectSourceList::CommandOptions::g_option_table[] = { { LLDB_OPT_SET_ALL, false, "count", 'c', required_argument, NULL, 0, eArgTypeCount, "The number of source lines to display."}, { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source file in the given shared library."}, +{ LLDB_OPT_SET_ALL, false, "show-breakpoints", 'b', no_argument, NULL, 0, eArgTypeNone, "Show the line table locations from the debug information that indicate valid places to set source level breakpoints."}, { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source."}, { LLDB_OPT_SET_1, false, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum, "The line number at which to start the display source."}, { LLDB_OPT_SET_2, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display."}, diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index b5693b18b8e..958aa2cf047 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -37,7 +37,7 @@ using namespace lldb_private; static void DumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm) { - ArchSpec &target_arch = target->GetArchitecture(); + const ArchSpec &target_arch = target->GetArchitecture(); ModuleSP exe_module_sp (target->GetExecutableModule ()); char exe_path[PATH_MAX]; diff --git a/lldb/source/Core/AddressResolverFileLine.cpp b/lldb/source/Core/AddressResolverFileLine.cpp index 1fdb7b90b85..0da1feb51fc 100644 --- a/lldb/source/Core/AddressResolverFileLine.cpp +++ b/lldb/source/Core/AddressResolverFileLine.cpp @@ -23,7 +23,7 @@ using namespace lldb_private; AddressResolverFileLine::AddressResolverFileLine ( const FileSpec &file_spec, - uint32_t line_no, + uint32_t line_no, bool check_inlines ) : AddressResolver (), @@ -42,7 +42,7 @@ AddressResolverFileLine::SearchCallback ( SearchFilter &filter, SymbolContext &context, - Address *addr, + Address *addr, bool containing ) { diff --git a/lldb/source/Core/FileLineResolver.cpp b/lldb/source/Core/FileLineResolver.cpp new file mode 100644 index 00000000000..9f5f3150a3d --- /dev/null +++ b/lldb/source/Core/FileLineResolver.cpp @@ -0,0 +1,118 @@ +//===-- FileLineResolver.cpp ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/FileLineResolver.h" + +// Project includes +#include "lldb/lldb-private-log.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/StreamString.h" +#include "lldb/Symbol/LineTable.h" + +using namespace lldb; +using namespace lldb_private; + +//---------------------------------------------------------------------- +// FileLineResolver: +//---------------------------------------------------------------------- +FileLineResolver::FileLineResolver +( + const FileSpec &file_spec, + uint32_t line_no, + bool check_inlines +) : + Searcher (), + m_file_spec (file_spec), + m_line_number (line_no), + m_inlines (check_inlines) +{ +} + +FileLineResolver::~FileLineResolver () +{ +} + +Searcher::CallbackReturn +FileLineResolver::SearchCallback +( + SearchFilter &filter, + SymbolContext &context, + Address *addr, + bool containing +) +{ + CompileUnit *cu = context.comp_unit; + + if (m_inlines || m_file_spec.Compare(*cu, m_file_spec, m_file_spec.GetDirectory())) + { + uint32_t start_file_idx = 0; + uint32_t file_idx = cu->GetSupportFiles().FindFileIndex(start_file_idx, m_file_spec); + if (file_idx != UINT32_MAX) + { + LineTable *line_table = cu->GetLineTable(); + if (line_table) + { + if (m_line_number == 0) + { + // Match all lines in a file... + const bool append = true; + while (file_idx != UINT32_MAX) + { + line_table->FineLineEntriesForFileIndex (file_idx, append, m_sc_list); + // Get the next file index in case we have multiple file + // entries for the same file + file_idx = cu->GetSupportFiles().FindFileIndex(file_idx + 1, m_file_spec); + } + } + else + { + // Match a specific line in a file... + } + } + } + } + return Searcher::eCallbackReturnContinue; +} + +Searcher::Depth +FileLineResolver::GetDepth() +{ + return Searcher::eDepthCompUnit; +} + +void +FileLineResolver::GetDescription (Stream *s) +{ + s->Printf ("File and line resolver for file: \"%s%s%s\" line: %u", + m_file_spec.GetDirectory().GetCString(), + m_file_spec.GetDirectory() ? "/" : "", + m_file_spec.GetFilename().GetCString(), + m_line_number); +} + +void +FileLineResolver::Clear() +{ + m_file_spec.Clear(); + m_line_number = UINT32_MAX; + m_sc_list.Clear(); + m_inlines = true; +} + +void +FileLineResolver::Reset (const FileSpec &file_spec, + uint32_t line, + bool check_inlines) +{ + m_file_spec = file_spec; + m_line_number = line; + m_sc_list.Clear(); + m_inlines = check_inlines; +} + diff --git a/lldb/source/Core/SearchFilter.cpp b/lldb/source/Core/SearchFilter.cpp index c8888421af7..cc0a8d5034f 100644 --- a/lldb/source/Core/SearchFilter.cpp +++ b/lldb/source/Core/SearchFilter.cpp @@ -40,7 +40,7 @@ Searcher::GetDescription (Stream *s) //---------------------------------------------------------------------- // SearchFilter constructor //---------------------------------------------------------------------- -SearchFilter::SearchFilter(lldb::TargetSP &target_sp) : +SearchFilter::SearchFilter(const TargetSP &target_sp) : m_target_sp (target_sp) { } diff --git a/lldb/source/Core/SourceManager.cpp b/lldb/source/Core/SourceManager.cpp index a43b592c231..04a0d766c0f 100644 --- a/lldb/source/Core/SourceManager.cpp +++ b/lldb/source/Core/SourceManager.cpp @@ -15,6 +15,7 @@ // Project includes #include "lldb/Core/DataBuffer.h" #include "lldb/Core/Stream.h" +#include "lldb/Symbol/SymbolContext.h" using namespace lldb_private; @@ -85,7 +86,8 @@ SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile uint32_t context_before, uint32_t context_after, const char* current_line_cstr, - Stream *s + Stream *s, + const SymbolContextList *bp_locs ) { if (line == 0) @@ -119,7 +121,21 @@ SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile break; } - s->Printf("%2.2s %-4u\t", curr_line == line ? current_line_cstr : "", curr_line); + char prefix[32] = ""; + if (bp_locs) + { + uint32_t bp_count = bp_locs->NumLineEntriesWithLine (curr_line); + + if (bp_count > 0) + ::snprintf (prefix, sizeof (prefix), "[%u] ", bp_count); + else + ::snprintf (prefix, sizeof (prefix), " "); + } + + s->Printf("%s%2.2s %-4u\t", + prefix, + curr_line == line ? current_line_cstr : "", + curr_line); if (m_last_file_sp->DisplaySourceLines (curr_line, 0, 0, s) == 0) { m_last_file_line = UINT32_MAX; @@ -138,7 +154,8 @@ SourceManager::DisplaySourceLinesWithLineNumbers uint32_t context_before, uint32_t context_after, const char* current_line_cstr, - Stream *s + Stream *s, + const SymbolContextList *bp_locs ) { bool same_as_previous = m_last_file_sp && m_last_file_sp->FileSpecMatches (file_spec); @@ -152,17 +169,17 @@ SourceManager::DisplaySourceLinesWithLineNumbers m_last_file_line = 0; } - return DisplaySourceLinesWithLineNumbersUsingLastFile (line, context_before, context_after, current_line_cstr, s); + return DisplaySourceLinesWithLineNumbersUsingLastFile (line, context_before, context_after, current_line_cstr, s, bp_locs); } size_t -SourceManager::DisplayMoreWithLineNumbers (Stream *s) +SourceManager::DisplayMoreWithLineNumbers (Stream *s, const SymbolContextList *bp_locs) { if (m_last_file_sp) { if (m_last_file_line == UINT32_MAX) return 0; - DisplaySourceLinesWithLineNumbersUsingLastFile (0, m_last_file_context_before, m_last_file_context_after, "", s); + DisplaySourceLinesWithLineNumbersUsingLastFile (0, m_last_file_context_before, m_last_file_context_after, "", s, bp_locs); } return 0; } diff --git a/lldb/source/Symbol/LineTable.cpp b/lldb/source/Symbol/LineTable.cpp index 875f12cce3b..69deba4ba34 100644 --- a/lldb/source/Symbol/LineTable.cpp +++ b/lldb/source/Symbol/LineTable.cpp @@ -378,6 +378,41 @@ LineTable::FindLineEntryIndexByFileIndex (uint32_t start_idx, uint32_t file_idx, return UINT32_MAX; } +size_t +LineTable::FineLineEntriesForFileIndex (uint32_t file_idx, + bool append, + SymbolContextList &sc_list) +{ + + if (!append) + sc_list.Clear(); + + size_t num_added = 0; + const size_t count = m_entries.size(); + if (count > 0) + { + SymbolContext sc (m_comp_unit); + + for (size_t idx = 0; idx < count; ++idx) + { + // Skip line table rows that terminate the previous row (is_terminal_entry is non-zero) + if (m_entries[idx].is_terminal_entry) + continue; + + if (m_entries[idx].file_idx == file_idx) + { + if (ConvertEntryAtIndexToLineEntry (idx, sc.line_entry)) + { + ++num_added; + sc_list.Append(sc); + } + } + } + } + return num_added; +} + + void LineTable::Dump (Stream *s, Target *target, Address::DumpStyle style, Address::DumpStyle fallback_style, bool show_line_ranges) { diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp index d0624c2cd68..717657b1ee1 100644 --- a/lldb/source/Symbol/SymbolContext.cpp +++ b/lldb/source/Symbol/SymbolContext.cpp @@ -842,3 +842,17 @@ SymbolContextList::GetSize() const { return m_symbol_contexts.size(); } + +uint32_t +SymbolContextList::NumLineEntriesWithLine (uint32_t line) const +{ + uint32_t match_count = 0; + const uint32_t size = m_symbol_contexts.size(); + for (uint32_t idx = 0; idx<size; ++idx) + { + if (m_symbol_contexts[idx].line_entry.line == line) + ++match_count; + } + return match_count; +} + |