Re: [Rock-dev] [PATCH] RTT: Added way to disable exception catching

Matthias Goldhoorn <[email protected]>
Newsgroups gmane.science.robotics.orocos.devel
Organization University of Bremen
Message-ID <[email protected]>
On 18.10.2013 14:00, Matthias Goldhoorn wrote:
> On 17.10.2013 15:15, Sylvain Joyeux wrote:
>> On 10/17/2013 03:00 PM, Matthias Goldhoorn wrote:
>>> Please find attached a patch that could make the debuggers/developers
>>> life much easier.
>>> suggestions are welcome.
>> I don't like the idea of using a compile-time flag. We should not have
>> to rebuild the complete stack each time we want to turn it on.
>>
>> A global flag on the RTT namespace, set automatically using an
>> environment variable would look a lot better to me
>>
> I changed the patch, that in release build the normal behaviour is 
> active.
> On Debug build level, the env export RTT_IGNORE_EXCEPTION could be set 
> and exceptions rising up...
>
> Suggestions?
>
> Matthias

After a personal Discussion with Sylvain here my current (hopefully 
final) patch attached.
Sylvain Requested that the enabling of the new handling becomes 
independent of the debug level of RTT.
I added a new define and cmake option for this now.

Greetings,
Matthias

>
>
>


-- 
  Dipl.-Inf. Matthias Goldhoorn
  Space and Underwater Robotic

  Universität Bremen
  FB 3 - Mathematik und Informatik
  AG Robotik
  Robert-Hooke-Straße 5
  28359 Bremen, Germany

  Tel.:     +49 421 178 45-4193
  Zentrale: +49 421 178 45-6550
  Fax:      +49 421 178 45-4150
  E-Mail:   [email protected]

  Weitere Informationen: http://www.informatik.uni-bremen.de/robotik

-- 
Orocos-Dev mailing list
[email protected]
http://lists.mech.kuleuven.be/mailman/listinfo/orocos-dev
0001-Exception-handling-Added-option-to-disable-exception.patch (text/x-patch, 19.4 KB)
>From fa36a02ac893b2950567ebd539939964413fadb9 Mon Sep 17 00:00:00 2001
From: Matthias Goldhoorn <[email protected]>
Date: Mon, 21 Oct 2013 08:57:15 +0200
Subject: [PATCH] Exception handling: Added option to disable exception

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                : [email protected]
+
+ ***************************************************************************
+ *   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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.