[lldb-dev] [BUG?] Confusion between translation units?

Greg Clayton via lldb-dev lldb-dev at lists.llvm.org
Mon Oct 26 11:44:11 PDT 2015


After speaking with Adrian Prantl over here we came up with a solution. Currently we do this when uniquing types:

// Only try and unique the type if it has a name.
if (type_name_const_str &&
    dwarf->GetUniqueDWARFASTTypeMap().Find (type_name_const_str,
                                            die,
                                            decl,
                                            byte_size_valid ? byte_size : -1,
                                            *unique_ast_entry_ap))
{
    // We have already parsed this type or from another
    // compile unit. GCC loves to use the "one definition
    // rule" which can result in multiple definitions
    // of the same class over and over in each compile
    // unit.
    type_sp = unique_ast_entry_ap->m_type_sp;
    if (type_sp)
    {
        dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
        return type_sp;
    }
}

We try to find a type by name and Declaration. We need to do this for all language except for C++ because C++ has the one definition rule where a type must be unique in a decl context (all types llvm::foo::bar must be the same). Since this only applies to C++ we could do something like:

if (type_name_const_str)
{
  LanguageType die_language = die.GetLanguage();
  bool handled = false;
  if (Language::LanguageIsCPlusPlus(die_language))
  {
    std::string qualified_name;
    if (die.GetQualifiedName (qualified_name))
    {
      handled = true;
      ConstString const_qualified_name(qualified_name);
      if (dwarf->GetUniqueDWARFASTTypeMap().Find (const_qualified_name,
                                                  die,
                                                  Declaration(),
                                                  byte_size_valid ? byte_size : -1,
                                                  *unique_ast_entry_ap))
      {
        type_sp = unique_ast_entry_ap->m_type_sp;
        if (type_sp)
        {
          dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
          return type_sp;
        }
      }
    }
  }
  
  if (!handled)
  {
    if (dwarf->GetUniqueDWARFASTTypeMap().Find (type_name_const_str,
                                                die,
                                                decl,
                                                byte_size_valid ? byte_size : -1,
                                                *unique_ast_entry_ap))
    {  
      type_sp = unique_ast_entry_ap->m_type_sp;
      if (type_sp)
      {
        dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
        return type_sp;
      }
    }
  }
}

Note that for C++ we get the fully qualified name and we pass in an empty Declaration() so they all will compare to the same thing. This would solve our current issue. We would also need to add the items to this map in the same way: for C++ get the fully qualified name and add the entry to the map with the fully qualified name and an empty Declaration...

Can you try this solution out and see if it fixes our issues?

Greg



