Dynamic Memory in C++

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
dflogeras
Posts: 232
Joined: Tue Sep 03, 2013 8:16 pm
Has thanked: 8 times
Been thanked: 22 times

Dynamic Memory in C++

Post 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?
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Dynamic Memory in C++

Post 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
dflogeras
Posts: 232
Joined: Tue Sep 03, 2013 8:16 pm
Has thanked: 8 times
Been thanked: 22 times

Re: Dynamic Memory in C++

Post 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?
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Dynamic Memory in C++

Post by Giovanni »

You should use the debug allocator.

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

Giovanni
dflogeras
Posts: 232
Joined: Tue Sep 03, 2013 8:16 pm
Has thanked: 8 times
Been thanked: 22 times

Re: Dynamic Memory in C++

Post 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?
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Dynamic Memory in C++

Post 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
dflogeras
Posts: 232
Joined: Tue Sep 03, 2013 8:16 pm
Has thanked: 8 times
Been thanked: 22 times

Re: Dynamic Memory in C++

Post 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
Post Reply