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 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 -- 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, 18.6 KB)
>From f43abf9e887ac0b50178deb535d5609d2ae33217 Mon Sep 17 00:00:00 2001 From: Matthias Goldhoorn <[email protected]> Date: Fri, 18 Oct 2013 13:58:12 +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. --- rtt/Config.hpp | 90 +++++++++++++++++++++++++++++++++++++++++++++++ rtt/ExecutionEngine.cpp | 32 ++++++++--------- rtt/TaskContext.hpp | 1 + rtt/base/TaskCore.cpp | 42 +++++++++++----------- rtt/os/Thread.cpp | 46 ++++++++++-------------- 5 files changed, 146 insertions(+), 65 deletions(-) create mode 100644 rtt/Config.hpp diff --git a/rtt/Config.hpp b/rtt/Config.hpp new file mode 100644 index 0000000..0ae392b --- /dev/null +++ b/rtt/Config.hpp @@ -0,0 +1,90 @@ +/*************************************************************************** + 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 NDEBUG +# 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 //Debug is Off, handle Exceptions every time +# 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 NDEBUG + Logger::log() << Logger::Error << "Could not set catching exception to false, because RTT was not built in debug level" << std::endl; +#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