(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 <ztur...@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? > > 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 <jing...@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 <ztur...@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@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@lists.llvm.org >> > http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits >> >>
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits