[ECOS] Constructor ordering for memory pools vs. stdio
Barry Wealand
barry.wealand@lmco.com
Wed Nov 9 19:57:00 GMT 2005
Barry Wealand wrote:
> Thank you, Andrew. After doing a little more research this morning, I
> discovered that the problem was caused by the ecos-2.0 version of
> packages/services/memalloc/common/v2_0/src/heapgen.tcl, which was
> generating C++ source with incorrect placement of the
> CYGBLD_ATTRIB_INIT_PRI(...) macro. This problem was specifically
> addressed and fixed with rev. 1.9 of this file. After replacing this
> file in our eCos source tree and rebuilding from scratch, all of these
> problems have gone away.
>
> Thanks again for your support.
>
> Barry Wealand
>
>
> Andrew Lunn wrote:
>
>>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
More information about the Ecos-discuss
mailing list