[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