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