[lldb-dev] DW_TAG_member extends beyond the bounds error on Linux

Greg Clayton via lldb-dev lldb-dev at lists.llvm.org
Mon Mar 28 09:31:04 PDT 2016


Is it possible for me to see the "biggrep_master_server_async" binary? I would like to look at the DWARF and try to figure out what is wrong. It seems that this code is what is causing the problem:


CompilerType member_clang_type = member_type->GetLayoutCompilerType ();
if (!member_clang_type.IsCompleteType())
    member_clang_type.GetCompleteType();

{
    // Older versions of clang emit array[0] and array[1] in the same way (<rdar://problem/12566646>).
    // If the current field is at the end of the structure, then there is definitely no room for extra
    // elements and we override the type to array[0].

    CompilerType member_array_element_type;
    uint64_t member_array_size;
    bool member_array_is_incomplete;

    if (member_clang_type.IsArrayType(&member_array_element_type,
                                      &member_array_size,
                                      &member_array_is_incomplete) &&
        !member_array_is_incomplete)
    {
        uint64_t parent_byte_size = parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX);

        if (member_byte_offset >= parent_byte_size)
        {
            if (member_array_size != 1 && (member_array_size != 0 || member_byte_offset > parent_byte_size))
            {
                module_sp->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 " which extends beyond the bounds of 0x%8.8" PRIx64,
                                        die.GetID(),
                                        name,
                                        encoding_form.Reference(),
                                        parent_die.GetID());
            }

            member_clang_type = m_ast.CreateArrayType(member_array_element_type, 0, false);
        }
    }
}


So we are parsing a member variable, and the member variable's type is an array type, and the offset of the member is beyond the parent's type's size and yet the array claims to have a valid size. 

This code is trying to correctly create an CompilerType for a struct such as this:

struct MyStruct
{
    size_t num_entries;
    Entry entries[0];
};

Older versions of clang would emit the same DWARF for:

struct MyStruct
{
    size_t num_entries;
    Entry entries[0];
};

or

struct MyStruct
{
    size_t num_entries;
    Entry entries[1];
};

This is bad because in the DWARFASTParserClang we are trying to faithfully re-create the type as the user initially created it.

This error is trying to say that you have a structure where the byte size of "MyStruct" is something like 8 bytes, but "entries" is an array that has a valid size (not zero or one) and that the offset of "entries" is greater than or equal to 8. If "entries" has a size like:

struct MyStruct
{
    size_t num_entries;
    Entry entries[1];
};

You would expect the member offset for "entries" to be less than or equal to the sizeof(MyStruct). If "Entry" is 8 bytes in size, you might expect the byte size of "MyStruct" to be 16, and the offset of "num_entries" to be 0 and "entries" to be 8. Both offsets are less than or equal to the byte size of 16.

If I can see the DWARF file I can tell you more. If I can't, you will need to step through this code and see why this is triggering. The error message is telling you all you need to know to dump the problem. So for this error message:

error: biggrep_master_server_async 0x10b9a91a: DW_TAG_member '_M_pod_data' refers to type 0x10bb1e99 which extends beyond the bounds of 0x10b9a901

So if you dump the DWARF and look for the DIE at 0x10b9a91a, you will be able to see the DWARF that is causing the problem. On MacOSX, I would do this:

% dwarfdump --debug-info=0x10b9a91a --show-children --show-parents biggrep_master_server_async

llvm-dwarfdump will dump your entire file and you will need to look through a ton of DWARF in the output. You will need to search for "0x10b9a91a:" (the offset followed by a colon).

So LLDB believes it is pointing out an error in the DWARF that needs to be fixed in the compiler. It could be an incorrect error, but I would need to see the DWARF in question to know more. Debugging can happen just fine if you ignore this error, it is actually more of a warning, but we emit an error so users know to file a bug and hopefully get the compiler fixed.

Greg

