[commit: ghc] master: Libdw: Handle failure to grab session for location lookup (ba14f04)

git at git.haskell.org git at git.haskell.org
Thu Nov 26 14:11:45 UTC 2015


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/ba14f04dae398c102209e3374bea882ebf823257/ghc

>---------------------------------------------------------------

commit ba14f04dae398c102209e3374bea882ebf823257
Author: Ben Gamari <ben at smart-cactus.org>
Date:   Thu Nov 26 12:12:32 2015 +0100

    Libdw: Handle failure to grab session for location lookup
    
    This one slipped through testing.


>---------------------------------------------------------------

ba14f04dae398c102209e3374bea882ebf823257
 libraries/base/GHC/ExecutionStack.hs           |  5 +++--
 libraries/base/GHC/ExecutionStack/Internal.hsc | 14 +++++++++-----
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/libraries/base/GHC/ExecutionStack.hs b/libraries/base/GHC/ExecutionStack.hs
index 245b996..11f8c9e 100644
--- a/libraries/base/GHC/ExecutionStack.hs
+++ b/libraries/base/GHC/ExecutionStack.hs
@@ -36,14 +36,15 @@ module GHC.ExecutionStack (
   , showStackTrace
   ) where
 
+import Control.Monad (join)
 import GHC.ExecutionStack.Internal
 
 -- | Get a trace of the current execution stack state.
 --
 -- Returns @Nothing@ if stack trace support isn't available on host machine.
 getStackTrace :: IO (Maybe [Location])
-getStackTrace = fmap stackFrames `fmap` collectStackTrace
+getStackTrace = (join . fmap stackFrames) `fmap` collectStackTrace
 
 -- | Get a string representation of the current execution stack state.
 showStackTrace :: IO (Maybe String)
-showStackTrace = fmap (flip showStackFrames "") `fmap` getStackTrace
+showStackTrace = fmap (\st -> showStackFrames st "") `fmap` getStackTrace
diff --git a/libraries/base/GHC/ExecutionStack/Internal.hsc b/libraries/base/GHC/ExecutionStack/Internal.hsc
index 7a30fea..e966e17 100644
--- a/libraries/base/GHC/ExecutionStack/Internal.hsc
+++ b/libraries/base/GHC/ExecutionStack/Internal.hsc
@@ -31,6 +31,7 @@ module GHC.ExecutionStack.Internal (
   , invalidateDebugCache
   ) where
 
+import Control.Monad (join)
 import Data.Word
 import Foreign.C.Types
 import Foreign.C.String (peekCString, CString)
@@ -66,11 +67,14 @@ newtype StackTrace = StackTrace (ForeignPtr StackTrace)
 -- | An address
 type Addr = Ptr ()
 
-withSession :: (ForeignPtr Session -> IO a) -> IO a
+withSession :: (ForeignPtr Session -> IO a) -> IO (Maybe a)
 withSession action = do
     ptr <- libdw_pool_take
-    fptr <- newForeignPtr libdw_pool_release ptr
-    action fptr
+    if | nullPtr == ptr -> return Nothing
+       | otherwise      -> do
+           fptr <- newForeignPtr libdw_pool_release ptr
+           ret <- action fptr
+           return $ Just ret
 
 -- | How many stack frames in the given 'StackTrace'
 stackDepth :: StackTrace -> Int
@@ -126,7 +130,7 @@ locationSize :: Int
 locationSize = (#const sizeof(Location))
 
 -- | List the frames of a stack trace.
-stackFrames :: StackTrace -> [Location]
+stackFrames :: StackTrace -> Maybe [Location]
 stackFrames st@(StackTrace fptr) = unsafePerformIO $ withSession $ \sess -> do
     chunks <- chunksList st
     go sess (reverse chunks)
@@ -197,7 +201,7 @@ foreign import ccall unsafe "&backtraceFree"
 
 -- | Get an execution stack.
 collectStackTrace :: IO (Maybe StackTrace)
-collectStackTrace = withSession $ \sess -> do
+collectStackTrace = fmap join $ withSession $ \sess -> do
     st <- withForeignPtr sess libdw_get_backtrace
     if | st == nullPtr -> return Nothing
        | otherwise     -> Just . StackTrace <$> newForeignPtr backtrace_free st



More information about the ghc-commits mailing list