> On Oct 26, 2015, at 11:13 AM, Greg Clayton via lldb-dev <lldb-dev at lists.llvm.org> wrote:
> 
> So when LLDB parses the DW_AT_decl_file attributes, it uses the files from the line table for the current compile unit. Each of those files is passed through the module source remapping function:
> 
> bool
> Module::RemapSourceFile (const char *path, std::string &new_path) const
> {
>    Mutex::Locker locker (m_mutex);
>    return m_source_mappings.RemapPath(path, new_path);
> }
> 
> So if you have a plist, it should be being added to this m_source_mappings list. You might want to debug what is happening by stepping through:
> 
> SymbolVendorMacOSX::CreateInstance()
> 
> for the dSYM file that is being used by your build. Inside the "if (XMLDocument::XMLEnabled())" statement is where we get the path remappings.
> 
> A quick note on the plist files in the dSYM: you must create one for each UUID plist for each architecture slice inside the dSYM bundle:
> 
> /tmp/foo.dSYM/Contents/Resources/9FE9CADA-7460-3F80-B881-42443C5FA2E1.plist
> /tmp/foo.dSYM/Contents/Resources/DF977301-4A63-32ED-9939-1EE3122D18D4.plist
> 
> And an example plist for you would need to look like:
> 
> % cat /tmp/foo.dSYM/Contents/Resources/9FE9CADA-7460-3F80-B881-42443C5FA2E1.plist
> <?xml version="1.0" encoding="UTF-8"?>
> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
> <plist version="1.0">
> <dict>
> 	<key>DBGBuildSourcePath</key>
> 	<string>~/src/llvm/include/llvm</string>
> 	<key>DBGSourcePath</key>
> 	<string>/usr/local/include/llvm</string>
> </dict>
> </plist>
> 
> 
>> On Oct 26, 2015, at 11:00 AM, Ramkumar Ramachandra <artagnon at gmail.com> wrote:
>> 
>> Okay, I'm stuck again. Let's back up and see what's happening:
>> 
>> ~/src$ git clone llvm/
>> ~/src$ mkdir llvm-build/
>> ~/src/llvm-build$ cmake -GNinja -DCMAKE_BUILD_TYPE=Debug ../llvm
>> ~/src/llvm-build$ ninja
>> 
>> Now, ~/src/llvm-build/lib/libLLVMCore.a contains DWARF information
>> that points to files ~/src/llvm/include/llvm/ADT/ilist.h,
>> ~/src/llvm/lib/IR/Core.cpp etc.
>> 
>> ~/src/llvm-build$ ninja install
>> 
>> The *.a files are copied to /usr/local/lib, but the *.h files are also
>> copied to /usr/local/include/llvm. The DWARF information is not
>> rewritten as part of the "install".
>> 
>> ~/src/fooapp$ clang++ -g -I/usr/local/include -L/usr/local/lib ...
>> 
>> The fooapp binary is going to contain DWARF information pointing to
>> /usr/local/include/llvm/ADT/ilist.h (because I did -I) _and_
>> ~/src/llvm/include/llvm/ADT/ilist.h (because of libLLVMCore.a).
>> 
>> lldb crashes. gdb hums along just fine in the face of this conflict
>> (the codebase is enormous; sorry, I couldn't find out how exactly).
>> 
>> Now, I cannot "fix" my build by -I'ing ~/src/llvm/include because some
>> essential headers are build artifacts. The only thing I can do is to
>> try and put a plist into the dSYM (which doesn't seem to work either,
>> or I'm doing something wrong). In the general case, there's nothing
>> special about my build: this problem needs to be solved in lldb for
>> the general audience.
>> 
>> Please advise.
>> 
>> Thanks.
>> 
>> Ram
>> 
>> On Fri, Oct 23, 2015 at 1:00 PM, Greg Clayton <gclayton at apple.com> wrote:
>>> I guess LLDB was just helping your resolve build issues and make your product better... :-)
>>> 
>>> Let us know how things go once you get your build fixed.
>>> 
>>> Greg
>>> 
>>>> On Oct 23, 2015, at 9:45 AM, Ramkumar Ramachandra <artagnon at gmail.com> wrote:
>>>> 
>>>> Hi,
>>>> 
>>>> On Wed, Oct 21, 2015 at 2:27 PM, Greg Clayton <gclayton at apple.com> wrote:
>>>>> ....
>>>> 
>>>> Atleast, can we have lldb report a nicer error?
>>>> 
>>>> There is conflicting DWARF information for type ilist...:
>>>> /sandbox/rramacha/3p/derived/List.h
>>>> /sandbox/rramacha/3p/install/List.h
>>>> 
>>>> /sandbox/rramacha/idivide/bin/libmwcgir_vm.so is to blame.
>>>> 
>>>> This is likely a problem with your build scripts. In any case, the
>>>> compiler is responsible for this mess.
>>>> 
>>>>> It sounds like you fixed your symlink issue. So a few questions:
>>>>> 1 - do you have just one type now in your libmwcgir_vm_rt.dylib.dSYM when you type:
>>>>> 
>>>>> (lldb) image lookup -t "iplist<llvm::Function, llvm::ilist_traits<llvm::Function> >"
>>>>> 
>>>>> If so, then you will need to find other competing definitions in other shared libraries and see if any of them differ by comparing the full "clang_type" value.
>>>> 
>>>> Yeah, after resolving the symlink, I realized that there are two
>>>> different paths. I'm attempting to fix my build system.
>>> 
> 
> _______________________________________________
> 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