> On Mar 26, 2016, at 5:10 PM, Jeffrey Tan via lldb-dev <lldb-dev at lists.llvm.org> wrote:
> 
> Sorry, sent to the wrong alias.
> 
> ---------- Forwarded message ----------
> From: Jeffrey Tan <jeffrey.fudan at gmail.com>
> Date: Sat, Mar 26, 2016 at 3:19 PM
> Subject: DW_TAG_member extends beyond the bounds error on Linux
> To: llvm-dev at lists.llvm.org
> 
> 
> Hi,
> 
> While dogfooding our lldb based IDE on Linux, I am seeing a lot of variable evaluation errors related to DW_TAG_member which prevents us from release the IDE. Can anyone help to confirm if they are known issues? If not, any information you need to troubleshoot this issue?
> 
> Here is one example:
> 
> (lldb) fr v
> error: biggrep_master_server_async 0x10b9a91a: DW_TAG_member '_M_pod_data' refers to type 0x10bb1e99 which extends beyond the bounds of 0x10b9a901
> error: biggrep_master_server_async 0x10b98edc: DW_TAG_member 'small_' refers to type 0x10bb1d9f which extends beyond the bounds of 0x10b98ed3
> error: biggrep_master_server_async 0x10baf034: DW_TAG_member '__size' refers to type 0x10baf04d which extends beyond the bounds of 0x10baefae
> (facebook::biggrep::BigGrepMasterAsync *) this = 0x00007fd14d374fd0
> (const string &const) corpus = error: summary string parsing error: {
>   store_ = {
>      = {
>       small_ = {}
>       ml_ = (data_ = "��UH\x89�H�}�H\x8bE�]ÐUH\x89�H��H\x89}�H\x8bE�H\x89��~\xb4��\x90��UH\x89�SH\x83�H\x89}�H�u�H�E�H���\x9e���H\x8b\x18H\x8bE�H���O\xb4��H\x89ƿ\b", size_ = 0, capacity_ = 1441151880758558720)
>     }
>   }
> }
> (const string &const) needle = error: summary string parsing error: {
>   store_ = {
>      = {
>       small_ = {}
>       ml_ = (data_ = "", size_ = 0, capacity_ = 1080863910568919040)
>     }
>   }
> }
> (facebook::biggrep::Options &) options = 0x00007fd133cfb7b0: {
>   engine = error: summary string parsing error
>   full_lines = true
>   user = error: summary string parsing error
>   max_bytes = 5000000
>   leading_context = 0
>   trailing_context = 0
>   case_sensitive = true
>   client_hostname = error: summary string parsing error
>   client_ip = error: summary string parsing error
>   skip_logging = false
>   client_port = 0
>   shards_override = 0
>   sample = false
>   count = false
>   filename_pattern = error: summary string parsing error
>   limit = 0
>   __isset = {
>     engine = true
>     full_lines = true
>     user = true
>     max_bytes = true
>     leading_context = true
>     trailing_context = true
>     case_sensitive = true
>     client_hostname = true
>     client_ip = true
>     skip_logging = true
>     client_port = true
>     shards_override = true
>     sample = true
>     count = true
>     filename_pattern = true
>     limit = true
>   }
> }
> (size_t) recv_timeout = 140536468041728
> (std::vector<std::basic_fbstring<char, std::char_traits<char>, std::allocator<char>, std::fbstring_core<char> >, std::allocator<std::basic_fbstring<char, std::char_traits<char>, std::allocator<char>, std::fbstring_core<char> > > >) corpuses = size=0 {}
> (std::vector<facebook::biggrep::BigGrepMasterAsync::Revision, std::allocator<facebook::biggrep::BigGrepMasterAsync::Revision> >) revisions = size=0 {}
> (std::vector<facebook::biggrep::BigGrepMasterAsync::RevisionShard, std::allocator<facebook::biggrep::BigGrepMasterAsync::RevisionShard> >) shards = size=0 {}
> (std::string) returnRev = error: summary string parsing error
> (<lambda(folly::StringPiece)>) quote = {}
> (std::basic_fbstring<char, std::char_traits<char>, std::allocator<char>, std::fbstring_core<char> >) desc = {
>   store_ = {
>      = {
>       small_ = {}
>       ml_ = (data_ = "", size_ = 73415312, capacity_ = 140536494141696)
>     }
>   }
> }
> (folly::EventBase *) eb = 0x00007fd133cfb888
> (apache::thrift::concurrency::ThreadManager *) tm = 0x00007fd133cfb570
> 
> I suspect each one may be different root cause. I was able to capture one callstack of a small repro:
> 
> Breakpoint 1, DWARFASTParserClang::ParseChildMembers (this=0x8c4520, sc=..., parent_die=..., class_clang_type=..., class_language=lldb::eLanguageTypeUnknown,
>     base_classes=..., member_accessibilities=..., member_function_dies=..., delayed_properties=...,
>     default_accessibility=@0x7ffdf3888cac: lldb::eAccessPublic, is_a_class=@0x7ffdf3888cab: false, layout_info=...)
>     at /home/engshare/third-party2/lldb/3.8.0.rc3/src/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp:2937
> 2937	                                                                        parent_die.GetID());
> (gdb) bt
> #0  0x00007f103d02533d in DWARFASTParserClang::ParseChildMembers(lldb_private::SymbolContext const&, DWARFDIE const&, lldb_private::CompilerType&, lldb::LanguageType, std::vector<clang::CXXBaseSpecifier*, std::allocator<clang::CXXBaseSpecifier*> >&, std::vector<int, std::allocator<int> >&, DWARFDIECollection&, std::vector<DWARFASTParserClang::DelayedAddObjCClassProperty, std::allocator<DWARFASTParserClang::DelayedAddObjCClassProperty> >&, lldb::AccessType&, bool&, DWARFASTParserClang::LayoutInfo&) (this=0x8c4520, sc=..., parent_die=..., class_clang_type=..., class_language=lldb::eLanguageTypeUnknown, base_classes=..., member_accessibilities=..., member_function_dies=..., delayed_properties=..., default_accessibility=@0x7ffdf3888cac: lldb::eAccessPublic, is_a_class=@0x7ffdf3888cab: false, layout_info=...) at /home/engshare/third-party2/lldb/3.8.0.rc3/src/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp:2937
> #1  0x00007f103d025b84 in DWARFASTParserClang::CompleteTypeFromDWARF(DWARFDIE const&, lldb_private::Type*, lldb_private::CompilerType&) (this=0x8c4520, die=..., type=0xc40a50, clang_type=...)
>     at /home/engshare/third-party2/lldb/3.8.0.rc3/src/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp:2036
> #2  0x00007f103d04c5e8 in SymbolFileDWARF::CompleteType(lldb_private::CompilerType&) (this=<optimized out>, compiler_type=...)
>     at /home/engshare/third-party2/lldb/3.8.0.rc3/src/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp:1635
> #3  0x00007f103ceff9da in lldb_private::ClangASTContext::CompleteTagDecl(void*, clang::TagDecl*) (baton=<optimized out>, decl=0xc41bc0)
>     at /home/engshare/third-party2/lldb/3.8.0.rc3/src/llvm/tools/lldb/source/Symbol/ClangASTContext.cpp:9619
> #4  0x00007f103cf03400 in GetCompleteQualType(clang::ASTContext*, clang::QualType, bool) (ast=0x7f102c020c30, qual_type=..., allow_completion=allow_completion at entry=true) at /home/engshare/third-party2/lldb/3.8.0.rc3/src/llvm/tools/lldb/source/Symbol/ClangASTContext.cpp:2632
> #5  0x00007f103cf0c99e in lldb_private::ClangASTContext::GetNumChildren(void*, bool) (this=0x8c43c0, type=<optimized out>, omit_empty_base_classes=<optimized out>) at /home/engshare/third-party2/lldb/3.8.0.rc3/src/llvm/tools/lldb/source/Symbol/ClangASTContext.cpp:5067
> #6  0x00007f103ce876ad in lldb_private::ValueObjectVariable::CalculateNumChildren(unsigned int) (this=<optimized out>, max=4294967295)
>     at /home/engshare/third-party2/lldb/3.8.0.rc3/src/llvm/tools/lldb/source/Core/ValueObjectVariable.cpp:102
> #7  0x00007f103ce7759f in lldb_private::ValueObject::GetNumChildren(unsigned int) (this=0xc40600, max=4294967295)
>     at /home/engshare/third-party2/lldb/3.8.0.rc3/src/llvm/tools/lldb/source/Core/ValueObject.cpp:778
> #8  0x00007f103cd999bd in lldb_private::FormatManager::ShouldPrintAsOneLiner(lldb_private::ValueObject&) (this=this at entry=0x7f103fe2f300 <GetFormatManager()::g_format_manager>, valobj=...) at /home/engshare/third-party2/lldb/3.8.0.rc3/src/llvm/tools/lldb/source/DataFormatters/FormatManager.cpp:576
> #9  0x00007f103cd9226a in lldb_private::DataVisualization::ShouldPrintAsOneLiner(lldb_private::ValueObject&) (valobj=...)
>     at /home/engshare/third-party2/lldb/3.8.0.rc3/src/llvm/tools/lldb/source/DataFormatters/DataVisualization.cpp:42
> #10 0x00007f103cdc2167 in lldb_private::ValueObjectPrinter::PrintChildrenIfNeeded(bool, bool) (this=this at entry=0x7ffdf38892a0, value_printed=<optimized out>, summary_printed=<optimized out>) at /home/engshare/third-party2/lldb/3.8.0.rc3/src/llvm/tools/lldb/source/DataFormatters/ValueObjectPrinter.cpp:869
> #11 0x00007f103cdc1572 in lldb_private::ValueObjectPrinter::PrintValueObject() (this=this at entry=0x7ffdf38892a0)
>     at /home/engshare/third-party2/lldb/3.8.0.rc3/src/llvm/tools/lldb/source/DataFormatters/ValueObjectPrinter.cpp:111
> #12 0x00007f103ce7102f in lldb_private::ValueObject::Dump(lldb_private::Stream&, lldb_private::DumpValueObjectOptions const&) (this=this at entry=0xc40600, s=..., options=...) at /home/engshare/third-party2/lldb/3.8.0.rc3/src/llvm/tools/lldb/source/Core/ValueObject.cpp:3585
> #13 0x00007f103d27e5e4 in CommandObjectFrameVariable::DoExecute(lldb_private::Args&, lldb_private::CommandReturnObject&) (this=0x7d0590, command=..., result=...) at /home/engshare/third-party2/lldb/3.8.0.rc3/src/llvm/tools/lldb/source/Commands/CommandObjectFrame.cpp:591
> #14 0x00007f103cece45d in lldb_private::CommandObjectParsed::Execute(char const*, lldb_private::CommandReturnObject&) (this=0x7d0590, args_string=<optimized out>, result=...) at /home/engshare/third-party2/lldb/3.8.0.rc3/src/llvm/tools/lldb/source/Interpreter/CommandObject.cpp:1095
> #15 0x00007f103cec9559 in lldb_private::CommandInterpreter::HandleCommand(char const*, lldb_private::LazyBool, lldb_private::CommandReturnObject&, lldb_private::ExecutionContext*, bool, bool) (this=this at entry=0x7a5210, command_line=<optimized out>, lazy_add_to_history=lazy_add_to_history at entry=lldb_private::eLazyBoolCalculate, result=..., override_context=override_context at entry=0x0, repeat_on_empty_command=repeat_on_empty_command at entry=true, no_context_switching=false)
>     at /home/engshare/third-party2/lldb/3.8.0.rc3/src/llvm/tools/lldb/source/Interpreter/CommandInterpreter.cpp:1820
> #16 0x00007f103ceca50d in lldb_private::CommandInterpreter::IOHandlerInputComplete(lldb_private::IOHandler&, std::string&) (this=0x7a5210, io_handler=..., line=...) at /home/engshare/third-party2/lldb/3.8.0.rc3/src/llvm/tools/lldb/source/Interpreter/CommandInterpreter.cpp:2976
> #17 0x00007f103ce1c733 in lldb_private::IOHandlerEditline::Run() (this=0x87d9b0)
>     at /home/engshare/third-party2/lldb/3.8.0.rc3/src/llvm/tools/lldb/source/Core/IOHandler.cpp:736
> 
> 
> Really appreciate if there is any fix/workaround I can get over this issue and unblock us!
> 
> Jeffrey
> 
> _______________________________________________
> lldb-dev mailing list
> lldb-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-dev



More information about the lldb-dev mailing list