new does not always throw a badalloc exception if memory cannot be allocated

Post here first, or if you can't find a relevant section!
Richard
Posts: 6
Joined: Sun Jan 05, 2025 1:51 pm

Re: new does not always throw a badalloc exception if memory cannot be allocated

Post by Richard »

Hi,

the meantime I tried different ways to override the compiler flags, but without success. I was in contact with the VisualMicro team, but no success too.
https://www.visualmicro.com/forums/YaBB ... 952506/0#2
Of course, I compiled everthing with the Nano Standard library.

As you recommended to contribute on this, since it is a community project, I suggest to replace the new definitions in this way:

Code: Select all

void* operator new(std::size_t sz) 
{ 
  void* ptr = std::malloc(sz);
#ifdef __cpp_exceptions
  if (ptr)
  {
      return ptr;
  }
  else throw std::bad_alloc{};
#else
  return ptr;
#endif
}
While dealing with this problem, I habe been overloading new and delete in this way. This works fine for ESP32 and Raspberry Pico projects, and I get the expected exceptions with too much news and push_backs. However, for my STM32 Board I got the error messages:
Linking it all together ...
# Coping cached core C:\Users\RK_2\AppData\Local\Temp\VMBCore\arduino20x\0d0afcdd19ce3666a17ed0725e134254\core.a to C:\Users\RK_2\AppData\Local\Temp\VMBuilds\STM32-F303RE\STMicroelectronics_Nucleo_64\Release\core.a

"c:\Users\RK_2\AppData\Local\Arduino15\packages\STMicroelectronics\tools\xpack-arm-none-eabi-gcc\13.2.1-1.1/bin/arm-none-eabi-gcc" -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -O0 -DNDEBUG -Wl,--defsym=LD_FLASH_OFFSET=0x0 -Wl,--defsym=LD_MAX_SIZE=524288 -Wl,--defsym=LD_MAX_DATA_SIZE=65536 -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common "-Wl,--default-script=c:\Users\RK_2\AppData\Local\Arduino15\packages\STMicroelectronics\hardware\stm32\2.9.0\variants\STM32F3xx\F303R(D-E)T/ldscript.ld" "-Wl,--script=c:\Users\RK_2\AppData\Local\Arduino15\packages\STMicroelectronics\hardware\stm32\2.9.0\system/ldscript.ld" "-Wl,-Map,C:\Users\RK_2\AppData\Local\Temp\VMBuilds\STM32-F303RE\STMicroelectronics_Nucleo_64\Release/STM32-F303RE.ino.map" -Wl,--no-warn-rwx-segments -o "C:\Users\RK_2\AppData\Local\Temp\VMBuilds\STM32-F303RE\STMicroelectronics_Nucleo_64\Release/STM32-F303RE.ino.elf" "-LC:\Users\RK_2\AppData\Local\Temp\VMBuilds\STM32-F303RE\STMicroelectronics_Nucleo_64\Release" -Wl,--start-group "STM32-F303RE.cpp.o" "SrcWrapper\syscalls.c.o" "SrcWrapper\HardwareTimer.cpp.o" "SrcWrapper\new.cpp.o" "SrcWrapper\HAL\stm32yyxx_hal.c.o" "SrcWrapper\HAL\stm32yyxx_hal_adc.c.o" "SrcWrapper\HAL\stm32yyxx_hal_adc_ex.c.o" "SrcWrapper\HAL\stm32yyxx_hal_can.c.o"

...

\Users\RK_2\AppData\Local\Temp\VMBCore\arduino20x\0d0afcdd19ce3666a17ed0725e134254\variant\variant_NUCLEO_F303RE.cpp.o" "C:\Users\RK_2\AppData\Local\Temp\VMBuilds\STM32-F303RE\STMicroelectronics_Nucleo_64\Release\core.a" -lc -Wl,--end-group -lm -lgcc -lstdc++

ld.exe: SrcWrapper\\new.cpp.o: in function operator new(unsigned int)
new.cpp*: (.text._Znwj+0x0): multiple definition of operator new(unsigned int); STM32-F303RE.cpp.o:STM32-F303RE.cpp:(.text._Znwj+0x0): first defined here

