>From ad35a35561e4bf58c5a0bc410ef115c5a2c79804 Mon Sep 17 00:00:00 2001 From: Matthias Goldhoorn Date: Thu, 17 Oct 2013 14:58:28 +0200 Subject: [PATCH] Exception handling: Added option to disable exception 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/ExecutionEngine.cpp | 16 ++++++++++++++++ rtt/base/TaskCore.cpp | 20 ++++++++++++++++++++ rtt/os/Thread.cpp | 16 +++++++++------- 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 912ae83..fdda247 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,6 +79,11 @@ endif( NOT OROCOS_SUFFIX ) # # ################################################### +OPTION(CATCH_EXCEPTION "Should RTT Catch Exceptions? Disable for debugging only." ON) +if(CATCH_EXCEPTION) + ADD_DEFINITIONS("-DCATCH_EXCEPTION") +endif() + OPTION(ENABLE_TESTS "Turn on to enable the testing framework." OFF) SET(BUILD_TEST_TIMEOUT 1500 CACHE STRING "Global timeout on all tests (seconds).") IF(ENABLE_TESTS) diff --git a/rtt/ExecutionEngine.cpp b/rtt/ExecutionEngine.cpp index 4bde246..a53b1fa 100644 --- a/rtt/ExecutionEngine.cpp +++ b/rtt/ExecutionEngine.cpp @@ -328,9 +328,12 @@ 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 ) { +#ifdef CATCH_EXCEPTION try { +#endif taskc->prepareUpdateHook(); taskc->updateHook(); +#ifdef CATCH_EXCEPTION } catch(std::exception const& e) { log(Error) << "in updateHook(): switching to exception state because of unhandled exception" << endlog(); log(Error) << " " << e.what() << endlog(); @@ -339,11 +342,15 @@ namespace RTT log(Error) << "in updateHook(): switching to exception state because of unhandled exception" << endlog(); taskc->exception(); // calls stopHook,cleanupHook } +#endif } // in case start() or updateHook() called error(), this will be called: if ( taskc->mTaskState == TaskCore::RunTimeError ) { +#ifdef CATCH_EXCEPTION try { +#endif taskc->errorHook(); +#ifdef CATCH_EXCEPTION } catch(std::exception const& e) { log(Error) << "in errorHook(): switching to exception state because of unhandled exception" << endlog(); log(Error) << " " << e.what() << endlog(); @@ -352,6 +359,7 @@ namespace RTT log(Error) << "in errorHook(): switching to exception state because of unhandled exception" << endlog(); taskc->exception(); // calls stopHook,cleanupHook } +#endif } } if ( !this->getActivity() || ! this->getActivity()->isRunning() ) return; @@ -359,9 +367,12 @@ namespace RTT // call all children as well. for (std::vector::iterator it = children.begin(); it != children.end();++it) { if ( (*it)->mTaskState == TaskCore::Running && (*it)->mTargetState == TaskCore::Running ) +#ifdef CATCH_EXCEPTION try { +#endif (*it)->prepareUpdateHook(); (*it)->updateHook(); +#ifdef CATCH_EXCEPTION } catch(std::exception const& e) { log(Error) << "in updateHook(): switching to exception state because of unhandled exception" << endlog(); log(Error) << " " << e.what() << endlog(); @@ -370,9 +381,13 @@ namespace RTT log(Error) << "in updateHook(): switching to exception state because of unhandled exception" << endlog(); (*it)->exception(); // calls stopHook,cleanupHook } +#endif if ( (*it)->mTaskState == TaskCore::RunTimeError ) +#ifdef CATCH_EXCEPTION try { +#endif (*it)->errorHook(); +#ifdef CATCH_EXCEPTION } catch(std::exception const& e) { log(Error) << "in errorHook(): switching to exception state because of unhandled exception" << endlog(); log(Error) << " " << e.what() << endlog(); @@ -381,6 +396,7 @@ namespace RTT log(Error) << "in errorHook(): switching to exception state because of unhandled exception" << endlog(); (*it)->exception(); // calls stopHook,cleanupHook } +#endif if ( !this->getActivity() || ! this->getActivity()->isRunning() ) return; } } diff --git a/rtt/base/TaskCore.cpp b/rtt/base/TaskCore.cpp index 3093583..2f8a0e3 100644 --- a/rtt/base/TaskCore.cpp +++ b/rtt/base/TaskCore.cpp @@ -102,7 +102,9 @@ namespace RTT { bool TaskCore::configure() { if ( mTaskState == Stopped || mTaskState == PreOperational) { +#ifdef CATCH_EXCEPTION try { +#endif mTargetState = Stopped; if (configureHook() ) { mTaskState = Stopped; @@ -111,6 +113,7 @@ namespace RTT { mTargetState = mTaskState = PreOperational; return false; } +#ifdef CATCH_EXCEPTION } catch(std::exception const& e) { log(Error) << "in configure(): switching to exception state because of unhandled exception" << endlog(); log(Error) << " " << e.what() << endlog(); @@ -119,17 +122,21 @@ namespace RTT { log(Error) << "in configure(): switching to exception state because of unhandled exception" << endlog(); exception(); } +#endif } return false; // no configure when running. } bool TaskCore::cleanup() { if ( mTaskState == Stopped ) { +#ifdef CATCH_EXCEPTION try { +#endif mTargetState = PreOperational; cleanupHook(); mTaskState = PreOperational; return true; +#ifdef CATCH_EXCEPTION } catch(std::exception const& e) { log(Error) << "in cleanup(): switching to exception state because of unhandled exception" << endlog(); log(Error) << " " << e.what() << endlog(); @@ -138,6 +145,7 @@ namespace RTT { log(Error) << "in cleanup(): switching to exception state because of unhandled exception" << endlog(); exception(); } +#endif } return false; // no cleanup when running or not configured. } @@ -159,7 +167,9 @@ namespace RTT { //log(Error) <<"Exception happend in TaskCore."<= Running ) { stopHook(); } @@ -167,6 +177,7 @@ namespace RTT { cleanupHook(); } exceptionHook(); +#ifdef CATCH_EXCEPTION } catch(std::exception const& e) { log(RTT::Error) << "stopHook(), cleanupHook() and/or exceptionHook() raised " << e.what() << ", going into Fatal" << endlog(); fatal(); @@ -175,6 +186,7 @@ namespace RTT { log(Error) << "stopHook(), cleanupHook() and/or exceptionHook() raised an exception, going into Fatal" << endlog(); fatal(); } +#endif } bool TaskCore::recover() { @@ -191,7 +203,9 @@ namespace RTT { bool TaskCore::start() { if ( mTaskState == Stopped ) { +#ifdef CATCH_EXCEPTION try { +#endif mTargetState = Running; if ( startHook() ) { mTaskState = Running; @@ -199,6 +213,7 @@ namespace RTT { return true; } mTargetState = Stopped; +#ifdef CATCH_EXCEPTION } catch(std::exception const& e) { log(Error) << "in start(): switching to exception state because of unhandled exception" << endlog(); log(Error) << " " << e.what() << endlog(); @@ -207,6 +222,7 @@ namespace RTT { log(Error) << "in start(): switching to exception state because of unhandled exception" << endlog(); exception(); } +#endif } return false; } @@ -214,7 +230,9 @@ namespace RTT { bool TaskCore::stop() { TaskState orig = mTaskState; if ( mTaskState >= Running ) { +#ifdef CATCH_EXCEPTION try { +#endif mTargetState = Stopped; if ( engine()->stopTask(this) ) { stopHook(); @@ -224,6 +242,7 @@ namespace RTT { mTaskState = orig; mTargetState = orig; } +#ifdef CATCH_EXCEPTION } catch(std::exception const& e) { log(Error) << "in stop(): switching to exception state because of unhandled exception" << endlog(); log(Error) << " " << e.what() << endlog(); @@ -232,6 +251,7 @@ namespace RTT { log(Error) << "in stop(): switching to exception state because of unhandled exception" << endlog(); exception(); } +#endif } return false; } diff --git a/rtt/os/Thread.cpp b/rtt/os/Thread.cpp index 1a0159d..d8a5ef0 100644 --- a/rtt/os/Thread.cpp +++ b/rtt/os/Thread.cpp @@ -53,13 +53,15 @@ #define SCOPE_OFF #endif -#ifndef ORO_EMBEDDED +#if !defined(ORO_EMBEDDED) and defined(CATCH_EXCEPTION) #define TRY try #define CATCH(a) catch(a) +#define CATCH_CONTEND #define CATCH_ALL catch(...) #else #define TRY #define CATCH(a) if (false) +#define CATCH_CONTEND std::exception const e; #define CATCH_ALL if (false) #endif @@ -137,13 +139,12 @@ 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; @@ -179,7 +180,7 @@ namespace RTT { break; // break while(1) {} } else // non periodic: - try + TRY { // this mutex guarantees that stop() waits // until loop() returns. @@ -190,8 +191,8 @@ namespace RTT { task->loop(); SCOPE_OFF task->inloop = false; - } - catch(...) { + } CATCH_ALL + { SCOPE_OFF task->inloop = false; throw; @@ -211,6 +212,7 @@ namespace RTT { } } CATCH(std::exception const& e) { + CATCH_CONTEND SCOPE_OFF task->emergencyStop(); Logger::In in(rtos_task_get_name(task->getTask())); -- 1.7.10.4