cancel
Showing results for 
Search instead for 
Did you mean: 

C++ no bad alloc exception for vector class

juliuscaesar
Associate III
Posted on June 24, 2018 at 21:34

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 default

http://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\Debug

arm-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.c

Linker flags:

Building target: Giessomat.elf

Invoking: MCU G++ Linker

arm-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 -lm

Finished building target: Giessomat.elf

With these flags exceptions should be enabled right? So why am i not catching this exception?

7 REPLIES 7
Posted on June 24, 2018 at 22:52

>>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?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
juliuscaesar
Associate III
Posted on June 25, 2018 at 23:26

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:

0690X0000060LT6QAM.png0690X0000060LIdQAM.png

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?

Posted on June 25, 2018 at 23:56

 ,

 ,

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Cyril FENARD
ST Employee
Posted on June 27, 2018 at 15:44

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

https://community.st.com/external-link.jspa?url=http%3A%2F%2Fsourceware.org%3A%2Fgit%2Fnewlib-cygwin.git

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::cout

Throwing an integer exception...

the integer exception was caught, with value: 42

test_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.

Posted on July 09, 2018 at 22:38

@

Turvey.Clive.002

I used True Studio to reproduce the error.

0690X0000060LdqQAE.png

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

Posted on July 10, 2018 at 08:16

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.

Posted on July 10, 2018 at 10:10

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