Added signal handlers (and placeholder for SEH handlers)
- based on PR 232 (https://github.com/philsquared/Catch/pull/232 - thanks Lukasz Forynski)
- Writes to reporter, so gets all the usual context, but then exits directly (since the stack cannot be resumed) so no summary
- On Windows does nothing, as yet.
diff --git a/include/internal/catch_fatal_condition.hpp b/include/internal/catch_fatal_condition.hpp
new file mode 100644
index 0000000..08c4dcc
--- /dev/null
+++ b/include/internal/catch_fatal_condition.hpp
@@ -0,0 +1,78 @@
+/*
+ *  Created by Phil on 21/08/2014
+ *  Copyright 2014 Two Blue Cubes Ltd. All rights reserved.
+ *
+ *  Distributed under the Boost Software License, Version 1.0. (See accompanying
+ *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ */
+#ifndef TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
+#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
+
+
+namespace Catch {
+
+    // Report the error condition then exit the process
+    inline void fatal( std::string const& message, int exitCode ) {
+        IContext& context = Catch::getCurrentContext();
+        IResultCapture* resultCapture = context.getResultCapture();
+        ResultBuilder resultBuilder = resultCapture->makeUnexpectedResultBuilder();
+        resultBuilder.setResultType( ResultWas::FatalErrorCondition );
+        resultBuilder << message;
+        resultBuilder.captureExpression();
+        
+		if( Catch::alwaysTrue() ) // avoids "no return" warnings
+            exit( exitCode );
+    }
+
+} // namespace Catch
+
+#if defined ( CATCH_PLATFORM_WINDOWS ) /////////////////////////////////////////
+
+namespace Catch {
+
+    struct FatalConditionHandler {};
+
+} // namespace Catch
+
+#else // Not Windows - assumed to be POSIX compatible //////////////////////////
+
+#include <signal.h>
+
+namespace Catch {
+
+    struct SignalDefs { int id; const char* name; };
+    extern SignalDefs signalDefs[];
+    SignalDefs signalDefs[] = {
+            { SIGINT,  "SIGINT - Terminal interrupt signal" },
+            { SIGILL,  "SIGILL - Illegal instruction signal" },
+            { SIGFPE,  "SIGFPE - Floating point error signal" },
+            { SIGSEGV, "SIGSEGV - Segmentation violation signal" },
+            { SIGTERM, "SIGTERM - Termination request signal" },
+            { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" }
+        };
+
+    struct FatalConditionHandler {
+
+        static void handleSignal( int sig ) {
+            for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
+                if( sig == signalDefs[i].id )
+                    fatal( signalDefs[i].name, -sig );
+            fatal( "<unknown signal>", -sig );
+        }
+
+        FatalConditionHandler() {
+            for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
+                signal( signalDefs[i].id, handleSignal );
+        }
+        ~FatalConditionHandler() {
+            for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i )
+                signal( signalDefs[i].id, SIG_DFL );
+        }
+    };
+
+} // namespace Catch
+
+#endif // not Windows
+
+#endif // TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED
diff --git a/include/internal/catch_interfaces_capture.h b/include/internal/catch_interfaces_capture.h
index 6565f0e..b9d1e87 100644
--- a/include/internal/catch_interfaces_capture.h
+++ b/include/internal/catch_interfaces_capture.h
@@ -21,6 +21,7 @@
     struct MessageInfo;
     class ScopedMessageBuilder;
     struct Counts;
+    class ResultBuilder;
 
     struct IResultCapture {
 
@@ -35,6 +36,8 @@
 
         virtual std::string getCurrentTestName() const = 0;
         virtual const AssertionResult* getLastResult() const = 0;
+
+        virtual ResultBuilder makeUnexpectedResultBuilder() const = 0;
     };
 
     IResultCapture& getResultCapture();
diff --git a/include/internal/catch_result_type.h b/include/internal/catch_result_type.h
index ce00ef0..31ad3e6 100644
--- a/include/internal/catch_result_type.h
+++ b/include/internal/catch_result_type.h
@@ -25,7 +25,9 @@
         Exception = 0x100 | FailureBit,
 
         ThrewException = Exception | 1,
-        DidntThrowException = Exception | 2
+        DidntThrowException = Exception | 2,
+
+        FatalErrorCondition = 0x200 | FailureBit
 
     }; };
 
