__cxa_atexit and __cxa_finalize implementation
Peter S. Mazinger
ps.m at gmx.net
Fri Sep 16 13:17:10 UTC 2005
On Fri, 16 Sep 2005, Stephen Warren wrote:
> Peter S. Mazinger wrote:
> > On Sun, 11 Sep 2005, Stephen Warren wrote:
> >>Stephen Warren wrote:
> >>>Here's a fixed version of my patch to implement these functions.
> >>
> >>Did anyone have any feedback on this? Is it likely to get merged, or are
> >>there problems with it?
> >
> > I have rebuilt a gentoo base development system applying this cxa_atexit
> > patch to uclibc and using --enable-cxa_atexit to build gcc. I can't see
> > until now any problems, but it would be good to have some test scenario
> > or app that is known to fail.
>
> Here's part 1 of a couple tests that demonstrate the problems.
>
> It's a little involved, but hopefully not too hard to follow, since not
> all the details are relevant.
>
> Basically, there's a global "CNvMutex g_mutex". The constructor for this
> global will run before main, and the destructor after main.
>
> The constructor calls function INvThreading::GetImp, which contains a
> static data member g_nvt, which gets constructed when
> INvThreading::GetImp is called.
>
> Now, the CNvMutex constructor logically depends upon the g_nvt
> constructor, because it essentially calls it. The compiler/code "knows"
> (or should know) this because at run-time, the g_nvt constructor
> completes before the g_mutex constructor.
>
> What is supposed to happen (by "spec" - although not sure what spec!) is
> that because of this dependency, the g_nvt destructor is deferred until
> after the g_mutex destructor is run, at app exit time.
>
> However, with -fno-use-cxa-atexit compile flag (or the equivalent gcc
> build flag that sets this as a default), the gcc-generated code for the
> global constructors does not implement this ordering, and hence g_nvt is
> destructed first, then the g_mutex destructor calls a method on g_nvt,
> and the app crashes with a pure virtual method call.
>
> Building with -fuse-cxa-atexit (or gcc build-time equivalent) will fix
> this, since the generated global ctor/dtor management code is very
> different. However, this requires that the C lib implement __cxa_atexit,
> hence my original patch.
>
> To demonstrate the problem, one should run these commands (note, I did
> this with the regular Fedora Core 3 glibc toolchain, since that's what I
> have at hand and in a known state right now, but the errors were the
> same with a non __cxa_atexit uClibc toolchain)
>
> BAD:
> g++ -fno-use-cxa-atexit -o invt invt.cpp && ./invt
> CNvMutex::CNvMutex init list pre m_pThreading
> INvThreading::GetImp pre
> CNvThreadingImp::CNvThreadingImp
> INvThreading::GetImp post
> CNvMutex::CNvMutex init list post m_pThreading
> CNvMutex::CNvMutex
> CNvThreadingImp::Create->10
> CNvMutex::CNvMutex -> m_h=10
> CNvMutex::Func()
> CNvThreadingImp::~CNvThreadingImp
> CNvMutex::~CNvMutex (m_h=10) start
building against uClibc++ produces the same without the next to lines
these seem to be comments from libstdc++ (Aborted is there)
> pure virtual method called
> terminate called without an active exception
> Aborted
>
libstdc++ is exactly as you wrote
> GOOD:
> g++ -fuse-cxa-atexit -o invt invt.cpp && ./invt
> CNvMutex::CNvMutex init list pre m_pThreading
> INvThreading::GetImp pre
> CNvThreadingImp::CNvThreadingImp
> INvThreading::GetImp post
> CNvMutex::CNvMutex init list post m_pThreading
> CNvMutex::CNvMutex
> CNvThreadingImp::Create->10
> CNvMutex::CNvMutex -> m_h=10
> CNvMutex::Func()
> CNvMutex::~CNvMutex (m_h=10) start
> CNvThreadingImp::Destroy(10)
> CNvMutex::~CNvMutex (m_h=10) done
> CNvThreadingImp::~CNvThreadingImp
both uClibc++ and libstdc++ perform like this
tested natively on uClibc-svn-20050908 w/ your cxa patch (and my addons
for nonshared) gcc-3.4.4/binutils-2.16.91.0.3
apropos: typo: s/old_atexit.c/old_atexit.o/ needed in my last patch
(old_atexit compatibility)
Peter
>
> Hope this helps!
>
> Test part 2 (to come later) demonstrates issues with DSOs being
> unloaded; dtors for objects in the DSO must run at DSO unload time
> rather than app exit time. This is why the __cxa_atexit implementation
> must play with __dso_handle, rather than just calling atexit() - which
> would fix the above problem.
>
>
--
Peter S. Mazinger <ps dot m at gmx dot net> ID: 0xA5F059F2
Key fingerprint = 92A4 31E1 56BC 3D5A 2D08 BB6E C389 975E A5F0 59F2
More information about the uClibc
mailing list