[PATCH] Exception handling: Added option to disable exception
Matthias Goldhoorn
matthias.goldhoorn at dfki.de
Fri Oct 25 08:38:28 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.
---
rtt/CatchConfig.cpp | 39 +++++++++++++++++++++++
rtt/CatchConfig.hpp | 79 +++++++++++++++++++++++++++++++++++++++++++++++
rtt/ExecutionEngine.cpp | 39 ++++++++++++-----------
rtt/base/TaskCore.cpp | 42 ++++++++++++-------------
rtt/os/Thread.cpp | 45 ++++++++++-----------------
5 files changed, 177 insertions(+), 67 deletions(-)
create mode 100644 rtt/CatchConfig.cpp
create mode 100644 rtt/CatchConfig.hpp
diff --git a/rtt/CatchConfig.cpp b/rtt/CatchConfig.cpp
new file mode 100644
index 0000000..f50e966
--- /dev/null
+++ b/rtt/CatchConfig.cpp
@@ -0,0 +1,39 @@
+/***************************************************************************
+ tag: Matthias Goldhoorn Fri Oct 18 10:00:05 CEST 2013 Config.hpp
+
+ Config.cpp - 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 *
+ * *
+ ***************************************************************************/
+
+#include <CatchConfig.hpp>
+int RTT::m_catch_exception=-1;
diff --git a/rtt/CatchConfig.hpp b/rtt/CatchConfig.hpp
new file mode 100644
index 0000000..237bed1
--- /dev/null
+++ b/rtt/CatchConfig.hpp
@@ -0,0 +1,79 @@
+/***************************************************************************
+ tag: Matthias Goldhoorn Fri Oct 18 10:00:05 CEST 2013 Config.hpp
+
+ CatchConfig.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_CATCHCONFIG_HPP
+#define ORO_CATCHCONFIG_HPP
+
+#include <stdlib.h>
+
+/**
+ * @file CatchConfig.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)
+# 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 //Exceptions are not availible at all
+# define TRY(C) C
+# define CATCH(T,C)
+# define CATCH_ALL(C)
+#endif
+
+namespace RTT{
+ extern int m_catch_exception;
+ inline bool catch_exception(){
+ if(m_catch_exception == -1){
+ if(getenv("RTT_IGNORE_EXCEPTION")){
+ m_catch_exception = 1;
+ }else{
+ m_catch_exception = 0;
+ }
+ }
+ return (bool)m_catch_exception;
+ }
+}
+
+#endif
diff --git a/rtt/ExecutionEngine.cpp b/rtt/ExecutionEngine.cpp
index 4bde246..0ca2d6b 100644
--- a/rtt/ExecutionEngine.cpp
+++ b/rtt/ExecutionEngine.cpp
@@ -44,6 +44,7 @@
#include "os/MutexLock.hpp"
#include "internal/MWSRQueue.hpp"
#include "TaskContext.hpp"
+#include "CatchConfig.hpp"
#include <boost/bind.hpp>
#include <boost/ref.hpp>
@@ -328,59 +329,61 @@ 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;
// 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 {
+ if ( (*it)->mTaskState == TaskCore::Running && (*it)->mTargetState == TaskCore::Running ){
+ 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 {
+ )
+ }
+ if ( (*it)->mTaskState == TaskCore::RunTimeError ){
+ 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/base/TaskCore.cpp b/rtt/base/TaskCore.cpp
index 3093583..ab32b60 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 "CatchConfig.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..9e6fe48 100644
--- a/rtt/os/Thread.cpp
+++ b/rtt/os/Thread.cpp
@@ -43,6 +43,7 @@
#include "MutexLock.hpp"
#include "../rtt-config.h"
+#include "../CatchConfig.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,7 @@ 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 +208,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
--------------090503000504060308030609--
More information about the Rock-dev
mailing list