[Lldb-commits] [lldb] r113721 - in /lldb/trunk: include/lldb/Symbol/LineTable.h source/Symbol/CompileUnit.cpp source/Symbol/LineTable.cpp
Greg Clayton
gclayton at apple.com
Sat Sep 11 23:24:05 PDT 2010
Author: gclayton
Date: Sun Sep 12 01:24:05 2010
New Revision: 113721
URL: http://llvm.org/viewvc/llvm-project?rev=113721&view=rev
Log:
Bug #: 8408441
Fixed an issue where LLDB would fail to set a breakpoint by
file and line if the DWARF line table has multiple file entries
in the support files for a source file.
Modified:
lldb/trunk/include/lldb/Symbol/LineTable.h
lldb/trunk/source/Symbol/CompileUnit.cpp
lldb/trunk/source/Symbol/LineTable.cpp
Modified: lldb/trunk/include/lldb/Symbol/LineTable.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/LineTable.h?rev=113721&r1=113720&r2=113721&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/LineTable.h (original)
+++ lldb/trunk/include/lldb/Symbol/LineTable.h Sun Sep 12 01:24:05 2010
@@ -158,6 +158,13 @@
uint32_t
FindLineEntryIndexByFileIndex (uint32_t start_idx, uint32_t file_idx, uint32_t line, bool exact, LineEntry* line_entry_ptr);
+ uint32_t
+ FindLineEntryIndexByFileIndex (uint32_t start_idx,
+ const std::vector<uint32_t> &file_indexes,
+ uint32_t line,
+ bool exact,
+ LineEntry* line_entry_ptr);
+
//------------------------------------------------------------------
/// Get the line entry from the line table at index \a idx.
///
Modified: lldb/trunk/source/Symbol/CompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/CompileUnit.cpp?rev=113721&r1=113720&r2=113721&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/CompileUnit.cpp (original)
+++ lldb/trunk/source/Symbol/CompileUnit.cpp Sun Sep 12 01:24:05 2010
@@ -281,58 +281,88 @@
SymbolContextList &sc_list
)
{
- const uint32_t prev_size = sc_list.GetSize();
+ // First find all of the file indexes that match our "file_spec". If
+ // "file_spec" has an empty directory, then only compare the basenames
+ // when finding file indexes
+ std::vector<uint32_t> file_indexes;
bool file_spec_matches_cu_file_spec = FileSpec::Compare(file_spec, this, !file_spec.GetDirectory().IsEmpty()) == 0;
- if (check_inlines || file_spec_matches_cu_file_spec)
+
+ // If we are not looking for inlined functions and our file spec doesn't
+ // match then we are done...
+ if (file_spec_matches_cu_file_spec == false && check_inlines == false)
+ return 0;
+
+ uint32_t file_idx = GetSupportFiles().FindFileIndex (1, file_spec);
+ while (file_idx != UINT32_MAX)
{
- SymbolContext sc(GetModule());
- sc.comp_unit = this;
+ file_indexes.push_back (file_idx);
+ file_idx = GetSupportFiles().FindFileIndex (file_idx + 1, file_spec);
+ }
+
+ const size_t num_file_indexes = file_indexes.size();
+ if (num_file_indexes == 0)
+ return 0;
+
+ const uint32_t prev_size = sc_list.GetSize();
- uint32_t file_idx = UINT32_MAX;
+ SymbolContext sc(GetModule());
+ sc.comp_unit = this;
- // If we are looking for inline functions only and we don't
- // find it in the support files, we are done.
- if (check_inlines)
- {
- file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
- if (file_idx == UINT32_MAX)
- return 0;
- }
+ if (line != 0)
+ {
+ LineTable *line_table = sc.comp_unit->GetLineTable();
- if (line != 0)
+ if (line_table != NULL)
{
- LineTable *line_table = sc.comp_unit->GetLineTable();
-
- if (line_table != NULL)
+ uint32_t found_line;
+ uint32_t line_idx;
+
+ if (num_file_indexes == 1)
{
- // We will have already looked up the file index if
- // we are searching for inline entries.
- if (!check_inlines)
- file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
+ // We only have a single support file that matches, so use
+ // the line table function that searches for a line entries
+ // that match a single support file index
+ line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_indexes.front(), line, exact, &sc.line_entry);
+
+ // If "exact == true", then "found_line" will be the same
+ // as "line". If "exact == false", the "found_line" will be the
+ // closest line entry with a line number greater than "line" and
+ // we will use this for our subsequent line exact matches below.
+ found_line = sc.line_entry.line;
- if (file_idx != UINT32_MAX)
+ while (line_idx != UINT_MAX)
{
- uint32_t found_line;
-
- uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, exact, &sc.line_entry);
- found_line = sc.line_entry.line;
+ sc_list.Append(sc);
+ line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_indexes.front(), found_line, true, &sc.line_entry);
+ }
+ }
+ else
+ {
+ // We found multiple support files that match "file_spec" so use
+ // the line table function that searches for a line entries
+ // that match a multiple support file indexes.
+ line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_indexes, line, exact, &sc.line_entry);
+
+ // If "exact == true", then "found_line" will be the same
+ // as "line". If "exact == false", the "found_line" will be the
+ // closest line entry with a line number greater than "line" and
+ // we will use this for our subsequent line exact matches below.
+ found_line = sc.line_entry.line;
- while (line_idx != UINT_MAX)
- {
- sc_list.Append(sc);
- line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
- }
+ while (line_idx != UINT_MAX)
+ {
+ sc_list.Append(sc);
+ line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_indexes, found_line, true, &sc.line_entry);
}
}
}
- else if (file_spec_matches_cu_file_spec && !check_inlines)
- {
- // only append the context if we aren't looking for inline call sites
- // by file and line and if the file spec matches that of the compile unit
- sc_list.Append(sc);
- }
-
+ }
+ else if (file_spec_matches_cu_file_spec && !check_inlines)
+ {
+ // only append the context if we aren't looking for inline call sites
+ // by file and line and if the file spec matches that of the compile unit
+ sc_list.Append(sc);
}
return sc_list.GetSize() - prev_size;
}
Modified: lldb/trunk/source/Symbol/LineTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/LineTable.cpp?rev=113721&r1=113720&r2=113721&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/LineTable.cpp (original)
+++ lldb/trunk/source/Symbol/LineTable.cpp Sun Sep 12 01:24:05 2010
@@ -281,6 +281,64 @@
}
uint32_t
+LineTable::FindLineEntryIndexByFileIndex
+(
+ uint32_t start_idx,
+ const std::vector<uint32_t> &file_indexes,
+ uint32_t line,
+ bool exact,
+ LineEntry* line_entry_ptr
+)
+{
+
+ const size_t count = m_entries.size();
+ std::vector<uint32_t>::const_iterator begin_pos = file_indexes.begin();
+ std::vector<uint32_t>::const_iterator end_pos = file_indexes.end();
+ size_t best_match = UINT_MAX;
+
+ for (size_t idx = start_idx; 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 (find (begin_pos, end_pos, m_entries[idx].file_idx) == end_pos)
+ continue;
+
+ // Exact match always wins. Otherwise try to find the closest line > the desired
+ // line.
+ // FIXME: Maybe want to find the line closest before and the line closest after and
+ // if they're not in the same function, don't return a match.
+
+ if (m_entries[idx].line < line)
+ {
+ continue;
+ }
+ else if (m_entries[idx].line == line)
+ {
+ if (line_entry_ptr)
+ ConvertEntryAtIndexToLineEntry (idx, *line_entry_ptr);
+ return idx;
+ }
+ else if (!exact)
+ {
+ if (best_match == UINT32_MAX)
+ best_match = idx;
+ else if (m_entries[idx].line < m_entries[best_match].line)
+ best_match = idx;
+ }
+ }
+
+ if (best_match != UINT_MAX)
+ {
+ if (line_entry_ptr)
+ ConvertEntryAtIndexToLineEntry (best_match, *line_entry_ptr);
+ return best_match;
+ }
+ return UINT_MAX;
+}
+
+uint32_t
LineTable::FindLineEntryIndexByFileIndex (uint32_t start_idx, uint32_t file_idx, uint32_t line, bool exact, LineEntry* line_entry_ptr)
{
const size_t count = m_entries.size();
More information about the lldb-commits
mailing list