[Quoting entire email for the benefit of everyone else]

On Tue, Oct 20, 2015 at 7:39 PM, Greg Clayton <gclay...@apple.com> wrote:
> Ok, so try this on all of your dSYM files:
>
> 1 - load the dsym file into lldb:
>
> % xcrun lldb 
> libmwcgir_vm_rt.dylib.dSYM/Contents/Resources/DWARF/libmwcgir_vm_rt.dylib
> (lldb) image lookup -t "iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> >"
> 2 matches found in 
> /Volumes/work/gclayton/Downloads/libmwcgir_vm_rt.dylib.dSYM/Contents/Resources/DWARF/libmwcgir_vm_rt.dylib:
> id = {0x000211dc}, name = "iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> >", qualified = 
> "llvm::iplist<llvm::Function, llvm::ilist_traits<llvm::Function> >", 
> byte-size = 24, decl = ilist.h:313, clang_type = "class iplist : public 
> llvm::ilist_traits<llvm::Function> {
>     llvm::Function *Head;
>     llvm::Function *getTail();
>     const llvm::Function *getTail() const;
>     void setTail(llvm::Function *) const;
>     void CreateLazySentinel() const;
>     static bool op_less(llvm::Function &, llvm::Function &);
>     static bool op_equal(llvm::Function &, llvm::Function &);
>     iplist(const llvm::iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> > &);
>     void operator=(const llvm::iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> > &);
>     iplist();
>     ~iplist();
>     iterator begin();
>     const_iterator begin() const;
>     iterator end();
>     const_iterator end() const;
>     reverse_iterator rbegin();
>     const_reverse_iterator rbegin() const;
>     reverse_iterator rend();
>     const_reverse_iterator rend() const;
>     size_type max_size() const;
>     bool empty() const;
>     reference front();
>     const_reference front() const;
>     reference back();
>     const_reference back() const;
>     void swap(llvm::iplist<llvm::Function, llvm::ilist_traits<llvm::Function> 
> > &);
>     iterator insert(iterator, llvm::Function *);
>     iterator insertAfter(iterator, llvm::Function *);
>     llvm::Function *remove(iterator &);
>     llvm::Function *remove(const iterator &);
>     iterator erase(iterator);
>     void clearAndLeakNodesUnsafely();
>     void transfer(iterator, llvm::iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> > &, iterator, iterator);
>     size_type size() const;
>     iterator erase(iterator, iterator);
>     void clear();
>     void push_front(llvm::Function *);
>     void push_back(llvm::Function *);
>     void pop_front();
>     void pop_back();
>     void splice(iterator, llvm::iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> > &);
>     void splice(iterator, llvm::iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> > &, iterator);
>     void splice(iterator, llvm::iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> > &, iterator, iterator);
>     void erase(const llvm::Function &);
>     void unique();
>     void merge(llvm::iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> > &);
>     void sort();
> }
> "
> id = {0x001a658a}, name = "iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> >", qualified = 
> "llvm::iplist<llvm::Function, llvm::ilist_traits<llvm::Function> >", 
> byte-size = 24, decl = ilist.h:313, clang_type = "class iplist : public 
> llvm::ilist_traits<llvm::Function> {
>     llvm::Function *Head;
>     llvm::Function *getTail();
>     const llvm::Function *getTail() const;
>     void setTail(llvm::Function *) const;
>     void CreateLazySentinel() const;
>     static bool op_less(llvm::Function &, llvm::Function &);
>     static bool op_equal(llvm::Function &, llvm::Function &);
>     iplist(const llvm::iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> > &);
>     void operator=(const llvm::iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> > &);
>     iplist();
>     ~iplist();
>     iterator begin();
>     const_iterator begin() const;
>     iterator end();
>     const_iterator end() const;
>     reverse_iterator rbegin();
>     const_reverse_iterator rbegin() const;
>     reverse_iterator rend();
>     const_reverse_iterator rend() const;
>     size_type max_size() const;
>     bool empty() const;
>     reference front();
>     const_reference front() const;
>     reference back();
>     const_reference back() const;
>     void swap(llvm::iplist<llvm::Function, llvm::ilist_traits<llvm::Function> 
> > &);
>     iterator insert(iterator, llvm::Function *);
>     iterator insertAfter(iterator, llvm::Function *);
>     llvm::Function *remove(iterator &);
>     llvm::Function *remove(const iterator &);
>     iterator erase(iterator);
>     void clearAndLeakNodesUnsafely();
>     void transfer(iterator, llvm::iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> > &, iterator, iterator);
>     size_type size() const;
>     iterator erase(iterator, iterator);
>     void clear();
>     void push_front(llvm::Function *);
>     void push_back(llvm::Function *);
>     void pop_front();
>     void pop_back();
>     void splice(iterator, llvm::iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> > &);
>     void splice(iterator, llvm::iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> > &, iterator);
>     void splice(iterator, llvm::iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> > &, iterator, iterator);
>     void erase(const llvm::Function &);
>     void unique();
>     void merge(llvm::iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> > &);
>     void sort();
> }
> "
>
>
> Do the same thing for any other shared libraries that you have and compare 
> the data in quotes of the 'clang_type = "<copy>"' and save the <copy> to a 
> file. See if any of them differ from each other.
>
>
> What is interesting here is that we have two of the same copies of this type 
> in the same file, this shouldn't happen. I looked into why this is happening 
> and found the reason:
>
> Looking at the two types that were found above we see two types:
>
> id = {0x000211dc}, name = "iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> >", ...
> id = {0x001a658a}, name = "iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> >", ...
>
> The "id" in this case is actually the DWARF offset: 0x000211dc and 0x001a658a 
> which we can use to dump the DWARF in the dSYM file:
>
> % dwarfdump --show-parents --debug-info=0x000211dc libmwcgir_vm_rt.dylib.dSYM/
> ----------------------------------------------------------------------
>  File: 
> libmwcgir_vm_rt.dylib.dSYM/Contents/Resources/DWARF/libmwcgir_vm_rt.dylib 
> (x86_64)
> ----------------------------------------------------------------------
> .debug_info[0x000211dc]:
>
> 0x00017fa3: TAG_compile_unit [1] *
>              AT_producer( "Apple LLVM version 6.0 (clang-600.0.57) (based on 
> LLVM 3.5svn)" )
>              AT_language( DW_LANG_C_plus_plus )
>              AT_name( "vm/CgInstDbgPrint.cpp" )
>              AT_stmt_list( 0x000012a1 )
>              AT_comp_dir( 
> "/mathworks/devel/sbs/34/rramacha.idivide-final-lap/matlab/src/cgir_vm_rt" )
>              AT_low_pc( 0x0000000000002ef0 )
>
> 0x00017fbe:     TAG_namespace [2] *
>                  AT_name( "llvm" )
>                  AT_decl_file( 
> "../../../3p_mirror/maci64/LLVM/include/llvm/ADT/iterator_range.h" )
>                  AT_decl_line( 24 )
>
> 0x000211dc:         TAG_class_type [3] *
>                      AT_name( "iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> >" )
>                      AT_byte_size( 0x18 )
>                      AT_decl_file( 
> "../../../3p_mirror/maci64/LLVM/include/llvm/ADT/ilist.h" )
>                      AT_decl_line( 313 )
>
>
> % dwarfdump --show-parents --debug-info=0x001a658a libmwcgir_vm_rt.dylib.dSYM/
> ----------------------------------------------------------------------
>  File: 
> libmwcgir_vm_rt.dylib.dSYM/Contents/Resources/DWARF/libmwcgir_vm_rt.dylib 
> (x86_64)
> ----------------------------------------------------------------------
> .debug_info[0x001a658a]:
>
> 0x00172c2a: TAG_compile_unit [185] *
>              AT_producer( "Apple LLVM version 5.0 (clang-500.2.79) (based on 
> LLVM 3.3svn)" )
>              AT_language( DW_LANG_C_plus_plus )
>              AT_name( 
> "/mathworks/devel/sandbox/rramacha/3p-tmw-osx/3p/derived/maci64/LLVM/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp"
>  )
>              AT_low_pc( 0x0000000000027460 )
>              AT_stmt_list( 0x00013f74 )
>              AT_comp_dir( 
> "/mathworks/devel/sandbox/rramacha/3p-tmw-osx/3p/derived/maci64/LLVM/build/lib/Transforms/ObjCARC"
>  )
>
> 0x001a601c:     TAG_namespace [2] *
>                  AT_name( "llvm" )
>                  AT_decl_file( 
> "/mathworks/devel/sandbox/rramacha/3p-tmw-osx/3p/derived/maci64/LLVM/llvm/include/llvm/IR/SymbolTableListTraits.h"
>  )
>                  AT_decl_line( 30 )
>
> 0x001a658a:         TAG_class_type [3] *
>                      AT_name( "iplist<llvm::Function, 
> llvm::ilist_traits<llvm::Function> >" )
>                      AT_byte_size( 0x18 )
>                      AT_decl_file( 
> "/mathworks/devel/sandbox/rramacha/3p-tmw-osx/3p/derived/maci64/LLVM/llvm/include/llvm/ADT/ilist.h"
>  )
>
>
> LLDB uniques types based off of decl file + decl line + full qualified named 
> + byte size. Note that the decl file is 
> "../../../3p_mirror/maci64/LLVM/include/llvm/ADT/ilist.h" and 
> "/mathworks/devel/sandbox/rramacha/3p-tmw-osx/3p/derived/maci64/LLVM/llvm/include/llvm/ADT/ilist.h"
>  for the other... This is why we incorrectly create two types, because the 
> keys (decl file) we are using to unique the types are not the same.
>
> So the easy way to fix your problem is fix your build system so that it 
> doesn't do this. It seems that your build is using a relative path for one 
> file "vm/CgInstDbgPrint.cpp" and a full path for another: 
> "/mathworks/devel/sandbox/rramacha/3p-tmw-osx/3p/derived/maci64/LLVM/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp".
>  If you can fix your build system to always use full paths for source files 
> this problem might go away (if no other competing versions of 
> "iplist<llvm::Function, llvm::ilist_traits<llvm::Function> >" exist anywhere).
>
> The other bad thing is even after you normalize the paths you are comparing:
>
> /mathworks/devel/sbs/34/rramacha.idivide-final-lap/3p_mirror/maci64/LLVM/include/llvm/ADT/ilist.h
> /mathworks/devel/sandbox/rramacha/3p-tmw-osx/3p/derived/maci64/LLVM/llvm/include/llvm/ADT/ilist.h
>
> Are you pulling in data from two different copies of LLVM in your project? Or 
> is something in here symlink to the other somewhere?

Excellent find. Yes, 3p_mirror is a symlink to the 3p-tmw-osx location.

> So to sum up: LLDB uniques types by decl file + decl line + byte size + fully 
> qualified typename and that is failing because the decl files are different 
> for these two types from the debug infos point of view. And these types could 
> actually differ since they come from different files and we need to allow 
> this so that we can display these types.

I'm slightly confused: can't we ask Clang to tell us if the two types
are structurally equivalent? Is this some short-cut? We need to
account for symlinks then, it seems.

Thanks!

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

Reply via email to