This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Constructor ordering for memory pools vs. stdio




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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]