> On Feb 27, 2015, at 9:40 AM, David Blaikie <[email protected]> wrote:
>
>
>
> On Fri, Feb 27, 2015 at 9:31 AM, Greg Clayton <[email protected]> wrote:
> I recommend telling the compiler to not do this using (set
> -no-fstandalone-debug in OTHER_CFLAGS) if you want to debug with LLDB. If you
> don't you can DWARF for the following code:
>
>
> class A : public B
> {
> };
>
> Where the compiler says "no one used 'B' so I am going to emit a forward
> declaration for 'B'.
>
> That's not quite the logic used here. Certainly if you use A then you've used
> B. B may be emitted as a declaration if we know that some other CU will
> contain the definition (eg: using the vtable optimization - if B has virtual
> functions, we'll only emit the definition of B where the vtable goes (if B
> has a key function, this means the debug info definition of B goes in exactly
> one place: where the definition of the key function appears))
Sure, then only if B has a vtable this will happen.
>
> Then LLDB tries to make class 'A' in a clang AST context and then we try to
> parse 'B' so we can have 'A' inherit from it and clang of course would assert
> and kill LLDB (if we actually try to give clang a class 'B' that is a forward
> declaration as a base class) so LLDB has to lie to keep clang from asserting
> and just say that 'B' class that contains nothing.
>
> Shouldn't it go & find B in another file? The same way you would find the
> definition of foo if one file contained "struct foo; foo *f;" and the user
> executed the command "p f->bar"?
LLDB is designed to parse each shared library individually so that we can
re-use shared libraries from between multiple runs. If liba.so doesn't changed,
we don't need to re-parse anything in liba.so or its debug info file. If you
recompile libb.so, we don't have any dependencies in liba.so on types like 'B'
from elsewhere otherwise the types passed out by each shared library have
dependencies and have to throw everything away when any dependent shared
library is loaded.
But in LLDB, when we have a process, _will_ find the real definition elsewhere
when displaying things to you for things that can legally be forward
declarations in sources (pointers and references). So we will have a variable
of type "A" from liba.so and we will be displaying it and if it has an instance
variable, whose type is "C *" and that 'C' is a forward declaration, we will
search and find "C" elsewhere (in libb.so) for display purposed by switching
over to using the type from 'libb.so'. But we can't do this for things that
can't be forward declarations in sources, like base classes.
>
> The idea was that someone will certainly declare 'B' somewhere in your
> current source base.
>
> It's more robust than that - the vtable optimization, assuming you compile
> your whole program with debug info, is guaranteed by the C++ standard (odr
> use of the class means you have a definition of all the virtual members
> /somewhere/ in your program).
Yes, but this doesn't guarantee that this debug info is in the current shared
library or executable. So if the other shared library doesn't have debug info,
then you end up missing debug info. LLDB parses shared libraries individually
because it can have multiple debug sessions running simultaneously, each using
different combinations of shared libraries at the same time. So we can't take
type 'B' from libb.so and copy it into type 'A' from liba.so because if libb.so
changes and we restart a debug session, we would have to throw away all type
info (or maintain dependency lists). Further we can't do it because process 123
might be still be using the old version of libb.so while process 124 restarted
and is using the new version.
> GCC has been doing this optimization for a while now, Clang was doing similar
> optimizations ("struct foo { }; foo *f;" - we'd only emit the declaration of
> 'foo' since it was never dereferenced) for a while too - I believe Eric
> implemented the first versions of that on a suggestion from Chris Lattner,
> FWIW.
Again, for places that can have forward declarations (for pointers and
references), this is quite OK. Our variable display logic will find the right
definition. It is just in the base class case where this falls down for LLDB.
>
> This mostly holds true, but if you have a header file from a shared library
> that has a C++ class that people might inherit from (like we do in Darwin
> Kernel Extensions),
>
> If you don't have debug info for that shared library (hence the suggestion to
> install debug info for the standard library - there are packages for it).
> Granted I imagine it'll take some finagling to change the Darwin Kernel
> Extensions build system to build a partial debug info package (presumably you
> don't want to ship all the debug info for the implementation of that library
> - for size and privacy reasons).
We do have this issue and we won't be changing the default on MacOSX for this
very reason.
The performance and memory benefits we get in LLDB from having each shared
library be independent are huge. Re-starting a debug session in Xcode for the
same program (rerunning) is instant as we have a global cache of shared
libraries that are all stand alone and have no dependencies. When we still used
GDB, every restart was a new delay as it loaded all shared libraries and debug
info for each run. Each debug session was a unique new instance of GDB running
in a separate process so that GDB could hack its shared libraries up any way it
chose to with no worries of dependencies because there was only 1 debug session
going on at a time. If a shared library doesn't change in LLDB, we still have a
live copy all pre-parsed and ready to go in our global cache.
>
> we end up with a class we use for debugging that isn't allowed to see any
> ivars from "B", nor call any functions declared inside 'B' or any of its
> subclasses (because we told clang 'B' has no contents when creating the type
> in the clang AST. So we default to -no-fstandalone-debug for all of Darwin to
> avoid this.
>
> Greg Clayton
>
> > On Feb 26, 2015, at 4:35 PM, Ed Maste <[email protected]> wrote:
> >
> > On 26 February 2015 at 17:28, Adrian Prantl <[email protected]> wrote:
> >>
> >> The -fstandalone-debug option turns off these optimizations.
> >> This is useful when working with 3rd-party libraries that don't come with
> >> debug information. This is the default on Darwin. Note that
> >> Clang will never emit type information for types that are not referenced at
> >> all by the program.
> >
> > Note that this is also the default on FreeBSD. This might be an
> > important point when comparing test results on FreeBSD and Linux since
> > they otherwise share a lot of attributes.
> >
> > -Ed
>
>
_______________________________________________
lldb-dev mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev