diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,12 @@
 HsQML - Release History
 
+release-0.3.2.1 - 2014.11.29
+
+  * Added function to shutdown the Qt framework.
+  * Fixed intermittent crash on exit under Linux.
+  * Fixed reanimated objects being passed to QML as undefined.
+  * Fixed typo in the names of implicit property signals.
+
 release-0.3.2.0 - 2014.11.13
 
   * Added OpenGL canvas support.
diff --git a/cbits/Manager.cpp b/cbits/Manager.cpp
--- a/cbits/Manager.cpp
+++ b/cbits/Manager.cpp
@@ -28,8 +28,20 @@
     "ObjectSerial"
 };
 
-extern "C" void hsqml_dump_counters()
+// This definition overrides a symbol in the GHC RTS
+#ifdef HSQML_USE_EXIT_HOOK
+#ifdef Q_OS_LINUX // TODO: Test on other platforms.
+extern "C" void OnExitHook()
 {
+    if (gManager) {
+        gManager->shutdown();
+    }
+}
+#endif
+#endif
+
+static void dump_counters()
+{
     Q_ASSERT (gManager);
     if (gManager->checkLogLevel(1)) {
         for (int i=0; i<HsQMLManager::TotalCounters; i++) {
@@ -60,11 +72,11 @@
     , mFreeFun(freeFun)
     , mFreeStable(freeStable)
     , mOriginalHandler(qcoreVariantHandler())
-    , mHookedHandler(*mOriginalHandler)
     , mApp(NULL)
     , mLock(QMutex::Recursive)
     , mRunning(false)
     , mRunCount(0)
+    , mShutdown(false)
     , mStackBase(NULL)
     , mStartCb(NULL)
     , mJobsCb(NULL)
@@ -76,17 +88,13 @@
     if (env) {
         setLogLevel(QString(env).toInt());
     }
-
-    // Set hooked handler functions
-    mHookedHandler.construct = &hooked_construct;
-    mHookedHandler.clear = &hooked_clear;
 }
 
 void HsQMLManager::setLogLevel(int ll)
 {
     mLogLevel = ll;
     if (ll > 0 && !mAtExit) {
-        if (atexit(&hsqml_dump_counters) == 0) {
+        if (atexit(&dump_counters) == 0) {
             mAtExit = true;
         }
         else {
@@ -183,10 +191,13 @@
 {
     QMutexLocker locker(&mLock);
 
-    // Check if already running
+    // Check for invalid state
     if (mRunning) {
         return HSQML_EVLOOP_ALREADY_RUNNING;
     }
+    else if (mShutdown) {
+        return HSQML_EVLOOP_POST_SHUTDOWN;
+    }
 
     // Check if event loop bound to a different thread
     if (mApp && !isEventThread()) {
@@ -207,16 +218,8 @@
             "Warning: CPU cannot idle when using the non-threaded RTS.");
     }
 
-    // Perform one-time initialisation
+    // Create application object
     if (!mApp) {
-        // Install hooked handler for QVariants
-        QVariantPrivate::registerHandler(0, &mHookedHandler);
-
-        // Register custom types
-        qRegisterMetaType<HsQMLEngineConfig>("HsQMLEngineConfig");
-        qmlRegisterType<HsQMLCanvas>("HsQML.Canvas", 1, 0, "HaskellCanvas");
-
-        // Create application object
         mApp = new HsQMLManagerApp();
     }
 
@@ -329,13 +332,42 @@
     QCoreApplication::postEvent(mApp, ev);
 }
 
+HsQMLManager::EventLoopStatus HsQMLManager::shutdown()
+{
+    QMutexLocker locker(&mLock);
+
+    if (mRunning) {
+        return HSQML_EVLOOP_ALREADY_RUNNING;
+    }
+    else if (isEventThread()) {
+        HSQML_LOG(1, "Deleting QApplication object.");
+        delete mApp;
+        mApp = NULL;
+        mShutdown = true;
+    }
+    else if (mApp) {
+        return HSQML_EVLOOP_WRONG_THREAD; 
+    }
+    return HSQML_EVLOOP_OK;
+}
+
 HsQMLManagerApp::HsQMLManagerApp()
     : mArgC(1)
     , mArg0(0)
     , mArgV(&mArg0)
+    , mHookedHandler(*gManager->mOriginalHandler)
     , mApp(mArgC, &mArgV)
 {
     mApp.setQuitOnLastWindowClosed(false);
+
+    // Install hooked handler for QVariants
+    mHookedHandler.construct = &hooked_construct;
+    mHookedHandler.clear = &hooked_clear;
+    QVariantPrivate::registerHandler(0, &mHookedHandler);
+
+    // Register custom types
+    qRegisterMetaType<HsQMLEngineConfig>("HsQMLEngineConfig");
+    qmlRegisterType<HsQMLCanvas>("HsQML.Canvas", 1, 0, "HaskellCanvas");
 }
 
 HsQMLManagerApp::~HsQMLManagerApp()
@@ -415,6 +447,14 @@
 extern "C" void hsqml_evloop_notify_jobs()
 {
     gManager->notifyJobs();
+}
+
+extern "C" HsQMLEventLoopStatus hsqml_evloop_shutdown()
+{
+    if (gManager) {
+        return gManager->shutdown();
+    }
+    return HSQML_EVLOOP_OK;
 }
 
 extern "C" void hsqml_set_debug_loglevel(int ll)
diff --git a/cbits/Manager.h b/cbits/Manager.h
--- a/cbits/Manager.h
+++ b/cbits/Manager.h
@@ -54,6 +54,7 @@
     void setActiveEngine(HsQMLEngine*);
     HsQMLEngine* activeEngine();
     void postObjectEvent(HsQMLObjectEvent*);
+    EventLoopStatus shutdown();
 
 private:
     friend class HsQMLManagerApp;
@@ -67,11 +68,11 @@
     void (*mFreeStable)(HsStablePtr);
     QSet<const QObject*> mObjectSet;
     const QVariant::Handler* mOriginalHandler;
-    QVariant::Handler mHookedHandler;
     HsQMLManagerApp* mApp;
     QMutex mLock;
     bool mRunning;
     int mRunCount;
+    bool mShutdown;
     void* mStackBase;
     HsQMLTrivialCb mStartCb;
     HsQMLTrivialCb mJobsCb;
@@ -113,6 +114,7 @@
     int mArgC;
     char mArg0;
     char* mArgV;
+    QVariant::Handler mHookedHandler;
     QApplication mApp;
 };
 
diff --git a/cbits/Object.cpp b/cbits/Object.cpp
--- a/cbits/Object.cpp
+++ b/cbits/Object.cpp
@@ -57,12 +57,16 @@
     Q_ASSERT(engine);
     if (!mObject) {
         mObject = new HsQMLObject(this, engine);
-        tryGCLock();
 
         HSQML_LOG(5,
             QString().sprintf("New QObject, class=%s, id=%d, qptr=%p.",
             mKlass->name(), mSerial, mObject));
     }
+
+    // Old objects may have lost their lock via weak references in addition
+    // to new objects needing it.
+    tryGCLock();
+
     return mObject;
 }
 
diff --git a/cbits/hsqml.h b/cbits/hsqml.h
--- a/cbits/hsqml.h
+++ b/cbits/hsqml.h
@@ -21,6 +21,7 @@
 typedef enum {
     HSQML_EVLOOP_OK = 0,
     HSQML_EVLOOP_ALREADY_RUNNING,
+    HSQML_EVLOOP_POST_SHUTDOWN,
     HSQML_EVLOOP_WRONG_THREAD,
     HSQML_EVLOOP_NOT_RUNNING,
     HSQML_EVLOOP_OTHER_ERROR
@@ -36,6 +37,8 @@
 extern void hsqml_evloop_release();
 
 extern void hsqml_evloop_notify_jobs();
+
+extern HsQMLEventLoopStatus hsqml_evloop_shutdown();
 
 /* String */
 typedef char HsQMLStringHandle;
diff --git a/hsqml.cabal b/hsqml.cabal
--- a/hsqml.cabal
+++ b/hsqml.cabal
@@ -1,5 +1,5 @@
 Name:               hsqml
-Version:            0.3.2.0
+Version:            0.3.2.1
 Cabal-version:      >= 1.14
 Build-type:         Custom
 License:            BSD3
@@ -35,6 +35,11 @@
         Force enable GHCi workaround library if not using shared libraries.
     Default: True
 
+Flag UseExitHook
+    Description:
+        Override the OnExitHook symbol to shutdown the Qt framework on exit.
+    Default: True
+
 Library
     Default-language: Haskell2010
     Build-depends:
@@ -79,6 +84,8 @@
     Build-tools: c2hs
     if flag(ForceGHCiLib)
         X-force-ghci-lib: True
+    if flag(UseExitHook)
+        CC-options: -DHSQML_USE_EXIT_HOOK
     if os(windows) && !flag(UsePkgConfig)
         Include-dirs: /QT_ROOT/include
         Extra-libraries:
diff --git a/src/Graphics/QML/Engine.hs b/src/Graphics/QML/Engine.hs
--- a/src/Graphics/QML/Engine.hs
+++ b/src/Graphics/QML/Engine.hs
@@ -22,6 +22,7 @@
   RunQML(),
   runEventLoop,
   requireEventLoop,
+  shutdownQt,
   EventLoopException(),
 
   -- * Document Paths
@@ -168,9 +169,31 @@
                 Nothing -> return ()
     bracket_ reqFn hsqmlEvloopRelease runFn
 
+-- | Shuts down and frees resources used by the Qt framework, preventing
+-- further use of the event loop. The framework is initialised when
+-- 'runEventLoop' is first called and remains initialised afterwards so that
+-- the event loop can be reentered if desired (e.g. when using GHCi). Once
+-- shut down, the framework cannot be reinitialised.
+--
+-- It is recommended that you call this function at the end of your program as
+-- this library will try, but cannot guarantee in all configurations to be able
+-- to shut it down for you. Failing to shutdown the framework has been known to
+-- intermittently cause crashes on process exit on some platforms.
+--
+-- This function must be called from the event loop thread and the event loop
+-- must not be running at the time otherwise an 'EventLoopException' will be
+-- thrown.
+shutdownQt :: IO ()
+shutdownQt = do
+    status <- hsqmlEvloopShutdown
+    case statusException status of
+        Just ex -> throw ex
+        Nothing -> return ()
+
 statusException :: HsQMLEventLoopStatus -> Maybe EventLoopException
 statusException HsqmlEvloopOk = Nothing
 statusException HsqmlEvloopAlreadyRunning = Just EventLoopAlreadyRunning
+statusException HsqmlEvloopPostShutdown = Just EventLoopPostShutdown
 statusException HsqmlEvloopWrongThread = Just EventLoopWrongThread
 statusException HsqmlEvloopNotRunning = Just EventLoopNotRunning
 statusException _ = Just EventLoopOtherError
@@ -178,6 +201,7 @@
 -- | Exception type used to report errors pertaining to the event loop.
 data EventLoopException
     = EventLoopAlreadyRunning
+    | EventLoopPostShutdown
     | EventLoopWrongThread
     | EventLoopNotRunning
     | EventLoopOtherError
diff --git a/src/Graphics/QML/Internal/BindCore.chs b/src/Graphics/QML/Internal/BindCore.chs
--- a/src/Graphics/QML/Internal/BindCore.chs
+++ b/src/Graphics/QML/Internal/BindCore.chs
@@ -63,6 +63,10 @@
   {} ->
   `()' #}
 
+{#fun unsafe hsqml_evloop_shutdown as ^
+  {} ->
+  `HsQMLEventLoopStatus' cIntToEnum #}
+
 {#fun hsqml_create_engine as ^
   {withMaybeHsQMLObjectHandle* `Maybe HsQMLObjectHandle',
    id `HsQMLStringHandle',
diff --git a/src/Graphics/QML/Objects.hs b/src/Graphics/QML/Objects.hs
--- a/src/Graphics/QML/Objects.hs
+++ b/src/Graphics/QML/Objects.hs
@@ -150,7 +150,7 @@
         impKeys = filter (flip Set.notMember sigKeys) $ mapMaybe memberKey $
             filterMembers PropertyMember ms
         impMember i k = Member SignalMember
-            ("__implictSignal" ++ show i)
+            ("__implicitSignal" ++ show i)
             tyVoid
             []
             (\_ _ -> return ())
