>From ad35a35561e4bf58c5a0bc410ef115c5a2c79804 Mon Sep 17 00:00:00 2001
From: Matthias Goldhoorn <matthias.goldhoorn@dfki.de>
Date: Thu, 17 Oct 2013 14:58:28 +0200
Subject: [PATCH] Exception handling: Added option to disable exception

This make the life for developers much easier. Let the Exception Raise
so that the user could use gdb for backtracke analysis. Only for Debuggig
purposes.
---
 CMakeLists.txt          |    5 +++++
 rtt/ExecutionEngine.cpp |   16 ++++++++++++++++
 rtt/base/TaskCore.cpp   |   20 ++++++++++++++++++++
 rtt/os/Thread.cpp       |   16 +++++++++-------
 4 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 912ae83..fdda247 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -79,6 +79,11 @@ endif( NOT OROCOS_SUFFIX )
 #                                                 #
 ###################################################
 
+OPTION(CATCH_EXCEPTION "Should RTT Catch Exceptions? Disable for debugging only." ON)
+if(CATCH_EXCEPTION)
+    ADD_DEFINITIONS("-DCATCH_EXCEPTION")
+endif()
+
 OPTION(ENABLE_TESTS "Turn on to enable the testing framework." OFF)
 SET(BUILD_TEST_TIMEOUT 1500 CACHE STRING "Global timeout on all tests (seconds).")
 IF(ENABLE_TESTS)
diff --git a/rtt/ExecutionEngine.cpp b/rtt/ExecutionEngine.cpp
index 4bde246..a53b1fa 100644
--- a/rtt/ExecutionEngine.cpp
+++ b/rtt/ExecutionEngine.cpp
@@ -328,9 +328,12 @@ namespace RTT
         if ( taskc ) {
             // A trigger() in startHook() will be ignored, we trigger in TaskCore after startHook finishes.
             if ( taskc->mTaskState == TaskCore::Running && taskc->mTargetState == TaskCore::Running ) {
+#ifdef CATCH_EXCEPTION 
                 try {
+#endif 
                     taskc->prepareUpdateHook();
                     taskc->updateHook();
+#ifdef CATCH_EXCEPTION 
                 } catch(std::exception const& e) {
                     log(Error) << "in updateHook(): switching to exception state because of unhandled exception" << endlog();
                     log(Error) << "  " << e.what() << endlog();
@@ -339,11 +342,15 @@ namespace RTT
                     log(Error) << "in updateHook(): switching to exception state because of unhandled exception" << endlog();
                     taskc->exception(); // calls stopHook,cleanupHook
                 }
+#endif
             }
             // in case start() or updateHook() called error(), this will be called:
             if (  taskc->mTaskState == TaskCore::RunTimeError ) {
+#ifdef CATCH_EXCEPTION 
                 try {
+#endif
                     taskc->errorHook();
+#ifdef CATCH_EXCEPTION 
                 } catch(std::exception const& e) {
                     log(Error) << "in errorHook(): switching to exception state because of unhandled exception" << endlog();
                     log(Error) << "  " << e.what() << endlog();
@@ -352,6 +359,7 @@ namespace RTT
                     log(Error) << "in errorHook(): switching to exception state because of unhandled exception" << endlog();
                     taskc->exception(); // calls stopHook,cleanupHook
                 }
+#endif
             }
         }
         if ( !this->getActivity() || ! this->getActivity()->isRunning() ) return;