diff --git a/include/internal/catch_runner_impl.hpp b/include/internal/catch_runner_impl.hpp
index fa4f319..47b2e2b 100644
--- a/include/internal/catch_runner_impl.hpp
+++ b/include/internal/catch_runner_impl.hpp
@@ -20,6 +20,7 @@
 #include "catch_test_case_tracker.hpp"
 #include "catch_timer.h"
 #include "catch_result_builder.h"
+#include "catch_fatal_condition.hpp"
 
 #include <set>
 #include <string>
@@ -215,6 +216,13 @@
             return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() );
         }
 
+        virtual ResultBuilder makeUnexpectedResultBuilder() const {
+            return ResultBuilder(   m_lastAssertionInfo.macroName.c_str(),
+                                    m_lastAssertionInfo.lineInfo,
+                                    m_lastAssertionInfo.capturedExpression.c_str(),
+                                    m_lastAssertionInfo.resultDisposition );
+        }
+
     private:
 
         void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) {
@@ -232,10 +240,10 @@
                 if( m_reporter->getPreferences().shouldRedirectStdOut ) {
                     StreamRedirect coutRedir( std::cout, redirectedCout );
                     StreamRedirect cerrRedir( std::cerr, redirectedCerr );
-                    m_activeTestCase->invoke();
+                    invokeActiveTestCase();
                 }
                 else {
-                    m_activeTestCase->invoke();
+                    invokeActiveTestCase();
                 }
                 duration = timer.getElapsedSeconds();
             }
@@ -243,11 +251,7 @@
                 // This just means the test was aborted due to failure
             }
             catch(...) {
-                ResultBuilder exResult( m_lastAssertionInfo.macroName.c_str(),
-                                        m_lastAssertionInfo.lineInfo,
-                                        m_lastAssertionInfo.capturedExpression.c_str(),
-                                        m_lastAssertionInfo.resultDisposition );
-                exResult.useActiveException();
+                makeUnexpectedResultBuilder().useActiveException();
             }
             // If sections ended prematurely due to an exception we stored their
             // infos here so we can tear them down outside the unwind process.
@@ -272,6 +276,11 @@
             m_reporter->sectionEnded( testCaseSectionStats );
         }
 
