[PATCH] Exception handling: Added option to disable exception

Matthias Goldhoorn matthias.goldhoorn at dfki.de
Mon Oct 21 08:57:15 CEST 2013


The option could be enabled be setting either the enviorment Variable
RTT_IGNORE_EXCEPTION or be setting the static variable
RTT::m_catch_exception to a positive value.

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/Config.hpp          |   92 +++++++++++++++++++++++++++++++++++++++++++++++
 rtt/ExecutionEngine.cpp |   32 ++++++++---------
 rtt/TaskContext.hpp     |    1 +
 rtt/base/TaskCore.cpp   |   42 +++++++++++-----------
 rtt/os/Thread.cpp       |   46 ++++++++++--------------
 6 files changed, 153 insertions(+), 65 deletions(-)
 create mode 100644 rtt/Config.hpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 912ae83..bf08251 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -91,6 +91,11 @@ IF(BUILD_TESTING)
   MARK_AS_ADVANCED(BUILDNAME)
 ENDIF(BUILD_TESTING)
 
+OPTION(DISABLE_SELECTABLE_EXCEPTIONS "By setting to On, exceptions are catched every time by RTT. This makes RTT a pice faster, but user application debugging harder." OFF)
+if(DISABLE_SELECTABLE_EXCEPTIONS)
+    ADD_DEFINITIONS("-DDISABLE_SELECTABLE_EXCEPTIONS")
+endif()
+
 # turn on code coverage of tests
 include (CMakeDependentOption)
 CMAKE_DEPENDENT_OPTION(BUILD_ENABLE_COVERAGE "Turn on code coverage of all tests." OFF "ENABLE_TESTS" OFF)
