incremental
diff --git a/g3log/crashhandler_unix.cpp b/g3log/crashhandler_unix.cpp
new file mode 100644
index 0000000..3e1b7fe
--- /dev/null
+++ b/g3log/crashhandler_unix.cpp
@@ -0,0 +1,274 @@
+/** ==========================================================================
+ * 2011 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes
+ * with no warranties. This code is yours to share, use and modify with no
+ * strings attached and no restrictions or obligations.
+ *
+ * For more information see g3log/LICENSE or refer refer to http://unlicense.org
+ * ============================================================================*/
+
+#include "g3log/crashhandler.hpp"
+#include "g3log/logmessage.hpp"
+#include "g3log/logcapture.hpp"
+#include "g3log/loglevels.hpp"
+
+#if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) && !defined(__GNUC__))
+#error "crashhandler_unix.cpp used but it's a windows system"
+#endif
+
+
+#include <csignal>
+#include <cstring>
+#include <unistd.h>
+#include <execinfo.h>
+#include <cxxabi.h>
+#include <cstdlib>
+#include <sstream>
+#include <iostream>
+#include <thread>
+#include <atomic>
+#include <map>
+#include <mutex>
+
+// Linux/Clang, OSX/Clang, OSX/gcc
+#if (defined(__clang__) || defined(__APPLE__))
+#include <sys/ucontext.h>
+#else
+#include <ucontext.h>
+#endif
+
+
+namespace {
+
+   const std::map<int, std::string> kSignals = {
+      {SIGABRT, "SIGABRT"},
+      {SIGFPE, "SIGFPE"},
+      {SIGILL, "SIGILL"},
+      {SIGSEGV, "SIGSEGV"},
+      {SIGTERM, "SIGTERM"},
+   };
+
+   std::map<int, std::string> gSignals = kSignals;
+
+
+   bool shouldDoExit() {
+      static std::atomic<uint64_t> firstExit{0};
+      auto const count = firstExit.fetch_add(1, std::memory_order_relaxed);
+      return (0 == count);
+   }
+
+   void restoreSignalHandler(int signal_number) {
+#if !(defined(DISABLE_FATAL_SIGNALHANDLING))
+      struct sigaction action;
+      memset(&action, 0, sizeof (action)); //
+      sigemptyset(&action.sa_mask);
+      action.sa_handler = SIG_DFL; // take default action for the signal
+      sigaction(signal_number, &action, NULL);
+#endif
+   }
+
+
+   // Dump of stack,. then exit through g3log background worker
+   // ALL thanks to this thread at StackOverflow. Pretty much borrowed from:
+   // Ref: http://stackoverflow.com/questions/77005/how-to-generate-a-stacktrace-when-my-gcc-c-app-crashes
+   void signalHandler(int signal_number, siginfo_t* info, void* unused_context) {
+
+      // Only one signal will be allowed past this point
+      if (false == shouldDoExit()) {
+         while (true) {
+            std::this_thread::sleep_for(std::chrono::seconds(1));
+         }
+      }
+
+      using namespace g3::internal;
+      {
+         const auto dump = stackdump();
+         std::ostringstream fatal_stream;
+         const auto fatal_reason = exitReasonName(g3::internal::FATAL_SIGNAL, signal_number);
+         fatal_stream << "Received fatal signal: " << fatal_reason;
+         fatal_stream << "(" << signal_number << ")\tPID: " << getpid() << std::endl;
+         fatal_stream << "\n***** SIGNAL " << fatal_reason << "(" << signal_number << ")" << std::endl;
+         LogCapture trigger(FATAL_SIGNAL, static_cast<g3::SignalType>(signal_number), dump.c_str());
+         trigger.stream() << fatal_stream.str();
+      } // message sent to g3LogWorker
+      // wait to die
+   }
+
+
+
+   //
+   // Installs FATAL signal handler that is enough to handle most fatal events
+   //  on *NIX systems
+   void installSignalHandler() {
+#if !(defined(DISABLE_FATAL_SIGNALHANDLING))
+      struct sigaction action;
+      memset(&action, 0, sizeof (action));
+      sigemptyset(&action.sa_mask);
+      action.sa_sigaction = &signalHandler; // callback to crashHandler for fatal signals
+      // sigaction to use sa_sigaction file. ref: http://www.linuxprogrammingblog.com/code-examples/sigaction
+      action.sa_flags = SA_SIGINFO;
+
+      // do it verbose style - install all signal actions
+      for (const auto& sig_pair : gSignals) {
+         if (sigaction(sig_pair.first, &action, nullptr) < 0) {
+            const std::string error = "sigaction - " + sig_pair.second;
+            perror(error.c_str());
+         }
+      }
+#endif
+   }
+
+
+
+} // end anonymous namespace
+
+
+
+
+
+
+// Redirecting and using signals. In case of fatal signals g3log should log the fatal signal
+// and flush the log queue and then "rethrow" the signal to exit
+namespace g3 {
+   // References:
+   // sigaction : change the default action if a specific signal is received
+   //             http://linux.die.net/man/2/sigaction
+   //             http://publib.boulder.ibm.com/infocenter/aix/v6r1/index.jsp?topic=%2Fcom.ibm.aix.basetechref%2Fdoc%2Fbasetrf2%2Fsigaction.html
+   //
+   // signal: http://linux.die.net/man/7/signal and
+   //         http://msdn.microsoft.com/en-us/library/xdkz3x12%28vs.71%29.asp
+   //
+   // memset +  sigemptyset: Maybe unnecessary to do both but there seems to be some confusion here
+   //          ,plenty of examples when both or either are used
+   //          http://stackoverflow.com/questions/6878546/why-doesnt-parent-process-return-to-the-exact-location-after-handling-signal_number
+   namespace internal {
+
+      bool shouldBlockForFatalHandling() {
+         return true;  // For windows we will after fatal processing change it to false
+      }
+
+
+      /// Generate stackdump. Or in case a stackdump was pre-generated and non-empty just use that one
+      /// i.e. the latter case is only for Windows and test purposes
+      std::string stackdump(const char* rawdump) {
+         if (nullptr != rawdump && !std::string(rawdump).empty()) {
+            return {rawdump};
+         }
+
+         const size_t max_dump_size = 50;
+         void* dump[max_dump_size];
+         size_t size = backtrace(dump, max_dump_size);
+         char** messages = backtrace_symbols(dump, static_cast<int>(size)); // overwrite sigaction with caller's address
+
+         // dump stack: skip first frame, since that is here
+         std::ostringstream oss;
+         for (size_t idx = 1; idx < size && messages != nullptr; ++idx) {
+            char* mangled_name = 0, *offset_begin = 0, *offset_end = 0;
+            // find parantheses and +address offset surrounding mangled name
+            for (char* p = messages[idx]; *p; ++p) {
+               if (*p == '(') {
+                  mangled_name = p;
+               } else if (*p == '+') {
+                  offset_begin = p;
+               } else if (*p == ')') {
+                  offset_end = p;
+                  break;
+               }
+            }
+
+            // if the line could be processed, attempt to demangle the symbol
+            if (mangled_name && offset_begin && offset_end &&
+                  mangled_name < offset_begin) {
+               *mangled_name++ = '\0';
+               *offset_begin++ = '\0';
+               *offset_end++ = '\0';
+
+               int status;
+               char* real_name = abi::__cxa_demangle(mangled_name, 0, 0, &status);
+               // if demangling is successful, output the demangled function name
+               if (status == 0) {
+                  oss << "\n\tstack dump [" << idx << "]  " << messages[idx] << " : " << real_name << "+";
+                  oss << offset_begin << offset_end << std::endl;
+               }// otherwise, output the mangled function name
+               else {
+                  oss << "\tstack dump [" << idx << "]  " << messages[idx] << mangled_name << "+";
+                  oss << offset_begin << offset_end << std::endl;
+               }
+               free(real_name); // mallocated by abi::__cxa_demangle(...)
+            } else {
+               // no demangling done -- just dump the whole line
+               oss << "\tstack dump [" << idx << "]  " << messages[idx] << std::endl;
+            }
+         } // END: for(size_t idx = 1; idx < size && messages != nullptr; ++idx)
+         free(messages);
+         return oss.str();
+      }
+
+
+
+      /// string representation of signal ID
+      std::string exitReasonName(const LEVELS& level, g3::SignalType fatal_id) {
+
+         int signal_number = static_cast<int>(fatal_id);
+         switch (signal_number) {
+            case SIGABRT: return "SIGABRT";
+               break;
+            case SIGFPE: return "SIGFPE";
+               break;
+            case SIGSEGV: return "SIGSEGV";
+               break;
+            case SIGILL: return "SIGILL";
+               break;
+            case SIGTERM: return "SIGTERM";
+               break;
+            default:
+               std::ostringstream oss;
+               oss << "UNKNOWN SIGNAL(" << signal_number << ") for " << level.text;
+               return oss.str();
+         }
+      }
+
+
+
+      // Triggered by g3log->g3LogWorker after receiving a FATAL trigger
+      // which is LOG(FATAL), CHECK(false) or a fatal signal our signalhandler caught.
+      // --- If LOG(FATAL) or CHECK(false) the signal_number will be SIGABRT
+      void exitWithDefaultSignalHandler(const LEVELS& level, g3::SignalType fatal_signal_id) {
+         const int signal_number = static_cast<int>(fatal_signal_id);
+         restoreSignalHandler(signal_number);
+         std::cerr << "\n\n" << __FUNCTION__ << ":" << __LINE__ << ". Exiting due to " << level.text << ", " << signal_number << "   \n\n" << std::flush;
+
+
+         kill(getpid(), signal_number);
+         exit(signal_number);
+
+      }
+   } // end g3::internal
+
+
+   // This will override the default signal handler setup and instead
+   // install a custom set of signals to handle
+   void overrideSetupSignals(const std::map<int, std::string> overrideSignals) {
+      static std::mutex signalLock;
+      std::lock_guard<std::mutex> guard(signalLock);
+      for (const auto& sig : gSignals) {
+         restoreSignalHandler(sig.first);
+      }
+
+      gSignals = overrideSignals;
+      installCrashHandler(); // installs all the signal handling for gSignals
+   }
+
+   // restores the signal handler back to default
+   void restoreSignalHandlerToDefault() {
+      overrideSetupSignals(kSignals);
+   }
+
+
+   // installs the signal handling for whatever signal set that is currently active
+   // If you want to setup your own signal handling then
+   // You should instead call overrideSetupSignals()
+   void installCrashHandler() {
+      installSignalHandler();
+   }
+} // end namespace g3
+