Page 1 of 1

Dynamic Memory in C++

Posted: Fri Aug 01, 2014 2:11 pm
by dflogeras
Hi,

I've been attempting to play with C++ support in ChibiOS. I am working with a STM32F407 based discovery kit. Using ChibiOS-2.6.3's ARMCM4_STM32F407-DISCOVERY-G++ as a starting point.

Let me preface this with, yes I realize that typically one only uses a subset of C++ in embedded software. I am just playing with the possibilities of porting an existing codebase which makes use of such things as RTTI, exceptions, STL, and dynamic memory.

My toolchain is a Gentoo crossdev based chain using:
gcc/g++-4.7.3
newlib-2.0.0
binutils-2.23.2
gdb-7.6.2

I am attemping first to add the (seemingly) simple lines of code:

Code: Select all

#include <vector>
...
main( ... ) {
  std::vector< int > vi( 10 );
  ....
}


However, when the constructor of the vector attempts to allocate memory, I wind up in SIGTRAP in the bowels of newlib (do_AngelSWI).

I have attempted to implement (unsuccessfully) new/delete by enabling heap/malloc in chconf.h, and then adding:

Code: Select all

#include  <new>

void *operator new(size_t size) _GLIBCXX_USE_NOEXCEPT { return malloc(size); }
void *operator new[](size_t size) _GLIBCXX_USE_NOEXCEPT { return malloc(size); }
void operator delete(void *p) _GLIBCXX_USE_NOEXCEPT { free(p); }
void operator delete[](void *p) _GLIBCXX_USE_NOEXCEPT { free(p); }


to my project, but to no avail. The code compiles, but after loading the board locks up and I cannot even use the debugger.
Program received signal SIGTRAP, Trace/breakpoint trap.
0x00000000 in ?? ()


I have tried upping the stack/process stack sizes from 0x0400 to 0x0800 and even 0x1000 to no avail.

Do I need to add something in the linker script to support new/delete and/or exceptions? I've seen several bits online alluding to this, but all seem like shot in the dark hacks, I was wondering what the recommended way is?

Re: Dynamic Memory in C++

Posted: Fri Aug 01, 2014 2:20 pm
by Giovanni
Hi,

I think somebody already did this, it is matter of redefining the new operator to use the OS allocator, do not enable the use-malloc thing, use the native allocator.

Giovanni

Re: Dynamic Memory in C++

Posted: Fri Aug 01, 2014 3:31 pm
by dflogeras
Giovanni,

Ok, I had tried this earlier from something in the forums:

Code: Select all

void* operator new (size_t size) { return chCoreAlloc(size); }
void* operator new[] (size_t size) { return chCoreAlloc(size); }


But it did not work. I just tried this (after disabling CH_USE_MALLOC_HEAP):

Code: Select all

void* operator new( size_t size ) { return chHeapAlloc( 0x0, size ); }
void* operator new[]( size_t size ) { return chHeapAlloc( 0x0, size ); }
void operator delete( void *p ) { chHeapFree( p ); }
void operator delete[]( void *p ) { chHeapFree( p ); }


And I got a little further, in that my std::vector calls new, gets into my wrapper version, then it fails when attempting to call H_UNLOCK(heapp) on line 167 of chheap.c. Actually following it down in the debugger, it actually fails on line 284 of chmtx.c when calling:

Code: Select all

284│       if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio)
285│         newprio = mp->m_queue.p_next->p_prio;


What might be the cause of this?

Re: Dynamic Memory in C++

Posted: Fri Aug 01, 2014 3:36 pm
by Giovanni
You should use the debug allocator.

It could be anything, likely a stack overflow, are debug options enabled in chconf.h?

Giovanni

Re: Dynamic Memory in C++

Posted: Fri Aug 01, 2014 4:09 pm
by dflogeras
I turned all DBG features on in chconf.h.

It looks like in Mutex* chMtxUnlock(void) the second chDbgAssert (line 265) is failing and I wind up in the unhandled exception handler. In fact, after the first line of the function

Code: Select all

Thread *ctp = currp;

it looks like ctp is null.

I tried doubling the stacks (to 0x0800 bytes each), but to no avail. What is the difference between the main_stack_size and the process_stack_size?

Re: Dynamic Memory in C++

Posted: Fri Aug 01, 2014 4:27 pm
by Giovanni
The main stack is the stack for interrupts, the process stack is the stack for the main() function.

Of course you have to consider also stacks of other threads. That assertion is a symptom of a major memory corruption so there is something overflowing.

Giovanni

Re: Dynamic Memory in C++

Posted: Fri Aug 01, 2014 4:54 pm
by dflogeras
Oh god, time to look stupid :)

It was none of the above. I was instantiating my vector just before the halInit(); and System::init(); calls (which of course set up the heap as well as the main thread). It became plainly obvious when I started whittling the main.cpp down to the bare minimum.

Thanks for holding my hand through this Giovanni :)

Dave