diff --git a/miosix/config/miosix_settings.h b/miosix/config/miosix_settings.h
index e48e39e79e57ce6e4521617512f5a3530a94f0b8..4a55c651ba2ba60a07c5d58fd5e6f4ff81222499 100644
--- a/miosix/config/miosix_settings.h
+++ b/miosix/config/miosix_settings.h
@@ -251,6 +251,23 @@ const unsigned char MAIN_PRIORITY=1;
 const unsigned int MAX_TIME_SLICE=1000000;
 #endif //SCHED_TYPE_PRIORITY
 
+/// pthread_exit() is a dangerous function. To understand why, let's first
+/// discuss how Linux implements it. On the surface, it looks like it neatly
+/// works with C++ as it is implemented by throwing a special ForcedUnwind
+/// exception thus calling C++ destructors. However, implementers left a number
+/// of unhandled corner cases all leading to unexpected program termination.
+/// These are: calling pthread_exit() from code that directly or indirectly...
+/// 1) contains a catch(...) that does not rethrow? std::abort() gets called
+/// 2) contains a function declared noexcept? std::abort() gets called
+/// 3) is called from a destructor? you guessed it, std::abort() again!
+/// For this reason pthread_exit() support is by default disabled in Miosix and
+/// attempting to call this function is met with a linking error. If you really
+/// need it, uncomment the line below. Oh, right, how does Miosix implement it?
+/// Throwing a standard C++ exception, so a catch(...) can stop a pthread_exit()
+/// which is imho neither better nor worse than Linux.
+/// Reference: https://udrepper.livejournal.com/21541.html
+//#define WITH_PTHREAD_EXIT
+
 /// Enable support for pthread_key_create/pthread_key_delete/pthread_getspecific
 //#define WITH_PTHREAD_KEYS
 
diff --git a/miosix/kernel/boot.cpp b/miosix/kernel/boot.cpp
index b1646f45ec6bdbaef5345918854abc57b896b83e..48156d30f86ba0fb1379e0ee511736cc0561c4ff 100644
--- a/miosix/kernel/boot.cpp
+++ b/miosix/kernel/boot.cpp
@@ -38,6 +38,7 @@
 #include "filesystem/file_access.h"
 #include "error.h"
 #include "logging.h"
+#include "pthread_private.h"
 // settings for miosix
 #include "config/miosix_settings.h"
 #include "util/util.h"
@@ -150,11 +151,15 @@ void *mainLoader(void *argv)
     #else //__NO_EXCEPTIONS
     try {
         main(0,NULL);
+    #ifdef WITH_PTHREAD_EXIT
+    } catch(PthreadExitException&) {
+        errorLog("***Attempting to pthread_exit from main\n");
+    #endif //WITH_PTHREAD_EXIT
     } catch(std::exception& e) {
-        errorLog("***An exception propagated through a thread\n");
+        errorLog("***An exception propagated through main\n");
         errorLog("what():%s\n",e.what());
     } catch(...) {
-        errorLog("***An exception propagated through a thread\n");
+        errorLog("***An exception propagated through main\n");
     }
     #endif //__NO_EXCEPTIONS
     
diff --git a/miosix/kernel/kernel.cpp b/miosix/kernel/kernel.cpp
index 204f93b5142b3bfe66710460a9165218bb069752..235b241dedc7f71270d22e45c1c094bd002be22d 100755
--- a/miosix/kernel/kernel.cpp
+++ b/miosix/kernel/kernel.cpp
@@ -830,6 +830,10 @@ void Thread::threadLauncher(void *(*threadfunc)(void*), void *argv)
     #else //__NO_EXCEPTIONS
     try {
         result=threadfunc(argv);
+    #ifdef WITH_PTHREAD_EXIT
+    } catch(PthreadExitException& e) {
+        result=e.getReturnValue();
+    #endif //WITH_PTHREAD_EXIT
     } catch(std::exception& e) {
         errorLog("***An exception propagated through a thread\n");
         errorLog("what():%s\n",e.what());
diff --git a/miosix/kernel/pthread.cpp b/miosix/kernel/pthread.cpp
index 218a7b36f530eab0462fdbb716885c7f91a343d0..f87f19f22f5ede8257bb81d068dc2a8bdc62aca1 100644
--- a/miosix/kernel/pthread.cpp
+++ b/miosix/kernel/pthread.cpp
@@ -390,6 +390,15 @@ int pthread_once(pthread_once_t *once, void (*func)())
 
 int pthread_setcancelstate(int state, int *oldstate) { return 0; } //Stub
 
+#ifdef WITH_PTHREAD_EXIT
+
+void pthread_exit(void *returnValue)
+{
+    throw PthreadExitException(returnValue);
+}
+
+#endif //WITH_PTHREAD_EXIT
+
 #ifdef WITH_PTHREAD_KEYS
 
 typedef void (*destructor_type)(void *);
diff --git a/miosix/kernel/pthread_private.h b/miosix/kernel/pthread_private.h
index bed3f28811205199a6bfe1cf32e9b90391a068da..d49b7332c0013fb813c51dd6879d19bbc12e5182 100644
--- a/miosix/kernel/pthread_private.h
+++ b/miosix/kernel/pthread_private.h
@@ -167,6 +167,35 @@ static inline unsigned int IRQdoMutexUnlockAllDepthLevels(pthread_mutex_t *mutex
     return result;
 }
 
+#ifdef WITH_PTHREAD_EXIT
+
+/**
+ * Exception type thrown when pthread_exit is called.
+ *
+ * NOTE: This type should not derive from std::exception on purpose, as it would
+ * be bad if a \code catch(std::exception& e) \endcode would match this
+ * exception.
+ */
+class PthreadExitException
+{
+public:
+    /**
+     * Constructor
+     * \param returnValue thread return value passed to pthread_exit
+     */
+    PthreadExitException(void *returnValue) : returnValue(returnValue) {}
+
+    /**
+     * \return the thread return value passed to pthread_exit
+     */
+    void *getReturnValue() const { return returnValue; }
+
+private:
+    void *returnValue;
+};
+
+#endif //WITH_PTHREAD_EXIT
+
 #ifdef WITH_PTHREAD_KEYS
 /**
  * Called at thread exit to call destructors for pthread keys