2018-06-24 12:34 PM
Hey guys,
I'm using C++ on my STM32F429 with G++ compiler.
I was trying to test the limits of the vector class. However I'm always running into a hard fault. I'm expecting a bad alloc exception instead.
http://www.cplusplus.com/reference/vector/vector/emplace_back/
states that:If a reallocation happens, the storage is allocated using the container's
http://www.cplusplus.com/vector::get_allocator
, which may throw exceptions on failure (for the defaulthttp://www.cplusplus.com/allocator
, bad_alloc is thrown if the allocation request does not succeed).vector<int> test_vector;
try { for (int i = 0; i < 50000; i++) { test_vector.emplace_back(i); if (0 == (i % 10)) { //alle 10 mal 1 ms pause osDelay(1); } } } catch (const exception& ex) {//Stop right here
configASSERT(0); }So where is my exception?
Exceptions are enabled in both the compiler and linker.
Compiler flags:
Invoking: MCU GCC Compiler
xxx\Debugarm-none-eabi-gcc -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -std=c11 '-D__weak=__attribute__((weak))' '-D__packed=__attribute__((__packed__))' -DUSE_HAL_DRIVER -DSTM32F429xx -I'xxx/Giessomat/Inc' -I'xxx/Giessomat/Inc/User' -I'xxx/Giessomat/Inc/User/debug' -I'xxx/Giessomat/Inc/User/Testcases' -I'xxx/Giessomat/Inc/User/display' -I'xxx/Giessomat/Inc/User/display/img' -I'xxx/Giessomat/Inc/User/SD' -I'xxx/Giessomat/Inc/User/SD/XML' -I'xxx/Giessomat/Drivers/STM32F4xx_HAL_Driver/Inc' -I'xxx/Giessomat/Drivers/STM32F4xx_HAL_Driver/Inc/Legacy' -I'xxx/Giessomat/Middlewares/Third_Party/FreeRTOS/Source/portable/GCC/ARM_CM4F' -I'xxx/Giessomat/Middlewares/ST/STM32_USB_Device_Library/Core/Inc' -I'xxx/Giessomat/Middlewares/ST/STemWin/Config' -I'xxx/Giessomat/Middlewares/ST/STemWin/inc' -I'xxx/Giessomat/Middlewares/ST/STM32_USB_Device_Library/Class/CustomHID/Inc' -I'xxx/Giessomat/Drivers/CMSIS/Device/ST/STM32F4xx/Include' -I'xxx/Giessomat/Middlewares/Third_Party/FatFs/src' -I'xxx/Giessomat/Middlewares/Third_Party/FreeRTOS/Source/include' -I'xxx/Giessomat/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS' -I'xxx/Giessomat/Drivers/CMSIS/Include' -Og -g3 -pedantic -Wall -Wextra -fmessage-length=0 -ffunction-sections -c -fmessage-length=0 -MMD -MP -MF'Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.d' -MT'Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.o' -o 'Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.o' '../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_sdmmc.c'Building file: ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_usb.cLinker flags:
Building target: Giessomat.elf
Invoking: MCU G++ Linkerarm-none-eabi-g++ -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -L'xxx/\Giessomat\Middlewares\ST\STemWin\Lib' -specs=nosys.specs -specs=nano.specs -u_printf_float -T'../STM32F429ZITx_FLASH.ld' -Wl,-Map=output.map -Wl,--gc-sections -fno-rtti -o 'Giessomat.elf' @'objects.list' -lSTemWin540_CM4_OS_GCC -lmFinished building target: Giessomat.elfWith these flags exceptions should be enabled right? So why am i not catching this exception?
2018-06-24 01:52 PM
>>However I'm always running into a hard fault. I'm expecting a bad alloc exception instead.
So *what* is actually faulting? See processor registers and disassemble faulting instructions.
Does the compiler expect some additional handlers or infrastructure to implement the functionality you expect?
Structures that need to be initialized in the start up code?
2018-06-25 02:26 PM
hey,
the faulty part is that my vector get's larger than the available free heap. The vector probably trys to allocate memory from some protected area.
How can i diagnose the hard fault further. There is no stack trace. (But I'm very sure that the vector allocation is the problem. If i reduce the number of elements added to the vector (i.e instead of 50000 only 10000) everything works fine)
This is just a test to check out the limits of the vector class.
This code is not being used in the actual project.Therefore this code does not require any initialisation.
However how can i safely use a vector if i am always running into a hard fault once the vector is too large?
I'm using gcc/g++ compiler. My settings are as followed:
Both of them have exceptions enabled.
But you did ask the right question
Does the compiler expect some additional handlers or infrastructure to implement the functionality you expect?
I tested exception handling
try
{ //Test Exception throw invalid_argument(''test exception''); } catch (const exception& ex) { configASSERT(0); }why am i not running into an exception but into the termination handler?
2018-06-25 04:56 PM
,
,
How about instrumenting the HardFault_Handler so you get useful data?
,And adding code into _sbrk in syscalls.c or whatever is acting as the allocator. Figure out where the pool is, and how large it is.
If you can isolate where it fails you can try an unwind the call stack, or perform static analysis of the call tree.
>,>,why am i not running into an exception but into the termination handler?
I don't know, you're coding user side try/catch exception handling, but that requires system side implementation to make the plumbing actually work. If all your fault handlers and abort()/exit() functionalities goes into while(1) loops, or just explodes, you'll will likely end up in the trap of last resort, ie HardFault_Handler or Default_Handler.
2018-06-27 06:44 AM
Hi
Lampe.Julian
,Let me share what i did to make it work.
I generated the project thanks to CubeMX tool, targeting SW4STM32 project.
I changed the nature of the eclipse project to C++. I renamed main.c as main.cpp, to get c++ build for this file that tests the C++ exception. I added a main_misc.c file that implements: - _write for the output of std::cout to UART line,- _sbrk to check for lack of memory, from
source files.
I added -fexceptions in the build options I put the stack value at 0x1000 and the heap value at 0x5000....
printf('main(): with printf()\n'); std::cout << 'main(): with std::cout' << std::endl;try {
std::cout << 'Throwing an integer exception...\n'; throw 42; } catch (int i) { std::cout << ' the integer exception was caught, with value: ' << i << '\n'; }while (1){
std::vector<int> test_vector; size_t capacity = test_vector.capacity(); size_t size = 0; std::cout << 'test_vector.capacity() returned: ' << capacity << std::endl; for (int i = 0; i < 5000000; i++) { try { test_vector.emplace_back(i); capacity = test_vector.capacity(); size = test_vector.size();}catch (const std::exception& ex){
std::cout << ' the vector emplace_back() exception was caught, with value: ' << ex.what() << std::endl; Error_Handler();}
std::cout << 'test_vector.size() returned: ' << size << std::endl; std::cout << 'test_vector.capacity() returned: ' << capacity << std::endl; And i could have the following$ cat /dev/ttyS18
main(): with printf() main(): with std::coutThrowing an integer exception...
the integer exception was caught, with value: 42test_vector.capacity() returned: 0
test_vector.size() returned: 1 test_vector.capacity() returned: 1 ... test_vector.size() returned: 256 test_vector.capacity() returned: 256 _sbrk(): heap_end is incremented ... test_vector.size() returned: 4095 test_vector.capacity() returned: 4096 test_vector.size() returned: 4096 test_vector.capacity() returned: 4096 _sbrk: Heap and stack collision the vector emplace_back() exception was caught, with value: std::bad_alloc Hoping it helps. Regards. Cyril.2018-07-09 03:38 PM
@
Turvey.Clive.002
I used True Studio to reproduce the error.
Looks like I&39m allocating memory from some protected regions.
I did track down the problem. The problem is C++ new operator which is probably used internally in the STL. Trying to allocate a large object using new causes the same error. Trying to allocate a large object using malloc() successfully returns a nullpointer.
In my opinion this is a really stupid behaviour. We got the great STL with all those exceptions but none of them are thrown.
I know the implementation of the STL is very much platform depended but still...
Looks like i&39m having the same problems as this guy here:
https://community.st.com/0D50X00009XkWCcSAN
@
Fenard.Cyril
thx for your interesting post. Would you mind to post your main_misc.c file as well, so that i can have a look?
That would be very great
2018-07-10 01:16 AM
Looks like I'm allocating memory from some protected regions.
I wouldn't think so. Memory protection needs to be setup explicitly, and would cause a MPU fault.
2018-07-10 03:10 AM
Hi
,Please find some examples of sources. They are provided as is. Feel free to share improvements. Hope this will help solve your problems.
Regards.
Cyril
________________ Attachments : NUCELO-L476RG_cpp_exceptions.7z.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HxR6&d=%2Fa%2F0X0000000ay2%2FDN9rHATnCUTPjS3drB..qydhskunxLCLPM0JF.eN.5Q&asPdf=false