@@ -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
@@ -429,6 +429,50 @@ exceptionLocationExpr = unlines
429429 , " in go"
430430 ]
431431
432+ getExceptionInfo :: RemoteThreadId -> Debugger ExceptionInfo
433+ getExceptionInfo req_tid = GHC. getResumeContext >>= \ case
434+ [] -> return defaultExceptionInfo
435+ r: _ -> do
436+ r_tid <- getRemoteThreadIdFromRemoteContext (GHC. resumeContext r)
437+ case (r_tid == req_tid, GHC. resumeBreakpointId r) of
438+ (True , Nothing ) -> do
439+ let excRef = resumeApStack r
440+ fromMaybe defaultExceptionInfo <$> exceptionInfoFromContext excRef
441+ _ -> return defaultExceptionInfo
442+
443+ exceptionInfoFromContext :: ForeignHValue -> Debugger (Maybe ExceptionInfo )
444+ exceptionInfoFromContext excRef = do
445+ evalRes <- Remote. eval
446+ (Remote. raw exceptionInfoExpr `Remote.app` Remote. untypedRef excRef)
447+ case evalRes of
448+ Left err -> do
449+ logSDoc Logger. Debug $
450+ Ppr. text " Failed to evaluate exception info:" Ppr. <+> Ppr. text (show err)
451+ return Nothing
452+ Right fhv -> do
453+ parsed <- obtainParsedTerm " Exception info" 4 True anyTy (castForeignRef fhv)
454+ exceptionInfoParser
455+ case parsed of
456+ Left errs -> do
457+ logSDoc Logger. Debug $
458+ Ppr. text " Failed to parse exception info:"
459+ Ppr. <+> Ppr. vcat (map (Ppr. text . getTermErrorMessage) errs)
460+ return Nothing
461+ Right info -> return (Just info)
462+
463+ exceptionInfoParser :: TermParser ExceptionInfo
464+ exceptionInfoParser = do
465+ matchConstructorTerm " ExceptionInfoNode"
466+ ExceptionInfo
467+ <$> subtermWith 1 stringParser
468+ <*> subtermWith 0 stringParser
469+ <*> subtermWith 2 stringParser
470+ <*> subtermWith 3 (maybeParser stringParser)
471+ <*> subtermWith 4 (parseList exceptionInfoParser)
472+
473+ exceptionInfoExpr :: String
474+ exceptionInfoExpr = " GHC.Debugger.View.Exception.collectExceptionInfo"
475+
432476fallbackExceptionSourceSpan :: Maybe SrcSpan -> SourceSpan
433477fallbackExceptionSourceSpan mspan =
434478 let fileLabel = maybe " <exception>" spanLabel mspan
@@ -442,3 +486,19 @@ fallbackExceptionSourceSpan mspan =
442486 where
443487 spanLabel (RealSrcSpan rss _) = unpackFS (srcSpanFile rss)
444488 spanLabel (UnhelpfulSpan reason) = unpackFS (unhelpfulSpanFS reason)
489+
490+ defaultExceptionInfo :: ExceptionInfo
491+ defaultExceptionInfo = ExceptionInfo
492+ { exceptionInfoTypeName = " Exception"
493+ , exceptionInfoFullTypeName = " Exception"
494+ , exceptionInfoMessage = " Exception information not available"
495+ , exceptionInfoContext = Nothing
496+ , exceptionInfoInner = []
497+ }
498+
499+ currentlyStoppedOnException :: Debugger Bool
500+ currentlyStoppedOnException = do
501+ resumes <- GHC. getResumeContext
502+ return $ case resumes of
503+ [] -> False
504+ r: _ -> resumeHistoryIx r == 0 && isNothing (GHC. resumeBreakpointId r)
0 commit comments