+        void invokeActiveTestCase() {
+            FatalConditionHandler fatalConditionHandler; // Handle signals
+            m_activeTestCase->invoke();
+        }
+
     private:
         struct UnfinishedSections {
             UnfinishedSections( SectionInfo const& _info, Counts const& _prevAssertions, double _durationInSeconds )
diff --git a/include/reporters/catch_reporter_compact.hpp b/include/reporters/catch_reporter_compact.hpp
index 7a6353e..a5a1729 100644
--- a/include/reporters/catch_reporter_compact.hpp
+++ b/include/reporters/catch_reporter_compact.hpp
@@ -109,6 +109,13 @@
                         printExpressionWas();
                         printRemainingMessages();
                         break;
+                    case ResultWas::FatalErrorCondition:
+                        printResultType( Colour::Error, failedString() );
+                        printIssue( "fatal error condition with message:" );
+                        printMessage();
+                        printExpressionWas();
+                        printRemainingMessages();
+                        break;
                     case ResultWas::DidntThrowException:
                         printResultType( Colour::Error, failedString() );
                         printIssue( "expected exception, got none" );
diff --git a/include/reporters/catch_reporter_console.hpp b/include/reporters/catch_reporter_console.hpp
index 7246d32..8349832 100644
--- a/include/reporters/catch_reporter_console.hpp
+++ b/include/reporters/catch_reporter_console.hpp
@@ -149,6 +149,11 @@
                         passOrFail = "FAILED";
                         messageLabel = "due to unexpected exception with message";
                         break;
+                    case ResultWas::FatalErrorCondition:
+                        colour = Colour::Error;
+                        passOrFail = "FAILED";
+                        messageLabel = "due to a fatal error condition";
+                        break;
                     case ResultWas::DidntThrowException:
                         colour = Colour::Error;
                         passOrFail = "FAILED";
diff --git a/include/reporters/catch_reporter_junit.hpp b/include/reporters/catch_reporter_junit.hpp
index 63f7e14..1108794 100644
--- a/include/reporters/catch_reporter_junit.hpp
+++ b/include/reporters/catch_reporter_junit.hpp
@@ -168,6 +168,7 @@
                 std::string elementName;
                 switch( result.getResultType() ) {
                     case ResultWas::ThrewException:
+                    case ResultWas::FatalErrorCondition:
                         elementName = "error";
                         break;
                     case ResultWas::ExplicitFailure:
diff --git a/include/reporters/catch_reporter_xml.hpp b/include/reporters/catch_reporter_xml.hpp
index aa2cfed..4687471 100644
--- a/include/reporters/catch_reporter_xml.hpp
+++ b/include/reporters/catch_reporter_xml.hpp
@@ -108,6 +108,13 @@
                         .writeText( assertionResult.getMessage() );
                     m_currentTestSuccess = false;
                     break;
+                case ResultWas::FatalErrorCondition:
+                    m_xml.scopedElement( "Fatal Error Condition" )
+                        .writeAttribute( "filename", assertionResult.getSourceInfo().file )
+                        .writeAttribute( "line", assertionResult.getSourceInfo().line )
+                        .writeText( assertionResult.getMessage() );
+                    m_currentTestSuccess = false;
+                    break;
                 case ResultWas::Info:
                     m_xml.scopedElement( "Info" )
                         .writeText( assertionResult.getMessage() );
diff --git a/projects/SelfTest/MiscTests.cpp b/projects/SelfTest/MiscTests.cpp
index b229c76..49cfcf6 100644
--- a/projects/SelfTest/MiscTests.cpp
+++ b/projects/SelfTest/MiscTests.cpp
@@ -380,3 +380,9 @@
 	std::string result = Catch::toString( s );
 	CHECK( result == "\"wide load\"" );
 }
+
+TEST_CASE( "Divide by Zero signal handler", "[.][sig]" ) {
+    int i = 0;
+    int x = 10/i; // This should cause the signal to fire
+    CHECK( x == 0 );
+}
diff --git a/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj b/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj
index 31fc525..d0420a7 100644
--- a/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj
+++ b/projects/XCode/CatchSelfTest/CatchSelfTest.xcodeproj/project.pbxproj
@@ -66,6 +66,7 @@
 		2627F7061935B55F009BCE2D /* catch_result_builder.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_result_builder.hpp; sourceTree = "<group>"; };
 		262E7399184673A800CAC268 /* catch_reporter_bases.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_reporter_bases.hpp; sourceTree = "<group>"; };
 		262E739A1846759000CAC268 /* catch_common.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_common.hpp; sourceTree = "<group>"; };
+		263F7A4519A66608009474C2 /* catch_fatal_condition.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = catch_fatal_condition.hpp; sourceTree = "<group>"; };
 		263FD06017AF8DF200988A20 /* catch_timer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_timer.hpp; sourceTree = "<group>"; };
 		263FD06117AF8DF200988A20 /* catch_timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = catch_timer.h; sourceTree = "<group>"; };
 		2656C21F1925E5100040DB02 /* catch_test_spec_parser.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = catch_test_spec_parser.hpp; sourceTree = "<group>"; };
@@ -453,6 +454,7 @@
 				268F47B018A93F7800D8C14F /* catch_clara.h */,
 				2656C226192A77EF0040DB02 /* catch_suppress_warnings.h */,
 				2656C227192A78410040DB02 /* catch_reenable_warnings.h */,
+				263F7A4519A66608009474C2 /* catch_fatal_condition.hpp */,
 			);
 			name = Infrastructure;
 			sourceTree = "<group>";