[Lldb-commits] [lldb] r259611 - The compiler may use "line number 0" to indicate compiler generated goo that it can't

Adrian Prantl via lldb-commits lldb-commits at lists.llvm.org
Wed Feb 3 13:35:46 PST 2016


For context, here are the relevant LLVM discussions:
http://reviews.llvm.org/D16569 <http://reviews.llvm.org/D16569> (D16569: Emit line 0 line information for interesting 'orphan’ instructions)
http://reviews.llvm.org/D9887 <http://reviews.llvm.org/D9887> [DebugInfo][FastISel] Prevent using debug location from previous block for local values

> On Feb 3, 2016, at 12:56 PM, Zachary Turner <zturner at google.com> wrote:
> 
> (Also, if clang is not generating code like this currently, maybe it's not a priority, but seems worth mentioning the technique anyway, since it could have a lot of use for these types of scenarios)
> 
> On Wed, Feb 3, 2016 at 12:54 PM Zachary Turner <zturner at google.com <mailto:zturner at google.com>> wrote:
> I asked around a little bit, and it seems like you do this by hand-writing some LLVM IR (limiting yourself to a subset that is sufficiently platform independent) and having clang link that in alongside a regular executable.  Then call your LLVM IR function from C++ and step over it.  Would that work?

LLVM IR is nowhere near platform independent enough for this to be portable. Of course having a test for a single target is probably still better than having no test. I’m not sure if the effort of maintaining textual IR (which tends to change a lot) in the LLDB testsuite is worth it. Another option (not any less messy) would be to compile the test to assembler with -S insert a .loc 0 before assembling the file.

-- adrian

> 
> You'd probably need to talk to one of the LLVM guys to figure out how to do that, but it seems like it should work.
> 
> Assuming it does, this technique would also open the door to writing a lot of test cases that have historically been very difficult to write (such as unwinder tests that need frames to be constructed a specific way, etc).
> 
> 
> 
> On Tue, Feb 2, 2016 at 5:31 PM Jim Ingham <jingham at apple.com <mailto:jingham at apple.com>> wrote:
> I don't think Clang does this right now, but Adrian says they are considering doing it to solve some problems they have with keeping track of nested inlines.
> 
> Swift does it, but the compiler makes no guarantees as to when this will happen.  It isn't controlled by some pragma, builtin or whatever.  So I know some places where it will happen today, but there's no guarantee it will continue to happen in the future.  So I'll have to write a test that works with the current compiler, and fails if the compiler changes so the relevant function no longer has line number 0 code right after the prologue.  Yuck!
> 
> I don't think it will be any different with clang when/if it starts doing this.
> 
> Jim
> 
> 
> > On Feb 2, 2016, at 4:14 PM, Zachary Turner <zturner at google.com <mailto:zturner at google.com>> wrote:
> >
> > Shouldn't it be possible to force clang to generate code like this?  If so couldn't you write a test for this by stepping over a function call which has this kind of code in it?
> >
> > On Tue, Feb 2, 2016 at 4:11 PM Jim Ingham via lldb-commits <lldb-commits at lists.llvm.org <mailto:lldb-commits at lists.llvm.org>> wrote:
> > Author: jingham
> > Date: Tue Feb  2 18:07:23 2016
> > New Revision: 259611
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=259611&view=rev <http://llvm.org/viewvc/llvm-project?rev=259611&view=rev>
> > Log:
> > The compiler may use "line number 0" to indicate compiler generated goo that it can't
> > track a source for.  When we are pushing breakpoints and stepping past function prologues,
> > also push past code from line 0 immediately following the prologue end.
> >
> > <rdar://problem/23730696>
> >
> > Modified:
> >     lldb/trunk/include/lldb/Symbol/Function.h
> >     lldb/trunk/source/Symbol/Function.cpp
> >
> > Modified: lldb/trunk/include/lldb/Symbol/Function.h
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Function.h?rev=259611&r1=259610&r2=259611&view=diff <http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/Function.h?rev=259611&r1=259610&r2=259611&view=diff>
> > ==============================================================================
> > --- lldb/trunk/include/lldb/Symbol/Function.h (original)
> > +++ lldb/trunk/include/lldb/Symbol/Function.h Tue Feb  2 18:07:23 2016
> > @@ -574,6 +574,14 @@ public:
> >      CompilerType
> >      GetCompilerType ();
> >
> > +    //------------------------------------------------------------------
> > +    /// Get the size of the prologue instructions for this function.  The "prologue"
> > +    /// instructions include any instructions given line number 0 immediately following
> > +    /// the prologue end.
> > +    ///
> > +    /// @return
> > +    ///     The size of the prologue.
> > +    //------------------------------------------------------------------
> >      uint32_t
> >      GetPrologueByteSize ();
> >
> >
> > Modified: lldb/trunk/source/Symbol/Function.cpp
> > URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Function.cpp?rev=259611&r1=259610&r2=259611&view=diff <http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Function.cpp?rev=259611&r1=259610&r2=259611&view=diff>
> > ==============================================================================
> > --- lldb/trunk/source/Symbol/Function.cpp (original)
> > +++ lldb/trunk/source/Symbol/Function.cpp Tue Feb  2 18:07:23 2016
> > @@ -570,6 +570,8 @@ Function::GetPrologueByteSize ()
> >      {
> >          m_flags.Set(flagsCalculatedPrologueSize);
> >          LineTable* line_table = m_comp_unit->GetLineTable ();
> > +        uint32_t prologue_end_line_idx = 0;
> > +
> >          if (line_table)
> >          {
> >              LineEntry first_line_entry;
> > @@ -578,9 +580,12 @@ Function::GetPrologueByteSize ()
> >              {
> >                  // Make sure the first line entry isn't already the end of the prologue
> >                  addr_t prologue_end_file_addr = LLDB_INVALID_ADDRESS;
> > +                addr_t line_zero_end_file_addr = LLDB_INVALID_ADDRESS;
> > +
> >                  if (first_line_entry.is_prologue_end)
> >                  {
> >                      prologue_end_file_addr = first_line_entry.range.GetBaseAddress().GetFileAddress();
> > +                    prologue_end_line_idx = first_line_entry_idx;
> >                  }
> >                  else
> >                  {
> > @@ -595,6 +600,7 @@ Function::GetPrologueByteSize ()
> >                              if (line_entry.is_prologue_end)
> >                              {
> >                                  prologue_end_file_addr = line_entry.range.GetBaseAddress().GetFileAddress();
> > +                                prologue_end_line_idx = idx;
> >                                  break;
> >                              }
> >                          }
> > @@ -607,7 +613,7 @@ Function::GetPrologueByteSize ()
> >                  {
> >                      // Check the first few instructions and look for one that has
> >                      // a line number that's different than the first entry.
> > -                    const uint32_t last_line_entry_idx = first_line_entry_idx + 6;
> > +                    uint32_t last_line_entry_idx = first_line_entry_idx + 6;
> >                      for (uint32_t idx = first_line_entry_idx + 1; idx < last_line_entry_idx; ++idx)
> >                      {
> >                          LineEntry line_entry;
> > @@ -616,6 +622,7 @@ Function::GetPrologueByteSize ()
> >                              if (line_entry.line != first_line_entry.line)
> >                              {
> >                                  prologue_end_file_addr = line_entry.range.GetBaseAddress().GetFileAddress();
> > +                                prologue_end_line_idx = idx;
> >                                  break;
> >                              }
> >                          }
> > @@ -624,10 +631,37 @@ Function::GetPrologueByteSize ()
> >                      if (prologue_end_file_addr == LLDB_INVALID_ADDRESS)
> >                      {
> >                          prologue_end_file_addr = first_line_entry.range.GetBaseAddress().GetFileAddress() + first_line_entry.range.GetByteSize();
> > +                        prologue_end_line_idx = first_line_entry_idx;
> >                      }
> >                  }
> > +
> >                  const addr_t func_start_file_addr = m_range.GetBaseAddress().GetFileAddress();
> >                  const addr_t func_end_file_addr = func_start_file_addr + m_range.GetByteSize();
> > +
> > +                // Now calculate the offset to pass the subsequent line 0 entries.
> > +                uint32_t first_non_zero_line = prologue_end_line_idx;
> > +                while (1)
> > +                {
> > +                    LineEntry line_entry;
> > +                    if (line_table->GetLineEntryAtIndex(first_non_zero_line, line_entry))
> > +                    {
> > +                        if (line_entry.line != 0)
> > +                            break;
> > +                    }
> > +                    if (line_entry.range.GetBaseAddress().GetFileAddress() >= func_end_file_addr)
> > +                        break;
> > +
> > +                    first_non_zero_line++;
> > +                }
> > +
> > +                if (first_non_zero_line > prologue_end_line_idx)
> > +                {
> > +                    LineEntry first_non_zero_entry;
> > +                    if (line_table->GetLineEntryAtIndex(first_non_zero_line, first_non_zero_entry))
> > +                    {
> > +                        line_zero_end_file_addr = first_non_zero_entry.range.GetBaseAddress().GetFileAddress();
> > +                    }
> > +                }
> >
> >                  // Verify that this prologue end file address in the function's
> >                  // address range just to be sure
> > @@ -635,10 +669,16 @@ Function::GetPrologueByteSize ()
> >                  {
> >                      m_prologue_byte_size = prologue_end_file_addr - func_start_file_addr;
> >                  }
> > +
> > +                if (prologue_end_file_addr < line_zero_end_file_addr && line_zero_end_file_addr < func_end_file_addr)
> > +                {
> > +                    m_prologue_byte_size += line_zero_end_file_addr - prologue_end_file_addr;
> > +                }
> >              }
> >          }
> >      }
> > -    return m_prologue_byte_size;
> > +
> > +        return m_prologue_byte_size;
> >  }
> >
> >  lldb::LanguageType
> >
> >
> > _______________________________________________
> > lldb-commits mailing list
> > lldb-commits at lists.llvm.org <mailto:lldb-commits at lists.llvm.org>
> > http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits <http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits>
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20160203/a81d4041/attachment-0001.html>


More information about the lldb-commits mailing list