diff --git a/rtt/Config.hpp b/rtt/Config.hpp
new file mode 100644
index 0000000..f72db53
--- /dev/null
+++ b/rtt/Config.hpp
@@ -0,0 +1,92 @@
+/***************************************************************************
+  tag: Matthias Goldhoorn  Fri Oct 18 10:00:05 CEST 2013  Config.hpp
+
+                        Config.hpp -  description
+                           -------------------
+    begin                : Fri Oct 18 10:00:05 CEST 2013
+    copyright            : (C) 2013 Matthias Goldhoorn 
+    email                : matthias at goldhoorn.eu
+
+ ***************************************************************************
+ *   This library is free software; you can redistribute it and/or         *
+ *   modify it under the terms of the GNU General Public                   *
+ *   License as published by the Free Software Foundation;                 *
+ *   version 2 of the License.                                             *
+ *                                                                         *
+ *   As a special exception, you may use this file as part of a free       *
+ *   software library without restriction.  Specifically, if other files   *
+ *   instantiate templates or use macros or inline functions from this     *
+ *   file, or you compile this file and link it with other files to        *
+ *   produce an executable, this file does not by itself cause the         *
+ *   resulting executable to be covered by the GNU General Public          *
+ *   License.  This exception does not however invalidate any other        *
+ *   reasons why the executable file might be covered by the GNU General   *
+ *   Public License.                                                       *
+ *                                                                         *
+ *   This library is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
+ *   Lesser General Public License for more details.                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public             *
+ *   License along with this library; if not, write to the Free Software   *
+ *   Foundation, Inc., 59 Temple Place,                                    *
+ *   Suite 330, Boston, MA  02111-1307  USA                                *
+ *                                                                         *
+ ***************************************************************************/
+
+#ifndef ORO_CONFIG_HPP
+#define ORO_CONFIG_HPP
+
+#include <stdlib.h>
+#include "Logger.hpp"
+
+/**
+ * @file Config.hpp
+ */
+
+/**
+ * @brief Contains static global configuration variables and cached entries 
+ *
+ * The Real-Time Toolkit is documented in <a href="../../orocos-manual.html">
+ * The Orocos Real-Time Toolkit Online Manual</a>
+ */
+
+
+#if !defined(ORO_EMBEDDED) 
+# ifndef DISABLE_SELECTABLE_EXCEPTIONS 
+#  define TRY(C) if(::RTT::catch_exception()){C} else try{C} 
+#  define CATCH(T,C) catch(T){C}
+#  define CATCH_ALL(C) catch(...){C}
+# else //Catch Exception the normal way 
+#  define TRY(C) try{C} 
+#  define CATCH(T,C) catch(T){C}
+#  define CATCH_ALL(C) catch(...){C}
+# endif
+#else //Exceptions are not availible at all
+# define TRY(C) C 
+# define CATCH(T,C) 
+# define CATCH_ALL(C)
+#endif
+
+namespace RTT{
+        static int m_catch_exception=-1;
+        inline static bool catch_exception(){
+            if(m_catch_exception == -1){
+                if(getenv("RTT_IGNORE_EXCEPTION")){
+                    m_catch_exception = 1;
+                }else{
+                    m_catch_exception = 0;
+#ifdef DISABLE_SELECTABLE_EXCEPTIONS 
+                    Logger::log() << Logger::Error << "Could not set catching exception to false, because RTT was not built in debug level" << std::endl;
+#else
+                    m_catch_exception = 0;
+#endif
+                    
+                }
+            }
+            return (bool)m_catch_exception;
+        }
+}
+
+#endif
diff --git a/rtt/ExecutionEngine.cpp b/rtt/ExecutionEngine.cpp
index 4bde246..11ab57a 100644
--- a/rtt/ExecutionEngine.cpp
+++ b/rtt/ExecutionEngine.cpp
@@ -328,30 +328,30 @@ 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 ) {
-                try {
+                TRY (
                     taskc->prepareUpdateHook();
                     taskc->updateHook();
-                } catch(std::exception const& e) {
+                ) CATCH(std::exception const& e, 
                     log(Error) << "in updateHook(): switching to exception state because of unhandled exception" << endlog();
                     log(Error) << "  " << e.what() << endlog();
                     taskc->exception();
-                } catch(...){
+               ) CATCH_ALL (
                     log(Error) << "in updateHook(): switching to exception state because of unhandled exception" << endlog();
                     taskc->exception(); // calls stopHook,cleanupHook
-                }
+                )
             }
             // in case start() or updateHook() called error(), this will be called:
             if (  taskc->mTaskState == TaskCore::RunTimeError ) {
-                try {
+                TRY (
                     taskc->errorHook();
-                } catch(std::exception const& e) {
+                ) CATCH(std::exception const& e, 
                     log(Error) << "in errorHook(): switching to exception state because of unhandled exception" << endlog();
                     log(Error) << "  " << e.what() << endlog();
                     taskc->exception();
-                } catch(...){
+               ) CATCH_ALL (
                     log(Error) << "in errorHook(): switching to exception state because of unhandled exception" << endlog();
                     taskc->exception(); // calls stopHook,cleanupHook
-                }
+                )
             }
         }
         if ( !this->getActivity() || ! this->getActivity()->isRunning() ) return;
@@ -359,28 +359,28 @@ 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  )
-                try {
+                TRY (
                     (*it)->prepareUpdateHook();
                     (*it)->updateHook();
-                } catch(std::exception const& e) {
+                ) CATCH(std::exception const& e, 
                     log(Error) << "in updateHook(): switching to exception state because of unhandled exception" << endlog();
                     log(Error) << "  " << e.what() << endlog();
                     (*it)->exception();
-                } catch(...){
+               ) CATCH_ALL (
                     log(Error) << "in updateHook(): switching to exception state because of unhandled exception" << endlog();
                     (*it)->exception(); // calls stopHook,cleanupHook
-                }
+                )
             if (  (*it)->mTaskState == TaskCore::RunTimeError )
-                try {
+                TRY (
                     (*it)->errorHook();
-                } catch(std::exception const& e) {
+                ) CATCH(std::exception const& e, 
                     log(Error) << "in errorHook(): switching to exception state because of unhandled exception" << endlog();
                     log(Error) << "  " << e.what() << endlog();
                     (*it)->exception();
-                } catch(...){
+               ) CATCH_ALL (
                     log(Error) << "in errorHook(): switching to exception state because of unhandled exception" << endlog();
                     (*it)->exception(); // calls stopHook,cleanupHook
-                }
+                )
             if ( !this->getActivity() || ! this->getActivity()->isRunning() ) return;
         }
     }