ld.exe: SrcWrapper\\new.cpp.o: in function operator delete(void*)
new.cpp*: (.text._ZdlPv+0x0): multiple definition of operator delete(void*); STM32-F303RE.cpp.o:STM32-F303RE.cpp:(.text._ZdlPv+0x0): first defined here

collect2.exe*: error: ld returned 1 exit status

Error linking for board Nucleo-64 (STMicroelectronics_Nucleo_64)
Build failed for project 'STM32-F303RE'
Do you see a way to prevent this linker error messsages, so that I can overload new and delete?

This would at least be a way to get the exceptions that I want to have.

Thanks
Richard
fpiSTM
Posts: 1964
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 108
Location: Le Mans
Contact:

Re: new does not always throw a badalloc exception if memory cannot be allocated

Post by fpiSTM »

Don't know how you change build option in VSMicro, it works fine in Arduino IDE.
So use Arduino IDE then can help else stay with WSMicro and tell them that issue is on their side. It is quite easy to tell this:
These issues are best logged with the Board Package creators as these are not related to Visual Micro itself.
So I answer the same.
These issues are best logged with the VSMicro creators as these are not related to Board Package nor Arduino IDE themself.
I've tested with following setup:
1. sketch:

Code: Select all

void setup() {
  Serial.begin(9600);
}

void loop() {
  int* p = new int;
  delete p;
  int n = 1;
  int rep = 1;
  Serial.println("\nStart N_Exception_Basics::test_too_much_news(mit_Exceptions) ");
#ifdef __cpp_exceptions
  try {
#endif
    while (p != nullptr) {
      p = new int[n];
      delete[] p;
      n = n * 10;
      rep++;
      Serial.printf("n=%d p=%d \n", n, (int)p);
    }
#ifdef __cpp_exceptions
    // throw std::bad_alloc();
  } catch (std::exception& e) {
    Serial.printf("Exception bei test_too_much_news n=%d what()=%s\n", n, e.what());
  } catch (...) {
    Serial.printf("... Exception bei test_too_much_news \n");
  }
#endif
  Serial.printf("nach catch ... Exception bei test_too_much_news \n");
}
2. a platform.local.txt to enable the exception:

Code: Select all

compiler.cpp.flags={compiler.extra_flags} -c {compiler.optimization_flags} {compiler.warning_flags} -std={compiler.cpp.std} -ffunction-sections -fdata-sections -fno-threadsafe-statics --param max-inline-insns-single=500 -fno-rtti -fexceptions -fno-use-cxa-atexit -MMD {compiler.stm.extra_include}
3. change in new.cpp:

Code: Select all

@@ -23,15 +23,28 @@
  * SOFTWARE.
  */
 #include <stdlib.h>
+#include <new>
 
-void *operator new (size_t size)
+void* operator new(std::size_t sz)
 {
-  return malloc(size);
+  void* ptr = std::malloc(sz);
+#ifdef __cpp_exceptions
+  if (!ptr) {
+    throw std::bad_alloc{};
+  }
+#endif
+  return ptr;
 }
 
-void *operator new[](size_t size)
+void *operator new[](std::size_t sz)
 {
-  return malloc(size);
+  void* ptr = std::malloc(sz);
+#ifdef __cpp_exceptions
+  if (!ptr) {
+    throw std::bad_alloc{};
+  }
+#endif
+  return ptr;
 }
 
 void operator delete (void *ptr)
4. Newlib standard selected

Note:
- I've updated your changes has it produce warning about return not defined is some case and following MISRA, preferred only one return statement per function.
- change the new[] which is used in your sketch.

Like this it build properly for all setup with or without exception enabled and with newlib nano or standard.

Result:
Start N_Exception_Basics::test_too_much_news(mit_Exceptions)
n=10 p=536875600
n=100 p=536875600
n=1000 p=536875600
n=10000 p=536875600
n=100000 p=536875600
Exception bei test_too_much_news n=100000 what()=std::bad_alloc
nach catch ... Exception bei test_too_much_news
Honestly, I don't know what you want to achieve with this. For over 7 years no one has asked for exception support. Mainly for size constraint and by default newlib nano do not embed it.
And this time I'm agree with VS Micro comment:
As described on the other related thread, there are many limitations for exception handling on embedded systems, and differences between architectures, and versions of C++ in use.
Maybe other users could comment on this?
Post Reply

Return to “General discussion”