Skip to content
GitLab
Projects Groups Topics Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Register
  • Sign in
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributor statistics
    • Graph
    • Compare revisions
    • Locked files
  • Issues 5.5k
    • Issues 5.5k
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 639
    • Merge requests 639
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Artifacts
    • Schedules
    • Test cases
  • Deployments
    • Deployments
    • Releases
  • Packages and registries
    • Packages and registries
    • Model experiments
  • Analytics
    • Analytics
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell CompilerGlasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #21962

Segfault when allocating empty MutableArrayArray#

Summary

GHC 9.2.4 generates incorrect code that always segfaults when allocating an empty MutableArrayArray#. GHC 9.0.2 and GHC 8.10.7 do not have this problem.

Steps to reproduce

Build and run this program:

{-# language MagicHash #-}
{-# language UnboxedTuples #-}

import GHC.Exts
import GHC.IO (IO(IO))

main :: IO ()
main = do
  putStrLn "Begin"
  sz <- IO $ \s0 -> case newArrayArray# 0# s0 of
    (# s1, buf #) -> (# s1, I# (sizeofMutableArrayArray# buf) #)
  print sz
  putStrLn "End"

Expected behavior

The program should print:

Begin
0
End

Environment

  • GHC version used: 9.2.4

Comments

On GHC HEAD, ArrayArray# has been removed entirely in favor of Array#, and Array# does not have this problem. I think that all that is needed is a fix for the GHC 9.2 series. With git blame on a copy of the GHC source from Jan 2022, I see:

a7c0387d20c rts/PrimOps.cmm     (Simon Marlow                2012-10-03 09:30:56 +0100  454) stg_newArrayArrayzh ( W_ n /* words */ )
021a0dd265f rts/PrimOps.cmm     (Manuel M T Chakravarty      2011-12-07 22:40:14 +1100  455) {
a6939ec29a9 rts/PrimOps.cmm     (Johan Tibell                2014-03-20 07:58:10 +0100  456)     W_ words, size, p;
a6939ec29a9 rts/PrimOps.cmm     (Johan Tibell                2014-03-20 07:58:10 +0100  457)     gcptr arr;
021a0dd265f rts/PrimOps.cmm     (Manuel M T Chakravarty      2011-12-07 22:40:14 +1100  458) 
a7c0387d20c rts/PrimOps.cmm     (Simon Marlow                2012-10-03 09:30:56 +0100  459)     MAYBE_GC_N(stg_newArrayArrayzh, n);
021a0dd265f rts/PrimOps.cmm     (Manuel M T Chakravarty      2011-12-07 22:40:14 +1100  460) 
021a0dd265f rts/PrimOps.cmm     (Manuel M T Chakravarty      2011-12-07 22:40:14 +1100  461)     // the mark area contains one byte for each 2^MUT_ARR_PTRS_CARD_BITS words
021a0dd265f rts/PrimOps.cmm     (Manuel M T Chakravarty      2011-12-07 22:40:14 +1100  462)     // in the array, making sure we round up, and then rounding up to a whole
021a0dd265f rts/PrimOps.cmm     (Manuel M T Chakravarty      2011-12-07 22:40:14 +1100  463)     // number of words.
021a0dd265f rts/PrimOps.cmm     (Manuel M T Chakravarty      2011-12-07 22:40:14 +1100  464)     size = n + mutArrPtrsCardWords(n);
021a0dd265f rts/PrimOps.cmm     (Manuel M T Chakravarty      2011-12-07 22:40:14 +1100  465)     words = BYTES_TO_WDS(SIZEOF_StgMutArrPtrs) + size;
30a1eeea37e rts/PrimOps.cmm     (Ben Gamari                  2017-09-26 15:09:13 -0400  466)     ("ptr" arr) = ccall allocateMightFail(MyCapability() "ptr",words);
30a1eeea37e rts/PrimOps.cmm     (Ben Gamari                  2017-09-26 15:09:13 -0400  467)     if (arr == NULL) {
30a1eeea37e rts/PrimOps.cmm     (Ben Gamari                  2017-09-26 15:09:13 -0400  468)         jump stg_raisezh(base_GHCziIOziException_heapOverflow_closure);
30a1eeea37e rts/PrimOps.cmm     (Ben Gamari                  2017-09-26 15:09:13 -0400  469)     }
46d05ba03d1 rts/PrimOps.cmm     (Johan Tibell                2014-03-13 22:24:24 +0100  470)     TICK_ALLOC_PRIM(SIZEOF_StgMutArrPtrs, WDS(size), 0);
021a0dd265f rts/PrimOps.cmm     (Manuel M T Chakravarty      2011-12-07 22:40:14 +1100  471) 
021a0dd265f rts/PrimOps.cmm     (Manuel M T Chakravarty      2011-12-07 22:40:14 +1100  472)     SET_HDR(arr, stg_MUT_ARR_PTRS_DIRTY_info, W_[CCCS]);
021a0dd265f rts/PrimOps.cmm     (Manuel M T Chakravarty      2011-12-07 22:40:14 +1100  473)     StgMutArrPtrs_ptrs(arr) = n;
021a0dd265f rts/PrimOps.cmm     (Manuel M T Chakravarty      2011-12-07 22:40:14 +1100  474)     StgMutArrPtrs_size(arr) = size;
021a0dd265f rts/PrimOps.cmm     (Manuel M T Chakravarty      2011-12-07 22:40:14 +1100  475) 
d159041b440 rts/PrimOps.cmm     (Ben Gamari                  2021-01-06 11:20:44 -0500  476)     // Initialize card table to all-clean.
d159041b440 rts/PrimOps.cmm     (Ben Gamari                  2021-01-06 11:20:44 -0500  477)     setCardsValue(arr, 0, n, 0);
d159041b440 rts/PrimOps.cmm     (Ben Gamari                  2021-01-06 11:20:44 -0500  478) 
021a0dd265f rts/PrimOps.cmm     (Manuel M T Chakravarty      2011-12-07 22:40:14 +1100  479)     // Initialise all elements of the array with a pointer to the new array
021a0dd265f rts/PrimOps.cmm     (Manuel M T Chakravarty      2011-12-07 22:40:14 +1100  480)     p = arr + SIZEOF_StgMutArrPtrs;
021a0dd265f rts/PrimOps.cmm     (Manuel M T Chakravarty      2011-12-07 22:40:14 +1100  481)   for:
12056292280 rts/PrimOps.cmm     (Andreas Klebinger           2018-01-29 18:25:00 -0500  482)     if (p < arr + SIZEOF_StgMutArrPtrs + WDS(n)) (likely: True) {
f7c8c3d47be rts/PrimOps.cmm     (Ian Lynagh                  2013-06-09 14:48:32 +0100  483)         W_[p] = arr;
f7c8c3d47be rts/PrimOps.cmm     (Ian Lynagh                  2013-06-09 14:48:32 +0100  484)         p = p + WDS(1);
f7c8c3d47be rts/PrimOps.cmm     (Ian Lynagh                  2013-06-09 14:48:32 +0100  485)         goto for;
021a0dd265f rts/PrimOps.cmm     (Manuel M T Chakravarty      2011-12-07 22:40:14 +1100  486)     }
021a0dd265f rts/PrimOps.cmm     (Manuel M T Chakravarty      2011-12-07 22:40:14 +1100  487) 
a7c0387d20c rts/PrimOps.cmm     (Simon Marlow                2012-10-03 09:30:56 +0100  488)     return (arr);
021a0dd265f rts/PrimOps.cmm     (Manuel M T Chakravarty      2011-12-07 22:40:14 +1100  489) }

The only non-ancient change is this addition from @bgamari in Jan 2021:

// Initialize card table to all-clean.
setCardsValue(arr, 0, n, 0);

I can't tell whether or not setCardsValue gets messed up when n = 0 though.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking