public inbox for ecos-devel@sourceware.org
 help / color / mirror / Atom feed
* Re: Strange __cxa_pure_virtual problem
@ 2009-08-12  9:10 cetoni GmbH - Uwe Kindler
  0 siblings, 0 replies; 20+ messages in thread
From: cetoni GmbH - Uwe Kindler @ 2009-08-12  9:10 UTC (permalink / raw)
  To: ecos-devel

Hi Jonathan,

here you can download the linker mapping file ecos.map (zipped) that I 
picked  from folder build/infra/current after build process stopped with 
the __cxa_pure_virtual error.

http://www.cetoni.de/ecos_map.zip

Regards, Uwe

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Strange __cxa_pure_virtual problem
  2009-08-19 14:35 cetoni GmbH - Uwe Kindler
  2009-08-19 16:05 ` John Dallaway
@ 2009-08-21 14:55 ` Bart Veer
  1 sibling, 0 replies; 20+ messages in thread
From: Bart Veer @ 2009-08-21 14:55 UTC (permalink / raw)
  To: cetoni GmbH - Uwe Kindler; +Cc: ecos-devel, sergei.gavrikov

>>>>> "Uwe" == cetoni GmbH <- Uwe Kindler <uwe.kindler@cetoni.de>> writes:

    Uwe> Hi Bart,
    Uwe> I compiled an eCos library from default template with
    Uwe> arm-eabi toolchain from eCos homepage. These are teh compiler
    Uwe> switches:

    <snip>

OK, after looking at a disassembly and doing some reading I now
understand what is going on.

static Class object;
int
fred(void)
{
    ...
}

has different semantics from

int
fred(void)
{
    static Class object;
    ...    
}

In the first case "object" will be constructed at system
initialization time. In the second case "object" will be constructed
during the first call to fred(), not during system initialization
time. This difference in behaviour is defined in my copy of Stroustrup
and presumably in the C++ language standard.

In the early days of C++ this would not have been a problem. In
today's multi-threaded environments things are very different. fred()
may get called from inside several threads at the same time, leading
to multiple concurrent attempts at constructing "object". Needless to
say that is going to lead to disaster.

So, g++ generates code to avoid the problem. In particular it will
surround the construction with calls to __cxa_guard_acquire() and
__cxa_guard_release(), plus __cxa_guard_abort() in case problems.
These functions are normally provided in libsupc++.

The default implementations need to be examined in more details, but I
suspect the ones in the anoncvs toolchains are up to the job. They
will be unaware of eCos threading so will not provide appropriate
locking. Hence construction of per-function static objects will not be
properly thread-safe. Also, libsupc++ has been built on the assumption
that code may throw C++ exceptions so the __cxa_guard_...() functions
end up pulling in all the exception handling support, even though eCos
is built with -fno-exceptions. At this stage my guess is that we will
need to provide eCos-specific replacements for these guard functions.
The compiler is doing exactly what it is supposed to.

Theoretically this is a problem for any eCos code involving C++.
Obviously it is much more likely to trigger for code that uses C++
libraries like STL.

Bart

-- 
Bart Veer                                   eCos Configuration Architect
eCosCentric Limited    The eCos experts      http://www.ecoscentric.com/
Barnwell House, Barnwell Drive, Cambridge, UK.      Tel: +44 1223 245571
Registered in England and Wales: Reg No 4422071.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Strange __cxa_pure_virtual problem
  2009-08-19 14:35 cetoni GmbH - Uwe Kindler
@ 2009-08-19 16:05 ` John Dallaway
  2009-08-21 14:55 ` Bart Veer
  1 sibling, 0 replies; 20+ messages in thread
From: John Dallaway @ 2009-08-19 16:05 UTC (permalink / raw)
  To: ecos-devel

The following message seems to summarize the various options regarding
__cxa_guard_release quite succinctly:

  http://www.cygwin.com/ml/cygwin-patches/2005-q2/msg00066.html

John Dallaway

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Strange __cxa_pure_virtual problem
@ 2009-08-19 14:35 cetoni GmbH - Uwe Kindler
  2009-08-19 16:05 ` John Dallaway
  2009-08-21 14:55 ` Bart Veer
  0 siblings, 2 replies; 20+ messages in thread
From: cetoni GmbH - Uwe Kindler @ 2009-08-19 14:35 UTC (permalink / raw)
  To: ecos-devel; +Cc: Bart Veer, Sergei Gavrikov

Hi Bart,

I compiled an eCos library from default template with arm-eabi toolchain 
from eCos homepage. These are teh compiler switches:

-Wall -Wpointer-arith -Wstrict-prototypes -Wundef -Woverloaded-virtual 
-Wno-write-strings  -mno-thumb-interwork -mcpu=arm7tdmi -g2 -O0 
-ffunction-sections -fdata-sections -fno-rtti -fno-exceptions

I used a makfile from examples directory to build my application and 
link againts the library.

If I compile the following main file __cxa_guard_release() is not pulled in:

class Simple
{
private:
     int m_i;
public:
     Simple(int i)
         : m_i(i) {}
};

static Simple simple(1);

int main(int argc, char *argv[])
{
     return 0;
}


If I compile the following main file __cxa_guard_release() is pulled in:

class Simple
{
private:
     int m_i;
public:
     Simple(int i)
         : m_i(i) {}
};


int main(int argc, char *argv[])
{
     static Simple simple(1);
     return 0;
}

I found a message from a mailing list with a similar problem:

http://lists.apple.com/archives/darwin-drivers/2005/May/msg00061.html

The message states:

....
Evidently the compiler generates these as a by-product of the class 
instantiation. By moving the class instantiation out of the function, 
into global space, the symbols were not generated.
...

So this seems like a compiler issue for me. You can easily confirm this 
behaviour by building my simple application. It is important to link 
against a debug build of the library (-g2 -O0) to reproduce this behaviour.

Can anyone confirm that compiler behaviour of the arm-eabi toolchain?
Sergei, can you reproduce this. Can you reproduce this with any other 
toolchain (x86)?

Regards, Uwe

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Strange __cxa_pure_virtual problem
  2009-08-13  8:00   ` Uwe Kindler
@ 2009-08-19 10:37     ` Bart Veer
  0 siblings, 0 replies; 20+ messages in thread
From: Bart Veer @ 2009-08-19 10:37 UTC (permalink / raw)
  To: Uwe Kindler; +Cc: ecos-devel

>>>>> "Uwe" == Uwe Kindler <uwe_kindler@web.de> writes:

    <snip>

    Uwe> Summary:

    Uwe> As soon as I declare a static object of a class with pure
    Uwe> virtual functions, a lot of __cxa_... stuff is pulled in from
    Uwe> libsupc++. This does not depend on uSTL package.

    Uwe> If the static object is a string from uSTL package, the
    Uwe> __cxa_pure_virtual() function from libsupc++ is used. If the
    Uwe> class declaration is part of the application then the
    Uwe> __cxa_pure_virtual() from infra/pure.cxx is used.

    Uwe> Do you have any suggestions how to continue with uSTL package
    Uwe> integration?

The underlying problem seems to be that the compiler is generating
calls to __cxa_guard_release() for reasons that are still not clear.
According to jifl's posting of 12 August that should only happen when
compiling with -fexceptions (possibly accidentally, by removing
-fno-exceptions for the application makefile). Everything else
including pulling in __cxa_pure_virtual() from libsupc++ is a side
effect of that.

So you need to figure out what __cxa_guard_release() is for and under
what circumstances the compiler will issue calls to that function.
Then we can figure out how to proceed.

Bart

-- 
Bart Veer                                   eCos Configuration Architect
eCosCentric Limited    The eCos experts      http://www.ecoscentric.com/
Barnwell House, Barnwell Drive, Cambridge, UK.      Tel: +44 1223 245571
Registered in England and Wales: Reg No 4422071.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Strange __cxa_pure_virtual problem
  2009-08-12 19:07 ` Bart Veer
@ 2009-08-13  8:00   ` Uwe Kindler
  2009-08-19 10:37     ` Bart Veer
  0 siblings, 1 reply; 20+ messages in thread
From: Uwe Kindler @ 2009-08-13  8:00 UTC (permalink / raw)
  To: ecos-devel; +Cc: Bart Veer, jifl

Hi Bart,

here you will find some linker maps:

http://www.cetoni.de/ecos_ld_maps_20090813.zip

> What happens if you then try to link a trivial eCos application which
> declares a static string object? I suspect that is going to pull in
> __cxa_guard_release() again, which will take its __cxa_pure_virtual()
> from libsup++.a instead of libtarget.a. So deleting the static from
> the declaration is only moving the problem, not solving it.
> 
> Bart
> 


1.

I compiled a trivial eCos application (only a main function) which 
declares a static ustl string object. You will find the linker map in 
the zip archiv (ecos_app_ustl.map). I used the same eCos config that 
crashed on building the diag_printf1() test.

The application is build properly. You are right - it pulls in the 
__cxa_guard_release() and __cxa_pure_virtual() from libsupc++.a.

2.

I did not changed anything in the main function but added the class 
declarations and implementations of the cxxsupp.cxx test in front of the 
main function but did not created any object of these classes. The 
linker map is in the zip archive (ecos_app_ustl_pure.map).

All the __cxa_.... stuff like __cxa_guard_release() is still pulled in 
but now the application uses the __cxa_pure_virtual() from infra/pure.cxx.

(/home/Nutzer/ustl_test_0q_nofio_install/lib/libtarget.a(infra_pure.o)
                               twothreads.o (__cxa_pure_virtual))


3.

I created a default eCos library (template default). I compiled a 
trivial eCos application that contains a main function and in front of 
the main function the class declarations and implementations of the 
cxxsupp.cxx test. In the main function I declared a static object of 
type Derived:

int main(int argc, char *argv[])
{
     static Derived deriv(1);
...

The linker map is in the zip archive (ecos_app_default.map).
All the __cxa_.... stuff like __cxa_guard_release() is still pulled in 
but now the application uses the __cxa_pure_virtual() from 
infra/pure.cxx. That means no uSTL stuff but all __cxa_... stuff present.


Summary:

As soon as I declare a static object of a class with pure virtual 
functions, a lot of __cxa_... stuff is pulled in from libsupc++. This 
does not depend on uSTL package.

If the static object is a string from uSTL package, the 
__cxa_pure_virtual() function from libsupc++ is used. If the class 
declaration is part of the application then the __cxa_pure_virtual() 
from infra/pure.cxx is used.

Do you have any suggestions how to continue with uSTL package integration?

Regards, Uwe


http://www.cetoni.de/ecos_ld_maps_20090813.zip







^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Strange __cxa_pure_virtual problem
  2009-08-12 17:49 Uwe Kindler
@ 2009-08-12 19:07 ` Bart Veer
  2009-08-13  8:00   ` Uwe Kindler
  0 siblings, 1 reply; 20+ messages in thread
From: Bart Veer @ 2009-08-12 19:07 UTC (permalink / raw)
  To: Uwe Kindler; +Cc: ecos-devel, jifl

>>>>> "Uwe" == Uwe Kindler <uwe_kindler@web.de> writes:

    Uwe> Hello Jonathan,
    Uwe> thank you for your detailed description - it helped me to find the 
    Uwe> cause. In ustlecos.cpp there is a function:

    Uwe> void diag_print_exception(const exception& ex)
    Uwe> {
    Uwe>          static string exstr(64);
    Uwe> ...

    Uwe> if I remove the static from the string declaration the 
    Uwe> __cxa_pure_virtual problem is gone.

What happens if you then try to link a trivial eCos application which
declares a static string object? I suspect that is going to pull in
__cxa_guard_release() again, which will take its __cxa_pure_virtual()
from libsup++.a instead of libtarget.a. So deleting the static from
the declaration is only moving the problem, not solving it.

Bart

-- 
Bart Veer                                   eCos Configuration Architect
eCosCentric Limited    The eCos experts      http://www.ecoscentric.com/
Barnwell House, Barnwell Drive, Cambridge, UK.      Tel: +44 1223 245571
Registered in England and Wales: Reg No 4422071.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Strange __cxa_pure_virtual problem
@ 2009-08-12 17:49 Uwe Kindler
  2009-08-12 19:07 ` Bart Veer
  0 siblings, 1 reply; 20+ messages in thread
From: Uwe Kindler @ 2009-08-12 17:49 UTC (permalink / raw)
  To: ecos-devel; +Cc: jifl

Hello Jonathan,

thank you for your detailed description - it helped me to find the 
cause. In ustlecos.cpp there is a function:

void diag_print_exception(const exception& ex)
{
         static string exstr(64);
...

if I remove the static from the string declaration the 
__cxa_pure_virtual problem is gone.


Regards, Uwe

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Strange __cxa_pure_virtual problem
       [not found] <4A827EDC.3030004@cetoni.de>
@ 2009-08-12 14:15 ` Jonathan Larmour
  0 siblings, 0 replies; 20+ messages in thread
From: Jonathan Larmour @ 2009-08-12 14:15 UTC (permalink / raw)
  To: cetoni GmbH - Uwe Kindler; +Cc: ecos-devel

cetoni GmbH - Uwe Kindler wrote:
> Hi Jonathan,
> 
> attached ist the linker mapping file ecos.map (zipped) that I picked 
> from folder build/infra/current after build process stopped with the
> __cxa_pure_virtual error.

Thanks. That clears things up.

The reference comes from here:

/opt/ecos/gnutools/arm-eabi/bin/../lib/gcc/arm-eabi/4.3.2/../../../../arm-eabi/lib/nointerwork/libsupc++.a(pure.o)
 
/opt/ecos/gnutools/arm-eabi/bin/../lib/gcc/arm-eabi/4.3.2/../../../../arm-eabi/lib/nointerwork/libsupc++.a(eh_exception.o) 
(__cxa_pure_virtual)

eh_exception.o (in pure.o) in turn got pulled in because of this:
/opt/ecos/gnutools/arm-eabi/bin/../lib/gcc/arm-eabi/4.3.2/../../../../arm-eabi/lib/nointerwork/libsupc++.a(eh_exception.o)
 
/opt/ecos/gnutools/arm-eabi/bin/../lib/gcc/arm-eabi/4.3.2/../../../../arm-eabi/lib/nointerwork/libsupc++.a(guard.o) 
(_ZNSt9exceptionD2Ev)

And the real dependency causing the grief is here:

/opt/ecos/gnutools/arm-eabi/bin/../lib/gcc/arm-eabi/4.3.2/../../../../arm-eabi/lib/nointerwork/libsupc++.a(guard.o)
 
/home/Nutzer/ustl_test_0p_nofio_install/lib/libtarget.a(language_cxx_ustl_ustlecos.o) 
(__cxa_guard_release)

So guard.o (in libsupc++) is being pulled in because of a call from 
ustlecos.cpp to __cxa_guard_release (potentially among others). This pulls 
in the entire exception handling machinery, eventually causing 
__cxa_pure_virtual to be referenced, and because of the way ld looks for 
symbols, it will see the version in libsupc++ and use that instead of the 
one in libtarget.a, because libtarget.a comes earlier in the link line.

I don't quite know how ustlecos.cpp has a reference to 
__cxa_guard_release, since I would only expect that dependency if building 
with -fexceptions. And ustlecos.cpp is empty with -fno-exceptions. Have 
you made changes around this area?

Another odd change is that there is a dependency on ustl in something like 
the diag_sprintf1 test anyway. The problem seems to be here:
/home/Nutzer/ustl_test_0p_nofio_install/lib/libtarget.a(language_cxx_ustl_bktrace.o)
 
/home/Nutzer/ustl_test_0p_nofio_install/lib/libtarget.a(language_c_libc_stdio_stream.o) 
(_ZdlPv)

Looks like you have added uSTL stuff into stdio. Since this has a massive 
knock-on effect of dependencies, with tons of stuff being pulled in as a 
result, this seems like a bad idea TBH.

A fairly trivial workaround to the __cxa_pure_virtual issue may be to use 
CYG_REFERENCE_OBJECT with __cxa_pure_virtual directly from ustlecos.cpp, 
if using exceptions. That will cause the version in libtarget.a to be 
pulled in. But first we should find out why ustlecos.cpp is referencing 
__cxa_guard_release. If you haven't made any changes, then maybe a 
disassembly of the .o may clarify.

This doesn't help the new/delete overrides in infra and memalloc packages 
admittedly. Theoretically they could be susceptible to the same sort of 
issue, although I'm not sure it's a practical concern now.

Jifl
-- 
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Strange __cxa_pure_virtual problem
  2009-08-07 13:40   ` Bart Veer
  2009-08-07 15:08     ` John Dallaway
  2009-08-07 16:31     ` Sergei Gavrikov
@ 2009-08-12  1:34     ` Jonathan Larmour
  2 siblings, 0 replies; 20+ messages in thread
From: Jonathan Larmour @ 2009-08-12  1:34 UTC (permalink / raw)
  To: uwe.kindler; +Cc: Bart Veer, ecos-devel

Bart Veer wrote:
>>>>>>"John" == John Dallaway <john@dallaway.org.uk> writes:
> 
> 
>     John> Hi Uwe (and Bart)
> 
>     <snip>
> 
>     John> Bart, do you have any ideas why your implementation of
>     John> __cxa_pure_virtual() in CYGPKG_INFRA might be ignored?
> 
> It is not necessarily being ignored. The eCos version of
> __cxa_pure_virtual() ends up in libtarget.a, which is part of the same
> linker script GROUP() as libsupc++.a. So strictly speaking the linker
> is perfectly at liberty to choose one or the other.

In fact it isn't. Order is still well-defined. Anything else would be a bug.

I believe I've worked out where this problem is coming from. Unresolved 
symbol searches are not restarted. Which means ld will not return to the 
start of the library path to look for unresolved symbols - it will just 
continue from where it already is in the search path at the point the 
unresolved symbol appears.  So something that references 
__cxa_pure_virtual from somewhere _after_ libtarget.a, won't see the 
version in libtarget.a. Note this behaviour is not specific to GROUP; it's 
also true for standard linking.

Normally this isn't an issue for symbols within libtarget.a as the symbols 
are unique.

I note this could potentially also affect stuff in infra's delete.cxx and 
memalloc's malloc.cxx definitions of new/delete if 
CYGFUN_MEMALLOC_MALLOC_CXX_OPERATORS is on. So it's possible we need a 
more general solution than just for __cxa_pure_virtual().

But back to uSTL, I'm still not clear how Uwe has hit this. I did request 
the other day for a linker map file, which may shed some light. That 
request still stands. My guess is that uSTL is referencing some object in 
libsupc++ which is in turn referencing __cxa_pure_virtual. But I don't get 
why uSTL is a factor here when building a test like diag_sprintf1, as the 
presence of uSTL surely hasn't changed how diag_sprintf1 is built has it? 
Perhaps Uwe could shed some light. The uSTL package CDL doesn't seem to do 
anything like turn on -fexceptions or -frtti for example, that I've seen.

So we need more information before determining a correct fix (and FAOD, as 
Bart will know, his workaround would not be appropriate to be checked in).

Jifl
-- 
--["No sense being pessimistic, it wouldn't work anyway"]-- Opinions==mine

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Strange __cxa_pure_virtual problem
  2009-08-07 15:08     ` John Dallaway
  2009-08-07 15:42       ` Bart Veer
@ 2009-08-11  9:05       ` Daniel Néri
  1 sibling, 0 replies; 20+ messages in thread
From: Daniel Néri @ 2009-08-11  9:05 UTC (permalink / raw)
  To: ecos-devel

John Dallaway <john@dallaway.org.uk> writes:

> For future reference, it looks like configuring GCC with
> --disable-hosted-libstdcxx would result in a version of
> __cxa_pure_virtual() without any dependencies.

FWIW, that's how I configure my toolchain since a couple of years back.


Regards,
Daniel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Strange __cxa_pure_virtual problem
@ 2009-08-08  6:04 Uwe Kindler
  0 siblings, 0 replies; 20+ messages in thread
From: Uwe Kindler @ 2009-08-08  6:04 UTC (permalink / raw)
  To: ecos-devel

Hi Bart,

 > So, I think there is one solution (untested) that may work:

 > --- cdl/infra.cdl	29 Jan 2009 17:49:44 -0000	1.18
 > +++ cdl/infra.cdl	7 Aug 2009 13:30:03 -0000
 > @@ -59,7 +59,8 @@ cdl_package CYGPKG_INFRA {
 >      compile startup.cxx prestart.cxx pkgstart.cxx userstart.cxx      \
 >              dummyxxmain.cxx null.cxx simple.cxx fancy.cxx buffer.cxx \
 >              diag.cxx tcdiag.cxx memcpy.c memset.c delete.cxx eprintf.c \
 > -	    pure.cxx gccsupport.cxx
 > +            gccsupport.cxx
 > +    compile -library=libextras.a pure.cxx
 >

I've tried this patch as well with arm-eabi toolchain and it solved the 
__cxa_pure_virtual issue.

That means uSTL 1.3 package now compiles successfully in all 
configurations and with different optimisation levels.

Regards, Uwe

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Strange __cxa_pure_virtual problem
  2009-08-07 13:40   ` Bart Veer
  2009-08-07 15:08     ` John Dallaway
@ 2009-08-07 16:31     ` Sergei Gavrikov
  2009-08-12  1:34     ` Jonathan Larmour
  2 siblings, 0 replies; 20+ messages in thread
From: Sergei Gavrikov @ 2009-08-07 16:31 UTC (permalink / raw)
  To: Bart Veer; +Cc: John Dallaway, uwe.kindler, ecos-devel

On Fri, Aug 07, 2009 at 02:40:04PM +0100, Bart Veer wrote:

[snip]

> So, I think there is one solution (untested) that may work:

> --- cdl/infra.cdl	29 Jan 2009 17:49:44 -0000	1.18
> +++ cdl/infra.cdl	7 Aug 2009 13:30:03 -0000
> @@ -59,7 +59,8 @@ cdl_package CYGPKG_INFRA {
>      compile startup.cxx prestart.cxx pkgstart.cxx userstart.cxx      \
>              dummyxxmain.cxx null.cxx simple.cxx fancy.cxx buffer.cxx \
>              diag.cxx tcdiag.cxx memcpy.c memset.c delete.cxx eprintf.c \
> -	    pure.cxx gccsupport.cxx
> +            gccsupport.cxx
> +    compile -library=libextras.a pure.cxx
>  

[snip]

> This assumes moving pure.cxx to libextras.a fixes the problem.
> Hopefully somebody will try this in the near future.
> 
> Bart

Hello Bart,

I've tried it. It fixes __cxa_pure_virtual issue. I re-test it for the
Uwe's request with i386-elf toolchain and turned off optimization.

Thank you,

Sergei

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Strange __cxa_pure_virtual problem
  2009-08-07 15:08     ` John Dallaway
@ 2009-08-07 15:42       ` Bart Veer
  2009-08-11  9:05       ` Daniel Néri
  1 sibling, 0 replies; 20+ messages in thread
From: Bart Veer @ 2009-08-07 15:42 UTC (permalink / raw)
  To: John Dallaway; +Cc: ecos-devel

>>>>> "John" == John Dallaway <john@dallaway.org.uk> writes:

    John> Hi Bart
    John> Thanks for the suggestions and patch.

    John> Bart Veer wrote:

    >> 3) arguably __cxa_pure_virtual() should have been removed from
    >> libsupc++ in the prebuilt toolchains. But we don't want to
    >> respin toolchains for this, and anyway that would not help with
    >> the synthetic target where we want people to be able to use the
    >> existing Linux toolchain whenever possible.

    John> For future reference, it looks like configuring GCC with
    John> --disable-hosted-libstdcxx would result in a version of
    John> __cxa_pure_virtual() without any dependencies.

Interesting, but would not help with the synthetic target.

Bart

-- 
Bart Veer                                   eCos Configuration Architect
eCosCentric Limited    The eCos experts      http://www.ecoscentric.com/
Barnwell House, Barnwell Drive, Cambridge, UK.      Tel: +44 1223 245571
Registered in England and Wales: Reg No 4422071.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Strange __cxa_pure_virtual problem
  2009-08-07 13:40   ` Bart Veer
@ 2009-08-07 15:08     ` John Dallaway
  2009-08-07 15:42       ` Bart Veer
  2009-08-11  9:05       ` Daniel Néri
  2009-08-07 16:31     ` Sergei Gavrikov
  2009-08-12  1:34     ` Jonathan Larmour
  2 siblings, 2 replies; 20+ messages in thread
From: John Dallaway @ 2009-08-07 15:08 UTC (permalink / raw)
  To: Bart Veer; +Cc: eCos development list

Hi Bart

Thanks for the suggestions and patch.

Bart Veer wrote:

> 3) arguably __cxa_pure_virtual() should have been removed from libsupc++
> in the prebuilt toolchains. But we don't want to respin toolchains for
> this, and anyway that would not help with the synthetic target where
> we want people to be able to use the existing Linux toolchain whenever
> possible.

For future reference, it looks like configuring GCC with
--disable-hosted-libstdcxx would result in a version of
__cxa_pure_virtual() without any dependencies.

John Dallaway

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Strange __cxa_pure_virtual problem
  2009-08-07 12:04 ` John Dallaway
@ 2009-08-07 13:40   ` Bart Veer
  2009-08-07 15:08     ` John Dallaway
                       ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Bart Veer @ 2009-08-07 13:40 UTC (permalink / raw)
  To: John Dallaway; +Cc: uwe.kindler, ecos-devel

>>>>> "John" == John Dallaway <john@dallaway.org.uk> writes:

    John> Hi Uwe (and Bart)

    <snip>

    John> Bart, do you have any ideas why your implementation of
    John> __cxa_pure_virtual() in CYGPKG_INFRA might be ignored?

It is not necessarily being ignored. The eCos version of
__cxa_pure_virtual() ends up in libtarget.a, which is part of the same
linker script GROUP() as libsupc++.a. So strictly speaking the linker
is perfectly at liberty to choose one or the other. Normally I would
expect it to pick whichever it came across first while reading in the
library archives, which would mean the eCos libtarget.a one. I have no
idea why changing the compiler optimization level would affect the
linker behaviour.

A couple of points:

1) __cxa_pure_virtual() is actually pretty useless, except possibly as
a debugging tool. It is intend to catch the case where application
code calls a virtual function for an object that is still being
constructed, Ideally its use could be suppressed at compile-time, but
even if we submitted a compiler patch for this it would not help any
time soon.

2) it might be possible to fix the problem in the linker by making the
library search order more deterministic. If the linker is not going to
be deterministic about this then it should probably issue a warning
about ambiguous duplicate definitions in libraries. Again that is not
going to help anytime soon.

3) arguably __cxa_pure_virtual() should have been removed from libsupc++
in the prebuilt toolchains. But we don't want to respin toolchains for
this, and anyway that would not help with the synthetic target where
we want people to be able to use the existing Linux toolchain whenever
possible.

4) since __cxa_pure_virtual() should never get called in correctly
written code we could have a dummy symbol definition at an invalid
location. That is what -Wl,--defsym -Wl,__cxa_pure_virtual=0 achieves,
it tells the linker that __cxa_pure_virtual() can be found at location
0x0. The same could be achieved in the linker script. But 0x0 may not
always be a sensible NULL location, some targets may have real code
there. Plus, we don't want to start messing about with the linker
flags for all targets, nor the linker scripts for all architectures
and possibly all targets.

So, I think there is one solution (untested) that may work:

----------------------------------------------------------------------------
2009-08-07  Bart Veer  <bartv@ecoscentric.com>

	* cdl/infra.cdl: move __cxa_pure_virtual() into extras.o to
	prevent linker ambiguity with the libsupc++ version.

Index: cdl/infra.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/infra/current/cdl/infra.cdl,v
retrieving revision 1.18
diff -u -p -r1.18 infra.cdl
--- cdl/infra.cdl	29 Jan 2009 17:49:44 -0000	1.18
+++ cdl/infra.cdl	7 Aug 2009 13:30:03 -0000
@@ -59,7 +59,8 @@ cdl_package CYGPKG_INFRA {
     compile startup.cxx prestart.cxx pkgstart.cxx userstart.cxx      \
             dummyxxmain.cxx null.cxx simple.cxx fancy.cxx buffer.cxx \
             diag.cxx tcdiag.cxx memcpy.c memset.c delete.cxx eprintf.c \
-	    pure.cxx gccsupport.cxx
+            gccsupport.cxx
+    compile -library=libextras.a pure.cxx
 
 
     # ====================================================================
----------------------------------------------------------------------------

Basically this moves pure.cxx from libtarget.a to
libextras.a/extras.o. That means the eCos version will be part of a .o
file so will automatically be part of the executable with no need for
searching libraries, so the libsupc++ version will never be
considered. If __cxa_pure_virtual() is never used then linker garbage
collection should take care of it.

The disadvantage is that any dependencies of __cxa_pure_virtual() will
get resolved before linker garbage collection takes place, so if any
of those dependencies involve C++ static constructors or anything else
covered by a linker script KEEP() then we have added bloat to the
system. Looking at the current implementation:

----------------------------------------------------------------------------
extern "C" void
__cxa_pure_virtual(void)
{
    CYG_FAIL("attempt to use a virtual function before object has been constructed");
    for ( ; ; );
}
----------------------------------------------------------------------------

in a production build (CYGDBG_USE_ASSERTS disabled) CYG_FAIL() maps to
CYG_EMPTY_STATEMENT so no problem there. In a debug build we are
likely to pull in cyg_assert_msg() and cyg_assert_fail(), which means
all of diag_printf() and its dependencies. That is not actually too
serious. For anything except a minimal configuration there should be
other asserts in the system so those functions will get pulled in
anyway. However, for a minimal debug configuration we may have bloated
the system. We need to consider whether that is acceptable, or whether
we should remove the CYG_FAIL() line from the function - given that
__cxa_pure_virtual() serves little purpose anyway.

This assumes moving pure.cxx to libextras.a fixes the problem.
Hopefully somebody will try this in the near future.

Bart

-- 
Bart Veer                                   eCos Configuration Architect
eCosCentric Limited    The eCos experts      http://www.ecoscentric.com/
Barnwell House, Barnwell Drive, Cambridge, UK.      Tel: +44 1223 245571
Registered in England and Wales: Reg No 4422071.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Strange __cxa_pure_virtual problem
  2009-08-07 11:35 cetoni GmbH - Uwe Kindler
@ 2009-08-07 12:04 ` John Dallaway
  2009-08-07 13:40   ` Bart Veer
  0 siblings, 1 reply; 20+ messages in thread
From: John Dallaway @ 2009-08-07 12:04 UTC (permalink / raw)
  To: Uwe Kindler, Bart Veer; +Cc: ecos-devel

Hi Uwe (and Bart)

Uwe Kindler wrote:

> thank you for the hint.
> 
> I replaced the __cxa_pure_virtual function in infra/pure.cxx by the
> following code
> 
> #include <cxxabi.h>
> 
> extern "C" void
> __cxxabiv1::__cxa_pure_virtual (void)
> {
>     CYG_FAIL("attempt to use a virtual function before object has been
> constructed");
>     for ( ; ; );
> }
> 
> It did not solve the problem.

Hmm. It might be worth trying the older eCos arm-elf toolchain (GCC
3.2.1) to help narrow the search space for this problem.

Bart, do you have any ideas why your implementation of
__cxa_pure_virtual() in CYGPKG_INFRA might be ignored?

John Dallaway

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Strange __cxa_pure_virtual problem
@ 2009-08-07 11:35 cetoni GmbH - Uwe Kindler
  2009-08-07 12:04 ` John Dallaway
  0 siblings, 1 reply; 20+ messages in thread
From: cetoni GmbH - Uwe Kindler @ 2009-08-07 11:35 UTC (permalink / raw)
  Cc: John Dallaway, ecos-devel, Sergei Gavrikov

Hi John,

thank you for the hint.

I replaced the __cxa_pure_virtual function in infra/pure.cxx by the 
following code


#include <cxxabi.h>

extern "C" void
__cxxabiv1::__cxa_pure_virtual (void)
{
     CYG_FAIL("attempt to use a virtual function before object has been 
constructed");
     for ( ; ; );
}

It did not solve the problem.

Regards, Uwe

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Strange __cxa_pure_virtual problem
  2009-08-05 18:55 Uwe Kindler
@ 2009-08-07  9:35 ` John Dallaway
  0 siblings, 0 replies; 20+ messages in thread
From: John Dallaway @ 2009-08-07  9:35 UTC (permalink / raw)
  To: Uwe Kindler; +Cc: ecos-devel

Hi Uwe

Uwe Kindler wrote:

> I'm currently in the process of testing uSTL library port. I tried to
> build the library without filestream support and without package file I/O.
> 
> The library build process succeeds. Bu if I start building the test
> cases then the compiler fails on building diag_sprintf1 test with the
> error message:
> 
> make[1]: Leaving directory
> `/home/Nutzer/ustl_test_08_nofio_build/infra/current'
> /opt/ecos/gnutools/arm-eabi/bin/../lib/gcc/arm-eabi/4.3.2/../../../../arm-eabi/lib/nointerwork/libsupc++.a(pure.o):
> In function `__cxa_pure_virtual':
> make: Leaving directory `/home/Nutzer/ustl_test_08_nofio_build'
> (.text.__cxa_pure_virtual+0x14): undefined reference to `write'
> collect2: ld returned 1 exit status
> 
> So the compiler/linker does not link the __cxa_pure_virtual function in
> infra/current/src/pure.cxx and instead takes the implementation from
> libsupc++.

Perhaps this problem is related to the libsupc++ implementation of
__cxa_pure_virtual() moving into the __cxxabiv1 namespace:

http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/libsupc%2B%2B/pure.cc?r1=85452&r2=85463&diff_format=h

Try providing your own implementation of:

   __cxxabiv1::__cxa_pure_virtual()

John Dallaway

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Strange __cxa_pure_virtual problem
@ 2009-08-05 18:55 Uwe Kindler
  2009-08-07  9:35 ` John Dallaway
  0 siblings, 1 reply; 20+ messages in thread
From: Uwe Kindler @ 2009-08-05 18:55 UTC (permalink / raw)
  To: ecos-devel

Hi,

I'm currently in the process of testing uSTL library port. I tried to 
build the library without filestream support and without package file I/O.

The library build process succeeds. Bu if I start building the test 
cases then the compiler fails on building diag_sprintf1 test with the 
error message:

make[1]: Leaving directory 
`/home/Nutzer/ustl_test_08_nofio_build/infra/current'
/opt/ecos/gnutools/arm-eabi/bin/../lib/gcc/arm-eabi/4.3.2/../../../../arm-eabi/lib/nointerwork/libsupc++.a(pure.o): 
In function `__cxa_pure_virtual':
make: Leaving directory `/home/Nutzer/ustl_test_08_nofio_build'
(.text.__cxa_pure_virtual+0x14): undefined reference to `write'
collect2: ld returned 1 exit status

So the compiler/linker does not link the __cxa_pure_virtual function in 
infra/current/src/pure.cxx and instead takes the implementation from 
libsupc++.

In the libsupc++ source file pure.cc the function __cxa_pure_virtual 
writes an error string to stderr via 'write' function. Because no file 
I/O package is present, there is no write function and the reference to 
'write' is undefinded.

This error only occures for debug builds (-g2 -O0). If I build with -g 
-O2 this error does not occur. This problem does not occur, if I link my 
  main.cpp application against the library but it occures when I build 
test cases. As soon as I add the file I/O package, the tests build 
process succeeds because a 'write' function is present.

The question is, how can/should I solve this problem? Is there a way to 
force the compiler/linker to use the infra/current/src/pure.cxx 
implementation or should I provide a dummy 'write' function in uSTL 
package if file I/O package is not present?

Regards, Uwe

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2009-08-21 14:55 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-12  9:10 Strange __cxa_pure_virtual problem cetoni GmbH - Uwe Kindler
  -- strict thread matches above, loose matches on Subject: below --
2009-08-19 14:35 cetoni GmbH - Uwe Kindler
2009-08-19 16:05 ` John Dallaway
2009-08-21 14:55 ` Bart Veer
2009-08-12 17:49 Uwe Kindler
2009-08-12 19:07 ` Bart Veer
2009-08-13  8:00   ` Uwe Kindler
2009-08-19 10:37     ` Bart Veer
     [not found] <4A827EDC.3030004@cetoni.de>
2009-08-12 14:15 ` Jonathan Larmour
2009-08-08  6:04 Uwe Kindler
2009-08-07 11:35 cetoni GmbH - Uwe Kindler
2009-08-07 12:04 ` John Dallaway
2009-08-07 13:40   ` Bart Veer
2009-08-07 15:08     ` John Dallaway
2009-08-07 15:42       ` Bart Veer
2009-08-11  9:05       ` Daniel Néri
2009-08-07 16:31     ` Sergei Gavrikov
2009-08-12  1:34     ` Jonathan Larmour
2009-08-05 18:55 Uwe Kindler
2009-08-07  9:35 ` John Dallaway

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).