[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