@@ -359,9 +367,12 @@ namespace RTT
         // call all children as well.
         for (std::vector<TaskCore*>::iterator it = children.begin(); it != children.end();++it) {
             if ( (*it)->mTaskState == TaskCore::Running  && (*it)->mTargetState == TaskCore::Running  )
+#ifdef CATCH_EXCEPTION 
                 try {
+#endif
                     (*it)->prepareUpdateHook();
                     (*it)->updateHook();
+#ifdef CATCH_EXCEPTION 
                 } catch(std::exception const& e) {
                     log(Error) << "in updateHook(): switching to exception state because of unhandled exception" << endlog();
                     log(Error) << "  " << e.what() << endlog();
@@ -370,9 +381,13 @@ namespace RTT
                     log(Error) << "in updateHook(): switching to exception state because of unhandled exception" << endlog();
                     (*it)->exception(); // calls stopHook,cleanupHook
                 }
+#endif
             if (  (*it)->mTaskState == TaskCore::RunTimeError )
+#ifdef CATCH_EXCEPTION 
                 try {
+#endif
                     (*it)->errorHook();
+#ifdef CATCH_EXCEPTION 
                 } catch(std::exception const& e) {
                     log(Error) << "in errorHook(): switching to exception state because of unhandled exception" << endlog();
                     log(Error) << "  " << e.what() << endlog();
@@ -381,6 +396,7 @@ namespace RTT
                     log(Error) << "in errorHook(): switching to exception state because of unhandled exception" << endlog();
                     (*it)->exception(); // calls stopHook,cleanupHook
                 }
+#endif
             if ( !this->getActivity() || ! this->getActivity()->isRunning() ) return;
         }
     }
