> On Sep 11, 2018, at 2:55 AM, Stefan Gränitz <sgraen...@apple.com> wrote:
> 
> Hello everyone
> 
> I am investigating a bug that prevents correct breakpoint resolution in LTO 
> objects with embedded DWARF (no separate dSYM file) and tracked it down to 
> the initialization of SymbolFileDWARFDebugMap. This code seems to assume 
> there is only one compile unit per object file, but LTO objects have more 
> than that:
> 
> void SymbolFileDWARFDebugMap::InitOSO() {
> ...
>   const uint32_t oso_index_count =
>     symtab->AppendSymbolIndexesWithTypeAndFlagsValue(
>         eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes);
> ...
>   m_compile_unit_infos.resize(oso_index_count); // <—— one CU per OSO entry 
> in the Symtab
> 
>   for (uint32_t i = 0; i < oso_index_count; ++i) {
>     const uint32_t so_idx = oso_indexes[i] - 1;
>     const uint32_t oso_idx = oso_indexes[i];
>     const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx);
>     const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx);
> ...
>       const Symbol *last_symbol = symtab->SymbolAtIndex(sibling_idx - 1);
>       m_compile_unit_infos[i].first_symbol_index = so_idx;
>       m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1;
>       m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID();
>       m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID();
> 
> The symptom is that LLDB will only read debug_line for one CU and miss all 
> the rest. Thus, breakpoints in other CUs can’t be associated with line 
> information.
> 
> I wonder if there is a good way to populate the correct number of compile 
> units from the OSO entry at this point?

The reason it is like this is we don't want to have to open all .o files when 
we parse the debug map in order to figure out a compile unit index. Right now 
the compile unit UserID is just the index of the .o file in the debug map. 
Opening thousands of .o files can impose a performance issue.
> 
> The situation may appear similar to an archive file with a number of objects, 
> but then we have separate OSO entries like 
> “path/to/lib/libLLVMMCParser.a(AsmLexer.cpp.o)”. Furthermore LTO objects have 
> one common symtab for all compile units and it was probably mixed up by 
> optimization, so we cannot simply say that CUs start/end at certain symbol 
> indexes as in the above code. The latter is used rarely and only in 
> SymbolFileDWARFDebugMap, so there may be a workaround, but first I have to 
> figure out the initial question:
> 
> How to get more information about compile units in an LTO object? Any ideas 
> welcome!

The only way is to open each .o file and see how many compile units they 
contain. Right now we assume that each .o file has only on CU so we don't need 
to open all .o files in SymbolFileDWARFDebugMap::CalculateAbilities() which is 
something that gets run when we are trying to figure out which SymbolFile 
plug-in to load. But that being said, in the past I re-ordered how the 
SymbolFile plug-ins were initialized to always put SymbolFileDWARF first and if 
it finds DWARF debug info or a dSYM file and has all the abilities then we stop 
looking for symbol file plug-ins that can load the current file. The problem 
used to be that even if we had a dSYM file, the loop that selected the symbol 
file plug-in would give each and every symbol file plugin a chance to tell us 
how much info they could extract via a call to SymbolFile::CalculateAbilities() 
and that would cause us to open all .o files just to say "I parse all debug 
info" just like a previous plug-in could. So as soon as a SymbolFile plug-in 
can do everything we now stop.

> If that’s not possible, I may find another way to fix it further down the 
> road, but then the name m_compile_unit_infos seems not exactly correct here. 
> It’s rather something like m_referenced_object_infos, right?

So now that that change has been in for a while, it might be ok to open each .o 
file and see how many compile units they contain and then populate 
m_compile_unit_infos as needed. You will need to watch for any usage of 
m_compile_unit_infos and make sure it does the correct thing.


> Btw.: My first attempt was a workaround for the symptom (see 
> https://reviews.llvm.org/D51546 <https://reviews.llvm.org/D51546>). It simply 
> reads all debug_lines for a single CU, but I’d really appreciate a better 
> solution.

The fix in D51546 seems wrong because the only way we get to a line table is 
via the DW_AT_stmt_list from a compile unit. If we can fix the LTO case to load 
all compile units from the LTO.o files with multiple CU's this fix won't be 
needed.

So the correct solution is to detect how many compile units are in each .o file 
and then make sure to find all places that were assuming anything about the OSO 
index being the compile unit UserID are fixed. Now that plug-in loading stops 
after a SymbolFile says it can handle everything we can probably do a bit more 
work. One issue is that .o files might have been cleaned up or removed, so be 
sure to test any solution by removing the .o files and seeing how we do.

I will be happy to review any patch you have. I can't think of any other reason 
the the OSO index needs to be the compile unit index. IF you do make a patch, 
please remove any functions in SymbolFileDWARFDebugMap that are dead code. 
SymbolFileDWARFDebugMap::GetModuleByOSOIndex() seems to be dead. If that is 
dead thenvSymbolFileDWARFDebugMap::GetObjectFileByOSOIndex() seems to be dead 
also.


_______________________________________________
lldb-dev mailing list
lldb-dev@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev

Reply via email to