diff --git a/rtt/TaskContext.hpp b/rtt/TaskContext.hpp
index 3b8a462..cc42370 100644
--- a/rtt/TaskContext.hpp
+++ b/rtt/TaskContext.hpp
@@ -41,6 +41,7 @@
 
 
 #include "rtt-config.h"
+#include "Config.hpp"
 #include "Service.hpp"
 #include "ServiceRequester.hpp"
 #include "DataFlowInterface.hpp"
diff --git a/rtt/base/TaskCore.cpp b/rtt/base/TaskCore.cpp
index 3093583..58bf582 100644
--- a/rtt/base/TaskCore.cpp
+++ b/rtt/base/TaskCore.cpp
@@ -41,6 +41,7 @@
 #include "../ExecutionEngine.hpp"
 #include "ActivityInterface.hpp"
 #include "Logger.hpp"
+#include "Config.hpp"
 
 namespace RTT {
     using namespace detail;
@@ -102,7 +103,7 @@ namespace RTT {
 
     bool TaskCore::configure() {
         if ( mTaskState == Stopped || mTaskState == PreOperational) {
-            try {
+            TRY(
                 mTargetState = Stopped;
                 if (configureHook() ) {
                     mTaskState = Stopped;
@@ -111,33 +112,33 @@ namespace RTT {
                     mTargetState = mTaskState = PreOperational;
                     return false;
                 }
-            } catch(std::exception const& e) {
+             ) CATCH(std::exception const& e, 
                 log(Error) << "in configure(): switching to exception state because of unhandled exception" << endlog();
                 log(Error) << "  " << e.what() << endlog();
                 exception();
-            } catch(...) {
+             ) CATCH_ALL( 
                 log(Error) << "in configure(): switching to exception state because of unhandled exception" << endlog();
                 exception();
-            }
+             )
         }
         return false; // no configure when running.
     }
 
     bool TaskCore::cleanup() {
         if ( mTaskState == Stopped ) {
-            try {
+            TRY(
                 mTargetState = PreOperational;
                 cleanupHook();
                 mTaskState = PreOperational;
                 return true;
-            } catch(std::exception const& e) {
+             ) CATCH(std::exception const& e,
                 log(Error) << "in cleanup(): switching to exception state because of unhandled exception" << endlog();
                 log(Error) << "  " << e.what() << endlog();
                 exception();
-            } catch (...) {
+             ) CATCH_ALL (
                 log(Error) << "in cleanup(): switching to exception state because of unhandled exception" << endlog();
                 exception();
-            }
+             ) 
         }
         return false; // no cleanup when running or not configured.
     }
@@ -159,7 +160,7 @@ namespace RTT {
         //log(Error) <<"Exception happend in TaskCore."<<endlog();
         TaskState copy = mTaskState;
         mTargetState = mTaskState = Exception;
-        try {
+        TRY (
             if ( copy >= Running ) {
                 stopHook();
             }
@@ -167,14 +168,13 @@ namespace RTT {
                 cleanupHook();
             }
             exceptionHook();
-        } catch(std::exception const& e) {
+        ) CATCH(std::exception const& e, 
             log(RTT::Error) << "stopHook(), cleanupHook() and/or exceptionHook() raised " << e.what() << ", going into Fatal" << endlog();
             fatal();
-        }
-        catch (...) {
+        ) CATCH_ALL ( 
             log(Error) << "stopHook(), cleanupHook() and/or exceptionHook() raised an exception, going into Fatal" << endlog();
             fatal();
-        }
+        )
     }
 
     bool TaskCore::recover() {
@@ -191,7 +191,7 @@ namespace RTT {
 
     bool TaskCore::start() {
         if ( mTaskState == Stopped ) {
-            try {
+            TRY (
                 mTargetState = Running;
                 if ( startHook() ) {
                     mTaskState = Running;
@@ -199,14 +199,14 @@ namespace RTT {
                     return true;
                 }
                 mTargetState = Stopped;
-            } catch(std::exception const& e) {
+            ) CATCH(std::exception const& e, 
                 log(Error) << "in start(): switching to exception state because of unhandled exception" << endlog();
                 log(Error) << "  " << e.what() << endlog();
                 exception();
-            } catch (...) {
+            ) CATCH_ALL (
                 log(Error) << "in start(): switching to exception state because of unhandled exception" << endlog();
                 exception();
-            }
+            )
         }
         return false;
     }
@@ -214,7 +214,7 @@ namespace RTT {
     bool TaskCore::stop() {
         TaskState orig = mTaskState;
         if ( mTaskState >= Running ) {
-            try {
+            TRY(
                 mTargetState = Stopped;
                 if ( engine()->stopTask(this) ) {
                     stopHook();
@@ -224,14 +224,14 @@ namespace RTT {
                     mTaskState = orig;
                     mTargetState = orig;
                 }
-            } catch(std::exception const& e) {
+            ) CATCH(std::exception const& e, 
                 log(Error) << "in stop(): switching to exception state because of unhandled exception" << endlog();
                 log(Error) << "  " << e.what() << endlog();
                 exception();
-            } catch (...) {
+            ) CATCH_ALL (
                 log(Error) << "in stop(): switching to exception state because of unhandled exception" << endlog();
                 exception();
-            }
+            )
         }
         return false;
     }
diff --git a/rtt/os/Thread.cpp b/rtt/os/Thread.cpp
index 1a0159d..2258963 100644
--- a/rtt/os/Thread.cpp
+++ b/rtt/os/Thread.cpp
@@ -43,6 +43,7 @@
 #include "MutexLock.hpp"
 
 #include "../rtt-config.h"
+#include "../Config.hpp"
 
 #ifdef OROPKG_OS_THREAD_SCOPE
 # include "../extras/dev/DigitalOutInterface.hpp"
@@ -53,16 +54,6 @@
 #define SCOPE_OFF
 #endif
 
-#ifndef ORO_EMBEDDED
-#define TRY try
-#define CATCH(a) catch(a)
-#define CATCH_ALL catch(...)
-#else
-#define TRY
-#define CATCH(a) if (false)
-#define CATCH_ALL if (false)
-#endif
-
 namespace RTT {
     namespace os
     {
@@ -106,8 +97,7 @@ namespace RTT {
 
             while (!task->prepareForExit)
             {
-                TRY
-                {
+                TRY( 
                     /**
                      * The real task starts here.
                      */
@@ -137,17 +127,17 @@ 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;
-                                    }
+                                    )
 
                                     // Check changes in period
                                     if ( cur_period != task->period) {
@@ -179,8 +169,8 @@ namespace RTT {
                                     break; // break while(1) {}
                             }
                             else // non periodic:
-                            try
-                            {
+                            TRY 
+                            ( 
                                 // this mutex guarantees that stop() waits
                                 // until loop() returns.
                                 MutexLock lock(task->breaker);
@@ -190,12 +180,12 @@ namespace RTT {
                                 task->loop();
                                 SCOPE_OFF
                                 task->inloop = false;
-                            }
-                            catch(...) {
+                            ) CATCH_ALL
+                            (
                                 SCOPE_OFF
                                 task->inloop = false;
                                 throw;
-                            }
+                            )
                         }
                     } // while(1)
                     if (overruns == task->maxOverRun)
@@ -209,8 +199,8 @@ namespace RTT {
                         log()   << " See Thread::setMaxOverrun() for info."
                                 << endlog();
                     }
-                } CATCH(std::exception const& e)
-                {
+                )CATCH(std::exception const& e,
+                
                     SCOPE_OFF
                     task->emergencyStop();
                     Logger::In in(rtos_task_get_name(task->getTask()));
@@ -219,15 +209,15 @@ namespace RTT {
                             << endlog();
                     log(Critical) << "exception was: "
                                << e.what() << endlog();
-                } CATCH_ALL
-                {
+                ) CATCH_ALL
+                (
                     SCOPE_OFF
                     task->emergencyStop();
                     Logger::In in(rtos_task_get_name(task->getTask()));
                     log(Critical) << rtos_task_get_name(task->getTask())
                             << " caught an unknown C++ exception, stopped thread !"
                             << endlog();
-                }
+                )
             } // while (!prepareForExit)
 
             return 0;
-- 
1.7.10.4


--------------020703040602010109030908--


More information about the Rock-dev mailing list