From 2017aafe30883867a10e5c737a492182b10d61a4 Mon Sep 17 00:00:00 2001
From: Jan David Mol <mol@astron.nl>
Date: Thu, 27 Oct 2011 11:51:56 +0000
Subject: [PATCH] Task #2695: Don't allow fftw2 to call exit() (which it does
 when out of memory) or malloc() (which can throw a bad_alloc on the CNK when
 out of memory)

---
 RTCP/CNProc/src/CN_Processing_main.cc | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/RTCP/CNProc/src/CN_Processing_main.cc b/RTCP/CNProc/src/CN_Processing_main.cc
index f3a58ac601b..3e6d9e643d3 100644
--- a/RTCP/CNProc/src/CN_Processing_main.cc
+++ b/RTCP/CNProc/src/CN_Processing_main.cc
@@ -49,7 +49,19 @@
 #include <cstdio>
 #include <cstring>
 
+#if defined HAVE_BGP && defined HAVE_FFTW2
+// use our own memory managment to both use new/delete and
+// to avoid fftw from calling exit() when there is not
+// enough memory.
+
+// We can't redirect the malloc()s done by fftw3 yet as they are hard-coded.
+// Be warned that fftw also abort()s or exit()s when malloc fails.
+#define REROUTE_FFTW2_MALLOC
+#endif
 
+#if defined REROUTE_FFTW2_MALLOC
+#include <fftw.h>
+#endif
 
 // install a new handler to produce backtraces for std::bad_alloc
 LOFAR::NewHandler h(LOFAR::BadAllocException::newHandler);
@@ -120,6 +132,16 @@ static Stream *createIONstream(unsigned channel, const LocationInfo &locationInf
   return createStream(descriptor, false);
 }
 
+#if defined REROUTE_FFTW2_MALLOC
+void *my_fftw_malloc(size_t n) {
+  // don't use malloc() as it throws a bad_alloc on the BGP CNK.
+  return new char[n];
+}
+
+void my_fftw_free(void *p) {
+  delete[] p;
+}
+#endif
 
 int main(int argc, char **argv)
 {
@@ -129,6 +151,11 @@ int main(int argc, char **argv)
   std::set_terminate(terminate_with_backtrace);
 #endif
 
+#if defined REROUTE_FFTW2_MALLOC
+  fftw_malloc_hook = my_fftw_malloc;
+  fftw_free_hook   = my_fftw_free;
+#endif
+
 #if defined CATCH_EXCEPTIONS
   try {
 #endif
-- 
GitLab