[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