Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Sign in / Register
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Locked Files
  • Issues 5,255
    • Issues 5,255
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 562
    • Merge requests 562
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
    • Test Cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • Value stream
    • 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
  • #17088
Closed
Open
Issue created Aug 20, 2019 by Khudyakov@trac-Khudyakov

Deterministic crash in compiled program

Summary

I have program which crashes reliably with both GHC 8.4 & 8.6: coin-node.hs

Steps to reproduce

  1. To compile use: ghc --make -O1 -debug -rtsopts ./exe/coin-node.hs Crash happens if -O1/-O2 is specified. With -O0 program finish normally
  2. Run with ./coin-node +RTS -c -V0 -i0 -DS -A256k. Both -c and -A flags are necessary. Either removing -c or increasing -A makes crash go away so it's clearly related to GC somehow.
  3. -dcore-lint shows no errors

Low level code comes from memory package. Crash itself is deterministic and always happens in the same place. However test case is fragile and depends on forcing values in particular order. For example removing bang from pubK makes crash go away

Expected behavior

I expect programs compiled by GHC to not crash unless one gets way too playful with bits.

Core dump analysis

Crash happens in comparing two MutableByteArray# wrappers for equality:

   0x00000000004041ac <+316>:   mov    rsi,QWORD PTR [rdx+0x8]
   0x00000000004041b0 <+320>:   mov    rdi,QWORD PTR [rbp+0x10]
=> 0x00000000004041b4 <+324>:   cmp    rsi,QWORD PTR [rdi+0x8]

rdi's content is 0x0000420000700000 which is not valid address. However:

(rr) x/* ($rdi >> 8)
0x490680 <stg_ARR_WORDS_info>:  0x4657bfb8
(rr) x/g ($rdi >> 8) + 8
0x4200007008:   0x0000000000000001
(rr) x/8b ($rdi >> 8) + 8 +8
0x4200007010:   0x01    0xaa    0xaa    0xaa    0xaa    0xaa    0xaa    0xaa

So it does point to correct byte array except it got shifted by 8 bits somehow. Using rr one could find how that value gets stored onto stack(?):

   0x000000000040412c <+188>:   mov    rcx,QWORD PTR [rax+0x7]
=> 0x0000000000404130 <+192>:   mov    QWORD PTR [rbp-0x10],rcx

Very suspicious thing is load from rax+7. Indeed if we load from rax + 8 we'll get correct value. My only hypothesis is that rax expected to contain tagged pointer but that tag got lost somehow. rax = 0x42000bf708 so all tag bits are clear.

Environment

  • GHC version used: 8.4.4, 8.6.4, 8.6.5
  • Operating System: Linux
  • System Architecture: x64
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking