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

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Thu Feb 4 01:29:02 PST 2016


+1 for using IR for hand-crafting tricky functions.


On 3 February 2016 at 22:01, Adrian Prantl via lldb-commits
<lldb-commits at lists.llvm.org> wrote:
>
> On Feb 3, 2016, at 1:58 PM, Zachary Turner <zturner at google.com> wrote:
>
> I was thinking of a really trivial function that just returned an int or
> something.  But then again, I don't really know how to write LLVM IR myself
> so I was just going off of what other people told me would be possible.  I
> could be wrong :)
>
>
> I’m not saying that it is impossible to find such a function, but keep in
> mind that even the size of int is baked into the IR.
>
> -- adrian
>
>
> Maybe not worth worrying about if clang never generates this type of code
> anyway, just an idea.
>
> On Wed, Feb 3, 2016 at 1:35 PM Adrian Prantl <aprantl at apple.com> wrote:
>>
>> For context, here are the relevant LLVM discussions:
>> http://reviews.llvm.org/D16569 (D16569: Emit line 0 line information for
>> interesting 'orphan’ instructions)
>> 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> 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> 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> 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> 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
>>>> > 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
>>>> >
>>>> > ==============================================================================
>>>> > --- 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
>>>> >
>>>> > ==============================================================================
>>>> > --- 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
>>>> > http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
>>>>
>
>
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
>


More information about the lldb-commits mailing list