[Lldb-commits] [lldb] r267363 - Fix unwind failures when PC points beyond the end of a function
Author: uweigand Date: Sun Apr 24 15:49:56 2016 New Revision: 267363 URL: http://llvm.org/viewvc/llvm-project?rev=267363&view=rev Log: Fix unwind failures when PC points beyond the end of a function RegisterContextLLDB::InitializeNonZerothFrame already has code to attempt to detect and handle the case where the PC points beyond the end of a function, but there are certain cases where this doesn't work correctly. In fact, there are *two* different places where this detection is attempted, and the failure is in fact a result of an unfortunate interaction between those two separate attempts. First, the ResolveSymbolContextForAddress routine is called with the resolve_tail_call_address flag set to true. This causes the routine to internally accept a PC pointing beyond the end of a function, and still resolving the PC to that function symbol. Second, the InitializeNonZerothFrame routine itself maintains a "decr_pc_and_recompute_addr_range" flag and, if that turns out to be true, itself decrements the PC by one and searches again for a symbol at that new PC value. Both approaches correctly identify the symbol associated with the PC. However, the problem is now that later on, we also need to find the DWARF CFI record associated with the PC. This is done in the RegisterContextLLDB::GetFullUnwindPlanForFrame routine, and uses the "m_current_offset_backed_up_one" member variable. However, that variable only actually contains the PC "backed up by one" if the *second* approach above was taken. If the function was already identified via the first approach above, that member variable is *not* backed up by one but simply points to the original PC. This in turn causes GetEHFrameUnwindPlan to not correctly identify the DWARF CFI record associated with the PC. Now, in many cases, if the first method had to back up the PC by one, we *still* use the second method too, because of this piece of code: // Or if we're in the middle of the stack (and not "above" an asynchronous event like sigtramp), // and our "current" pc is the start of a function... if (m_sym_ctx_valid && GetNextFrame()->m_frame_type != eTrapHandlerFrame && GetNextFrame()->m_frame_type != eDebuggerFrame && addr_range.GetBaseAddress().IsValid() && addr_range.GetBaseAddress().GetSection() == m_current_pc.GetSection() && addr_range.GetBaseAddress().GetOffset() == m_current_pc.GetOffset()) { decr_pc_and_recompute_addr_range = true; } In many cases, when the PC is one beyond the end of the current function, it will indeed then be exactly at the start of the next function. But this is not always the case, e.g. if there happens to be alignment padding between the end of one function and the start of the next. In those cases, we may sucessfully look up the function symbol via ResolveSymbolContextForAddress, but *not* set decr_pc_and_recompute_addr_range, and therefore fail to find the correct DWARF CFI record. A very simple fix for this problem is to just never use the first method. Call ResolveSymbolContextForAddress with resolve_tail_call_address set to false, which will cause it to fail if the PC is beyond the end of the current function; or else, identify the next function if the PC is also at the start of the next function. In either case, we will then set the decr_pc_and_recompute_addr_range variable and back up the PC anyway, but this time also find the correct DWARF CFI. A related problem is that the ResolveSymbolContextForAddress sometimes returns a "symbol" with empty name. This turns out to be an ELF section symbol. Now, usually those get type eSymbolTypeInvalid. However, there is code in ObjectFileELF::ParseSymbols that tries to change the type of invalid symbols to eSymbolTypeCode or eSymbolTypeData if the symbol lies within the code or data section. Unfortunately, this check also hits the symbol for the code section itself, which is then marked as eSymbolTypeCode. While the size of the section symbol is 0 according to the ELF file, LLDB considers this size invalid and attempts to figure out the "correct" size. Depending on how this goes, we may end up with a symbol that overlays part of the code section, even outside areas covered by real function symbols. Therefore, if we call ResolveSymbolContextForAddress with PC pointing beyond the end of a function, we may get this bogus section symbol. This again means InitializeNonZerothFrame thinks we have a valid PC, but then we don't find any unwind info for it. The fix for this problem is me to simply always leave ELF section symbols as type eSymbolTypeInvalid. Differential Revision: http://reviews.llvm.org/D18975 Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileEL
Re: [Lldb-commits] [PATCH] D18975: Fix unwind failures when PC points beyond the end of a function
This revision was automatically updated to reflect the committed changes. Closed by commit rL267363: Fix unwind failures when PC points beyond the end of a function (authored by uweigand). Changed prior to commit: http://reviews.llvm.org/D18975?vs=53951&id=54813#toc Repository: rL LLVM http://reviews.llvm.org/D18975 Files: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Index: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp === --- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -470,11 +470,13 @@ return; } -bool resolve_tail_call_address = true; // m_current_pc can be one past the address range of the function... - // This will handle the case where the saved pc does not point to - // a function/symbol because it is beyond the bounds of the correct - // function and there's no symbol there. ResolveSymbolContextForAddress - // will fail to find a symbol, back up the pc by 1 and re-search. +bool resolve_tail_call_address = false; // m_current_pc can be one past the address range of the function... +// If the saved pc does not point to a function/symbol because it is +// beyond the bounds of the correct function and there's no symbol there, +// we do *not* want ResolveSymbolContextForAddress to back up the pc by 1, +// because then we might not find the correct unwind information later. +// Instead, let ResolveSymbolContextForAddress fail, and handle the case +// via decr_pc_and_recompute_addr_range below. const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol; uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress (m_current_pc, resolve_scope, Index: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp === --- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -2248,7 +2248,7 @@ } } -if (symbol_type == eSymbolTypeInvalid) +if (symbol_type == eSymbolTypeInvalid && symbol.getType() != STT_SECTION) { if (symbol_section_sp) { Index: lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp === --- lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ lldb/trunk/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -470,11 +470,13 @@ return; } -bool resolve_tail_call_address = true; // m_current_pc can be one past the address range of the function... - // This will handle the case where the saved pc does not point to - // a function/symbol because it is beyond the bounds of the correct - // function and there's no symbol there. ResolveSymbolContextForAddress - // will fail to find a symbol, back up the pc by 1 and re-search. +bool resolve_tail_call_address = false; // m_current_pc can be one past the address range of the function... +// If the saved pc does not point to a function/symbol because it is +// beyond the bounds of the correct function and there's no symbol there, +// we do *not* want ResolveSymbolContextForAddress to back up the pc by 1, +// because then we might not find the correct unwind information later. +// Instead, let ResolveSymbolContextForAddress fail, and handle the case +// via decr_pc_and_recompute_addr_range below. const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol; uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress (m_current_pc, resolve_scope, Index: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
Re: [Lldb-commits] [PATCH] D18975: Fix unwind failures when PC points beyond the end of a function
uweigand added a comment. Given Tamas' update, I've now checked in the original version, including comment. If you do want me to take out the comment after all, please let me know and I'll do so. Repository: rL LLVM http://reviews.llvm.org/D18975 ___ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] r267372 - Add a --element-count option to the expression command
Author: enrico Date: Sun Apr 24 19:52:47 2016 New Revision: 267372 URL: http://llvm.org/viewvc/llvm-project?rev=267372&view=rev Log: Add a --element-count option to the expression command This option evaluates an expression and, if the result is of pointer type, treats it as if it was an array of that many elements and displays such elements This has a couple subtle points but is mostly as straightforward as it sounds Add a parray N alias for this new mode Also, extend the --object-description mode to do the moral equivalent of the above but display each element in --object-description mode Add a poarray N alias for this Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/Makefile lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/TestPrintArray.py lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/main.cpp lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/Makefile lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/TestPrintObjectArray.py lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/poarray/main.mm Modified: lldb/trunk/include/lldb/DataFormatters/DumpValueObjectOptions.h lldb/trunk/include/lldb/DataFormatters/ValueObjectPrinter.h lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h lldb/trunk/source/Commands/CommandObjectExpression.cpp lldb/trunk/source/DataFormatters/DumpValueObjectOptions.cpp lldb/trunk/source/DataFormatters/ValueObjectPrinter.cpp lldb/trunk/source/Interpreter/CommandInterpreter.cpp lldb/trunk/source/Interpreter/OptionGroupValueObjectDisplay.cpp Modified: lldb/trunk/include/lldb/DataFormatters/DumpValueObjectOptions.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/DumpValueObjectOptions.h?rev=267372&r1=267371&r2=267372&view=diff == --- lldb/trunk/include/lldb/DataFormatters/DumpValueObjectOptions.h (original) +++ lldb/trunk/include/lldb/DataFormatters/DumpValueObjectOptions.h Sun Apr 24 19:52:47 2016 @@ -152,6 +152,9 @@ public: DumpValueObjectOptions& SetRevealEmptyAggregates (bool reveal = true); + +DumpValueObjectOptions& +SetElementCount (uint32_t element_count = 0); public: uint32_t m_max_depth = UINT32_MAX; @@ -163,6 +166,7 @@ public: lldb::LanguageType m_varformat_language = lldb::eLanguageTypeUnknown; PointerDepth m_max_ptr_depth; DeclPrintingHelper m_decl_printing_helper; +uint32_t m_element_count = 0; bool m_use_synthetic : 1; bool m_scope_already_checked : 1; bool m_flat_output : 1; Modified: lldb/trunk/include/lldb/DataFormatters/ValueObjectPrinter.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/DataFormatters/ValueObjectPrinter.h?rev=267372&r1=267371&r2=267372&view=diff == --- lldb/trunk/include/lldb/DataFormatters/ValueObjectPrinter.h (original) +++ lldb/trunk/include/lldb/DataFormatters/ValueObjectPrinter.h Sun Apr 24 19:52:47 2016 @@ -153,6 +153,10 @@ protected: void PrintChildrenPostamble (bool print_dotdotdot); +lldb::ValueObjectSP +GenerateChild (ValueObject* synth_valobj, + size_t idx); + void PrintChild (lldb::ValueObjectSP child_sp, const DumpValueObjectOptions::PointerDepth& curr_ptr_depth); Modified: lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h?rev=267372&r1=267371&r2=267372&view=diff == --- lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h (original) +++ lldb/trunk/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h Sun Apr 24 19:52:47 2016 @@ -77,6 +77,7 @@ public: uint32_t no_summary_depth; uint32_t max_depth; uint32_t ptr_depth; +uint32_t elem_count; lldb::DynamicValueType use_dynamic; }; Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/Makefile?rev=267372&view=auto == --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/Makefile (added) +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/data-formatter/parray/Makefile Sun Apr 24 19:52:47 201