lmi
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [lmi] Build fails with 'build_type=safestdlib'


From: Evgeniy Tarassov
Subject: Re: [lmi] Build fails with 'build_type=safestdlib'
Date: Thu, 19 Apr 2007 14:24:50 +0200

On 3/29/07, Greg Chicares <address@hidden> wrote:
It's really important to fix this. The libstdc++ flags
[...]
  C:/lmi/src/lmi[0]$make check_physical_closure install build_type=safestdlib >../log 
2>&1
[...]
undefined reference to `non-virtual thunk to wxChoice::GetCount() const'

Let me do an upside-down analysis of the root cause down to the observed error:

1) The flags (added when building with safestdlib) (_GLIBCXX_DEBUG,
..., _GLIBXX_DEBUG_PEDANTIC) change the size of STL containers (such
as std::list).
Probably some additional information is stored inside to allow
additional chechks during such a build.
As a consequence std::list<wxWindow> has different size (+16 bytes).

2) If WX is compiled with --enable-stl (wxUSE_STL), then wxList
implementation inherits from std::list.
In particular wxWindowList inherits from std::list<wxWindow> and as a
consequence has slightly increased size when safestdlib-ing.

3) wxWindow class has private data-member 'wxWindowList m_children'.
Therefore wxWindow size changes.

4) When compiling every virtual method gets a helper
implementation-function (called thunk), which is used to adjust this
pointer to match the right base (this is especially important for
multiple-inheritance, and gets really complicated for virtual
inheritance).
The 'mangled name' for the thunk is formed using the following rule(s):

http://www.codesourcery.com/cxx-abi/abi.html#mangling-special
| Virtual function override thunks come in two forms. Those overriding
| from a non-virtual base, with fixed this adjustments, use a "Th"
| prefix and encode the required adjustment offset, probably negative,
| indicated by a 'n' prefix, and the encoding of the target function

The most important thing is that the thunk function name includes the
adjustment offset in it.
For example wxChoice::GetCount method gets a helper thunk function:
_ZThn568_NK8wxChoice8GetCountEv (note the 568 number - the negative
offset to wxItemContainer (one of two base classes of wxChoice), that
originally defines (pure virtual) GetCount method).

5) wxChoice class has multiple base classes (via wxChoiceBase) --
wxControl and wxItemContainer. wxControl derives from wxWindow.
Therefore the offset changes when building with safestdlib and without.
As a consequnce the mangled name for the thunk-helper changes too -- in wx it is
_ZThn552_NK8wxChoice8GetCountEv
but lmi expects it to be
_ZThn568_NK8wxChoice8GetCountEv
(note the difference: 552 and 568)

As a workaround we could try to avoid using STL containers as
class-base and as data-members, to ensure that a class size does not
change. For example the m_children data member (mentioned above) could
be declared as a pointer to wxWindowList. But the problem will persist
because even if we manage to link (I have tested it -- lmi-safestdlib
links with wx if m_children is held as a pointer), lmi will still be
calculating wx classes size incorrectly -- for example for
wxWindowList, which could lead to a crash or an undefined behavior in
runtime).

The correct solution would be to compile both wx and lmi with the same
set of flags (to make a safestdlib build for wx too and to link to
it).

I wonder what if in some other library used by lmi (libxml2 or
libxslt) there is a multiple-inheritance class that uses STL
containers -- will the build fail with errors, or will it fail instead
during the runtime?

--
Best wishes,
Evgeniy Tarassov




reply via email to

[Prev in Thread] Current Thread [Next in Thread]