@@ -394,12 +394,12 @@ exceptionSourceSpanFromContext = do
394394 Ppr. <+> Ppr. vcat (map (Ppr. text . getTermErrorMessage) errs)
395395 return Nothing
396396 Right Nothing -> return Nothing
397- Right (Just (file, line , col)) ->
397+ Right (Just (file, srcLine , col)) ->
398398 return $ Just SourceSpan
399399 { file = file
400- , startLine = line
400+ , startLine = srcLine
401401 , startCol = col
402- , endLine = line
402+ , endLine = srcLine
403403 , endCol = col
404404 }
405405 _ -> return Nothing
@@ -433,6 +433,50 @@ exceptionLocationExpr = unlines
433433 , " in go"
434434 ]
435435
436+ getExceptionInfo :: RemoteThreadId -> Debugger ExceptionInfo
437+ getExceptionInfo req_tid = GHC. getResumeContext >>= \ case
438+ [] -> return defaultExceptionInfo
439+ r: _ -> do
440+ r_tid <- getRemoteThreadIdFromRemoteContext (GHC. resumeContext r)
441+ case (r_tid == req_tid, GHC. resumeBreakpointId r) of
442+ (True , Nothing ) -> do
443+ let excRef = resumeApStack r
444+ fromMaybe defaultExceptionInfo <$> exceptionInfoFromContext excRef
445+ _ -> return defaultExceptionInfo
446+
447+ exceptionInfoFromContext :: ForeignHValue -> Debugger (Maybe ExceptionInfo )
448+ exceptionInfoFromContext excRef = do
449+ evalRes <- Remote. eval
450+ (Remote. raw exceptionInfoExpr `Remote.app` Remote. untypedRef excRef)
451+ case evalRes of
452+ Left err -> do
453+ logSDoc Logger. Debug $
454+ Ppr. text " Failed to evaluate exception info:" Ppr. <+> Ppr. text (show err)
455+ return Nothing
456+ Right fhv -> do
457+ parsed <- obtainParsedTerm " Exception info" 4 True anyTy (castForeignRef fhv)
458+ exceptionInfoParser
459+ case parsed of
460+ Left errs -> do
461+ logSDoc Logger. Debug $
462+ Ppr. text " Failed to parse exception info:"
463+ Ppr. <+> Ppr. vcat (map (Ppr. text . getTermErrorMessage) errs)
464+ return Nothing
465+ Right info -> return (Just info)
466+
467+ exceptionInfoParser :: TermParser ExceptionInfo
468+ exceptionInfoParser = do
469+ matchConstructorTerm " ExceptionInfoNode"
470+ ExceptionInfo
471+ <$> subtermWith 1 stringParser
472+ <*> subtermWith 0 stringParser
473+ <*> subtermWith 2 stringParser
474+ <*> subtermWith 3 (maybeParser stringParser)
475+ <*> subtermWith 4 (parseList exceptionInfoParser)
476+
477+ exceptionInfoExpr :: String
478+ exceptionInfoExpr = " GHC.Debugger.View.Exception.collectExceptionInfo"
479+
436480fallbackExceptionSourceSpan :: Maybe SrcSpan -> SourceSpan
437481fallbackExceptionSourceSpan mspan =
438482 let fileLabel = maybe " <exception>" spanLabel mspan
@@ -446,3 +490,19 @@ fallbackExceptionSourceSpan mspan =
446490 where
447491 spanLabel (RealSrcSpan rss _) = unpackFS (srcSpanFile rss)
448492 spanLabel (UnhelpfulSpan reason) = unpackFS (unhelpfulSpanFS reason)
493+
494+ defaultExceptionInfo :: ExceptionInfo
495+ defaultExceptionInfo = ExceptionInfo
496+ { exceptionInfoTypeName = " Exception"
497+ , exceptionInfoFullTypeName = " Exception"
498+ , exceptionInfoMessage = " Exception information not available"
499+ , exceptionInfoContext = Nothing
500+ , exceptionInfoInner = []
501+ }
502+
503+ currentlyStoppedOnException :: Debugger Bool
504+ currentlyStoppedOnException = do
505+ resumes <- GHC. getResumeContext
506+ return $ case resumes of
507+ [] -> False
508+ r: _ -> resumeHistoryIx r == 0 && isNothing (GHC. resumeBreakpointId r)
0 commit comments