[GHC] #15906: Stable name allocation causes heap corruption when GC is triggered in the primop

#15906: Stable name allocation causes heap corruption when GC is triggered in the primop -------------------------------------+------------------------------------- Reporter: osa1 | Owner: (none) Type: bug | Status: new Priority: highest | Milestone: 8.6.3 Component: Runtime | Version: 8.7 System | Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- The error is originally reported in #15241, and is caught by the test `memo001` when run with `-debug` (which only happens in sanity way currently). Here's the problem. mkStableName# is defined like this: {{{ stg_makeStableNamezh ( P_ obj ) { W_ index, sn_obj; (index) = ccall lookupStableName(obj "ptr"); /* Is there already a StableName for this heap object? * stable_name_table is a pointer to an array of snEntry structs. */ if ( snEntry_sn_obj(W_[stable_name_table] + index*SIZEOF_snEntry) == NULL ) { ALLOC_PRIM (SIZEOF_StgStableName); <------------ PROBLEM HERE ---------- sn_obj = Hp - SIZEOF_StgStableName + WDS(1); SET_HDR(sn_obj, stg_STABLE_NAME_info, CCCS); StgStableName_sn(sn_obj) = index; snEntry_sn_obj(W_[stable_name_table] + index*SIZEOF_snEntry) = sn_obj; } else { sn_obj = snEntry_sn_obj(W_[stable_name_table] + index*SIZEOF_snEntry); } return (sn_obj); } }}} There's a problem in the annotated line: if we allocate a `snEntry` in the stable name table, but run out of heap to actually allocate the `StgStableName` we call GC with incorrect `snEntry` contents. As a reminder, this is `snEntry`: {{{ typedef struct { StgPtr addr; // Haskell object when entry is in use, next free // entry (NULL when this is the last free entry) // otherwise. May be NULL temporarily during GC (when // pointee dies). StgPtr old; // Old Haskell object, used during GC StgClosure *sn_obj; // The StableName object, or NULL when the entry is // free } snEntry; }}} In summary, `sn_obj == NULL` means the entry is free. When we trigger the GC after allocating the `snEntry` but before allocating the `StgStableName`, we end up calling the GC with `sn_obj == NULL` even though the `snEntry` is not actually free. In particular, the `addr` field should be updated by `gcStableNameTable`, but it's currently not because `gcStableNameTable` sees `sn_obj` as NULL and skips the entry. The is caught by memo001 when run with -debug. I already have a fix and will submit a patch soon. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15906 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15906: Stable name allocation causes heap corruption when GC is triggered in the primop -------------------------------------+------------------------------------- Reporter: osa1 | Owner: (none) Type: bug | Status: patch Priority: highest | Milestone: 8.6.3 Component: Runtime System | Version: 8.7 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D5342 Wiki Page: | -------------------------------------+------------------------------------- Changes (by osa1): * status: new => patch * cc: simonmar (added) * differential: => Phab:D5342 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15906#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15906: Stable name allocation causes heap corruption when GC is triggered in the
primop
-------------------------------------+-------------------------------------
Reporter: osa1 | Owner: (none)
Type: bug | Status: patch
Priority: highest | Milestone: 8.6.3
Component: Runtime System | Version: 8.7
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s): Phab:D5342
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by Ömer Sinan Ağacan

#15906: Stable name allocation causes heap corruption when GC is triggered in the primop -------------------------------------+------------------------------------- Reporter: osa1 | Owner: (none) Type: bug | Status: merge Priority: highest | Milestone: 8.6.3 Component: Runtime System | Version: 8.7 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D5342 Wiki Page: | -------------------------------------+------------------------------------- Changes (by osa1): * status: patch => merge -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15906#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#15906: Stable name allocation causes heap corruption when GC is triggered in the primop -------------------------------------+------------------------------------- Reporter: osa1 | Owner: (none) Type: bug | Status: closed Priority: highest | Milestone: 8.6.3 Component: Runtime System | Version: 8.7 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D5342 Wiki Page: | -------------------------------------+------------------------------------- Changes (by bgamari): * status: merge => closed * resolution: => fixed Comment: Merged with 22cd729abc4bcda999e3563759d8cb33160e6af6. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/15906#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC