This is the mail archive of the
ecos-discuss@sourceware.org
mailing list for the eCos project.
Re: Constructor ordering for memory pools vs. stdio
- From: Andrew Lunn <andrew at lunn dot ch>
- To: Barry Wealand <barry dot wealand at lmco dot com>
- Cc: eCos Discussion <ecos-discuss at ecos dot sourceware dot org>,"Mills, Ted" <ted dot mills at lmco dot com>
- Date: Wed, 9 Nov 2005 20:08:25 +0100
- Subject: Re: [ECOS] Constructor ordering for memory pools vs. stdio
- References: <4370B2FA.7040604@lmco.com>
On Tue, Nov 08, 2005 at 02:15:22PM +0000, Barry Wealand wrote:
> Hello -
>
> We're using eCos 2.0 with a MIPS-like target. We're building eCos with
> GCC 4.0.0 (in case that matters). In an effort to locate a problem with
> memory getting trashed, I built a couple of applications against a
> kernel with assertions enabled. Now, when these apps are executed, an
> assertion failure occurs very quickly:
>
> <5> stream.cxx[585] Cyg_ErrNo Cyg_StdioStream::write Stream object is
> not a valid stream!
>
> Working backward from there, the problem comes about because
> Cyg_StdioStream::initialize() does not finish and place the expected
> value in "magic_validity_word". Walking through the code with GDB, I
> see that the constructor call, Cyg_StdioStream::Cyg_StdioStream(),
> invokes a member constructor to set up an internal memory buffer. This
> constructor fails due to malloc() returning NULL. On further
> inspection, the memory pool upon which malloc depends has not yet been
> set up. And, indeed, looking at the constructor table in section
> .ctors, and with the understanding that cyg_hal_invoke_constructors()
> works through this table from higher memory addresses down to lower
> memory addresses, it seems that the constructor call for the memory pool
> comes later than the constructor call that sets up the stdio streams.
> And yet, I see (in malloc.cxx) that
> CYGBLD_ATTRIB_INIT_BEFORE(CYG_INIT_LIBC) is being used to (seemingly)
> specify that the memory pool constructor gets called before the libc
> constructors (which presumably includes the stdio constructors). On the
> surface, anyway, this seems to be a contradiction.
>
> Am I missing something here? Should the memory pool constructor be
> getting called before the stream constructor?
This sounds like a compiler problem:
(gdb) info br
Num Type Disp Enb Address What
1 breakpoint keep y 0x01005c52 in Cyg_StdioStreamBuffer::set_buffer(unsigned int, unsigned char*)
at /home/lunn/eCos/anoncvs-clean/packages/language/c/libc/stdio/current/src/common/streambuf.cxx:80
breakpoint already hit 2 times
3 breakpoint keep y 0x01008a36 in Cyg_Mempool_dlmalloc_Implementation
at /home/lunn/eCos/anoncvs-clean/packages/services/memalloc/common/current/src/dlmalloc.cxx:950
breakpoint already hit 2 times
4 breakpoint keep y 0x01008907 in malloc at dlmalloc.hxx:133
breakpoint already hit 1 time
(gdb)
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/lunn/eCos/work/install/tests/language/c/libc/stdio/curre nt/tests/stdiooutput
Breakpoint 3, 0x01008a36 in Cyg_Mempool_dlmalloc_Implementation (
this=0x200c800, base=0x200ccb0 "", size=8336208)
at /home/lunn/eCos/anoncvs-clean/packages/services/memalloc/common/current/s rc/dlmalloc.cxx:950
950 CYG_ADDRWORD /* argthru */ )
So first it calls the dlmalloc constructor.
(gdb) c
Continuing.
Breakpoint 1, Cyg_StdioStreamBuffer::set_buffer (this=0x200c78c, size=256,
new_buffer=0x0)
at /home/lunn/eCos/anoncvs-clean/packages/language/c/libc/stdio/current/src/common/streambuf.cxx:80
80 if (new_buffer != NULL) {
The set_buffer is called, which does:
(gdb) c
Continuing.
Breakpoint 4, malloc (size=256) at dlmalloc.hxx:133
133 try_alloc( cyg_int32 size ) { return mypool.try_alloc( size ); }
so everything is happening in the right order.
You might want to make a very simple test program with constructure
priorization which demonstrates the problem and then file a bug report
to the gcc people.
Andrew
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss