> On Jul 9, 2014, at 11:34 AM, Reid Kleckner <[email protected]> wrote:
> 
> On Wed, Jul 9, 2014 at 9:04 AM, Todd Fiala <[email protected]> wrote:
> Hey all,
> 
> When running lldb tests with clang, on non-Apple platforms, we really need 
> this flag set:
> -fstandalone-debug
> 
> We think this is a bug in LLDB, and would *really* like to see it fixed.  



> gdb works fine without this flag, and it *drastically* reduces the amount of 
> debug info stored in object files.  My understanding is that the debug info 
> that LLDB needs is there, but it's in a different compilation unit.

There are indeed some cases where this is true and LLDB does need to get better 
about being able to find full definitions of classes that aren't fully defined 
in some places, but it can also mean some class definitions might never be 
available. Also, if we get one shared library that has a definition for class A 
which inherits from B and we try to write an expression that uses a version of 
A from another shared library, and one library has a full definition and 
another doesn't, then we run into problems. The main issue is 
> 
> Usually the missing information is type information about a class with a 
> vtable where the first virtual method (aka the key function) is defined in a 
> different TU.  That TU will emit the vtable and all type information for that 
> class.

This isn't always true. We have kernel sources here at Apple where header files 
define base classes, but these base classes are never compiled in their own TU. 
This means we end up with just a forward declaration for this other class and 
we never get it fully defined. I consider this a compiler bug when I must be 
able to find debug info for shared library "B" in order to be able debug shared 
library "A".

> 
> That said, it's fine if LLDB has to add the flag as a short-term way to 
> stabilize the test suite.  I just want to make sure we're on the same page 
> here: this is probably an LLDB bug, not a Clang bug.

I agree there are bugs in LLDB. I also don't like the compiler just assuming 
debug info will be available from somewhere else. It isn't always available, 
and we do have code that proves that here at Apple and this is the reason the 
flag defaults to enable the -fstandalone-debug.

I believe the real solution is to do proper type uniquing in the compiler and 
linker. This is definitely a hard problem to solve correctly without increasing 
.o file size, but it is an effort I do believe is well worth it.

A few possible solutions:
1 - if the compiler uses precompiled headers, emit all types from the 
precompiled headers with their full definitions once into standalone PCH DWARF 
file. Then refer to these full types in this external file with new DWARF tags. 
This keeps the .o files small, and would keep the types properly organized 
inside a DW_TAG_compile_unit for each header file. When the linker links the 
final executable and is going to make the DWARF for the linked executable, it 
will copy the DWARF for the precompiled header over into the final binary, and 
then link each .o file and fix up any external type references to the types in 
the PCH DWARF. Then we get full debug info, no type duplication what so ever. 
The downside is this requires PCH.
2 - emit full types for everything in the .o files and then have a quick way to 
unique them. DWARF has a .debug_types section that does this using special ELF 
sections that the linker knows how to unique, but I don't really like the DWARF 
output for this as it spreads everything into separate sections. This also 
makes the .o files much larger as they all carry full type info.

So we know the current limitations and many of these are driven by how we 
re-create types in Clang ASTs and we run into problems when we have two 
differing definitions for a type. Imagine one share library that has a full 
definition for A which inherits from B and B is just a forward declaration 
because the compiler thought it didn't have to emit it. Now another shared 
library has a full definition of A and B, then we try to mix those types by 
using them in an expression. Clang gets unhappy when two types in the same decl 
context differ.

Also if you only have a forward declaration for B and kind find a full 
definition, you end up not being able to call any functions from B or use any 
instance variables from B. 

After running into these very issues, we decided to always emit full debug info 
for things that are inherited from. It is ok for pointers and reference to have 
forward declarations, but when A inherits from B, we do expect to be able to 
find a full definition in the current binary. If not, we have no idea what 
other binary to load in order to get the debug info for any classes we can't 
find.

Greg

_______________________________________________
lldb-dev mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev

Reply via email to