diff --git a/rtt/base/TaskCore.cpp b/rtt/base/TaskCore.cpp
index 3093583..2f8a0e3 100644
--- a/rtt/base/TaskCore.cpp
+++ b/rtt/base/TaskCore.cpp
@@ -102,7 +102,9 @@ namespace RTT {
 
     bool TaskCore::configure() {
         if ( mTaskState == Stopped || mTaskState == PreOperational) {
+#ifdef CATCH_EXCEPTION 
             try {
+#endif
                 mTargetState = Stopped;
                 if (configureHook() ) {
                     mTaskState = Stopped;
@@ -111,6 +113,7 @@ namespace RTT {
                     mTargetState = mTaskState = PreOperational;
                     return false;
                 }
+#ifdef CATCH_EXCEPTION 
             } catch(std::exception const& e) {
                 log(Error) << "in configure(): switching to exception state because of unhandled exception" << endlog();
                 log(Error) << "  " << e.what() << endlog();
@@ -119,17 +122,21 @@ namespace RTT {
                 log(Error) << "in configure(): switching to exception state because of unhandled exception" << endlog();
                 exception();
             }
+#endif
         }
         return false; // no configure when running.
     }
 
     bool TaskCore::cleanup() {
         if ( mTaskState == Stopped ) {
+#ifdef CATCH_EXCEPTION 
             try {
+#endif
                 mTargetState = PreOperational;
                 cleanupHook();
                 mTaskState = PreOperational;
                 return true;
+#ifdef CATCH_EXCEPTION 
             } catch(std::exception const& e) {
                 log(Error) << "in cleanup(): switching to exception state because of unhandled exception" << endlog();
                 log(Error) << "  " << e.what() << endlog();
@@ -138,6 +145,7 @@ namespace RTT {
                 log(Error) << "in cleanup(): switching to exception state because of unhandled exception" << endlog();
                 exception();
             }
+#endif
         }
         return false; // no cleanup when running or not configured.
     }
@@ -159,7 +167,9 @@ namespace RTT {
         //log(Error) <<"Exception happend in TaskCore."<<endlog();
         TaskState copy = mTaskState;
         mTargetState = mTaskState = Exception;
+#ifdef CATCH_EXCEPTION 
         try {
+#endif
             if ( copy >= Running ) {
                 stopHook();
             }
@@ -167,6 +177,7 @@ namespace RTT {
                 cleanupHook();
             }
             exceptionHook();
+#ifdef CATCH_EXCEPTION 
         } catch(std::exception const& e) {
             log(RTT::Error) << "stopHook(), cleanupHook() and/or exceptionHook() raised " << e.what() << ", going into Fatal" << endlog();
             fatal();
@@ -175,6 +186,7 @@ namespace RTT {
             log(Error) << "stopHook(), cleanupHook() and/or exceptionHook() raised an exception, going into Fatal" << endlog();
             fatal();
         }
+#endif
     }
 
     bool TaskCore::recover() {
@@ -191,7 +203,9 @@ namespace RTT {
 
     bool TaskCore::start() {
         if ( mTaskState == Stopped ) {
+#ifdef CATCH_EXCEPTION 
             try {
+#endif
                 mTargetState = Running;
                 if ( startHook() ) {
                     mTaskState = Running;
@@ -199,6 +213,7 @@ namespace RTT {
                     return true;
                 }
                 mTargetState = Stopped;
+#ifdef CATCH_EXCEPTION 
             } catch(std::exception const& e) {
                 log(Error) << "in start(): switching to exception state because of unhandled exception" << endlog();
                 log(Error) << "  " << e.what() << endlog();
@@ -207,6 +222,7 @@ namespace RTT {
                 log(Error) << "in start(): switching to exception state because of unhandled exception" << endlog();
                 exception();
             }
+#endif
         }
         return false;
     }
@@ -214,7 +230,9 @@ namespace RTT {
     bool TaskCore::stop() {
         TaskState orig = mTaskState;
         if ( mTaskState >= Running ) {
+#ifdef CATCH_EXCEPTION 
             try {
+#endif
                 mTargetState = Stopped;
                 if ( engine()->stopTask(this) ) {
                     stopHook();
@@ -224,6 +242,7 @@ namespace RTT {
                     mTaskState = orig;
                     mTargetState = orig;
                 }
+#ifdef CATCH_EXCEPTION 
             } catch(std::exception const& e) {
                 log(Error) << "in stop(): switching to exception state because of unhandled exception" << endlog();
                 log(Error) << "  " << e.what() << endlog();
@@ -232,6 +251,7 @@ namespace RTT {
                 log(Error) << "in stop(): switching to exception state because of unhandled exception" << endlog();
                 exception();
             }
+#endif
         }
         return false;
     }
diff --git a/rtt/os/Thread.cpp b/rtt/os/Thread.cpp
index 1a0159d..d8a5ef0 100644
--- a/rtt/os/Thread.cpp
+++ b/rtt/os/Thread.cpp
@@ -53,13 +53,15 @@
 #define SCOPE_OFF
 #endif
 
-#ifndef ORO_EMBEDDED
+#if !defined(ORO_EMBEDDED) and defined(CATCH_EXCEPTION)
 #define TRY try
 #define CATCH(a) catch(a)
+#define CATCH_CONTEND
 #define CATCH_ALL catch(...)
 #else
 #define TRY
 #define CATCH(a) if (false)
+#define CATCH_CONTEND std::exception const e; 
 #define CATCH_ALL if (false)
 #endif
 
@@ -137,13 +139,12 @@ namespace RTT {
                                 MutexLock lock(task->breaker);
                                 while(task->running && !task->prepareForExit )
                                 {
-                                    try
+                                    TRY 
                                     {
                                         SCOPE_ON
                                         task->step(); // one cycle
                                         SCOPE_OFF
-                                    }
-                                    catch(...)
+                                    } CATCH_ALL 
                                     {
                                         SCOPE_OFF
                                         throw;
@@ -179,7 +180,7 @@ namespace RTT {
                                     break; // break while(1) {}
                             }
                             else // non periodic:
-                            try
+                            TRY 
                             {
                                 // this mutex guarantees that stop() waits
                                 // until loop() returns.
@@ -190,8 +191,8 @@ namespace RTT {
                                 task->loop();
                                 SCOPE_OFF
                                 task->inloop = false;
-                            }
-                            catch(...) {
+                            } CATCH_ALL
+                            {
                                 SCOPE_OFF
                                 task->inloop = false;
                                 throw;
@@ -211,6 +212,7 @@ namespace RTT {
                     }
                 } CATCH(std::exception const& e)
                 {
+                    CATCH_CONTEND
                     SCOPE_OFF
                     task->emergencyStop();
                     Logger::In in(rtos_task_get_name(task->getTask()));
-- 
1.7.10.4

