[GHC] #15038: Memory Corruption (strange closure type)

GHC ghc-devs at haskell.org
Fri Apr 27 12:28:08 UTC 2018


#15038: Memory Corruption (strange closure type)
-------------------------------------+-------------------------------------
        Reporter:  andrewthad        |                Owner:  (none)
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:  8.6.1
       Component:  Compiler          |              Version:  8.4.1
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  Runtime crash     |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by osa1):

 I spent some more time debugging this. Basically at one point the GC
 overwrites an info table, messing up the type field.

 {{{
 $ gdb ./Main -nh
 Reading symbols from ./Main...done.
 (gdb) start
 Temporary breakpoint 1 at 0x40d29e
 Starting program: /home/omer/haskell/corrupted-memory-example/Main
 [Thread debugging using libthread_db enabled]
 Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

 Temporary breakpoint 1, 0x000000000040d29e in main ()
 }}}

 Now I can see that type of an info table is `CONSTR_2_0`:

 {{{
 (gdb) print get_itbl(0x9815f8)->type
 $1 = 4
 }}}

 Now continue until it crashes:

 {{{
 (gdb) c
 Continuing.
 Main: internal error: evacuate(static): strange closure type 16580
     (GHC version 8.5.20180425 for x86_64_unknown_linux)
     Please report this as a GHC bug:
 http://www.haskell.org/ghc/reportabug

 Program received signal SIGABRT, Aborted.
 0x00007ffff6e90428 in __GI_raise (sig=sig at entry=6) at
 ../sysdeps/unix/sysv/linux/raise.c:54
 54      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
 }}}

 and at this point the same info table has wrong type field:

 {{{
 (gdb) print get_itbl(0x9815f8)->type
 $2 = 16580
 }}}

 Adding a watchpoint to this location causes gdb to leak memory so I
 couldn't do it from the start. I realized that this happens when evacuate
 is called 143851nd time so I run the program until that call, then enable
 the watchpoint, and continue. First hit is

 {{{
 Watchpoint 3: get_itbl(0x9815f8)->type

 Old value = 4
 New value = 0
 evacuate_static_object (link_field=0x9815f8, q=0x9815f0) at
 rts/sm/Evac.c:347
 347             gct->static_objects = (StgClosure *)new_list_head;

 (gdb) bt
 #0  evacuate_static_object (link_field=0x9815f8, q=0x9815f0) at
 rts/sm/Evac.c:347
 #1  0x00000000008e79e0 in evacuate (p=0x981608) at rts/sm/Evac.c:546
 #2  0x0000000000910c29 in scavenge_static () at rts/sm/Scav.c:1831
 #3  0x00000000009111f8 in scavenge_loop () at rts/sm/Scav.c:2185
 #4  0x00000000008e34bb in scavenge_until_all_done () at rts/sm/GC.c:1092
 #5  0x00000000008e2118 in GarbageCollect (collect_gen=1,
 do_heap_census=false, gc_type=0, cap=0xad4080 <MainCapability>,
 idle_cap=0x0) at rts/sm/GC.c:418
 #6  0x00000000008d4dfb in scheduleDoGC (pcap=0x7fffffffd630,
 task=0xaebd00, force_major=false) at rts/Schedule.c:1799
 #7  0x00000000008d4347 in schedule (initialCapability=0xad4080
 <MainCapability>, task=0xaebd00) at rts/Schedule.c:545
 #8  0x00000000008d57a1 in scheduleWaitThread (tso=0x4200105388, ret=0x0,
 pcap=0x7fffffffd720) at rts/Schedule.c:2533
 #9  0x00000000008d7997 in rts_evalLazyIO (cap=0x7fffffffd720, p=0x981710,
 ret=0x0) at rts/RtsAPI.c:530
 #10 0x00000000008d808a in hs_main (argc=1, argv=0x7fffffffd918,
 main_closure=0x981710, rts_config=...) at rts/RtsMain.c:72
 #11 0x000000000040d39a in main ()
 }}}

 Here it gets overwritten to `0`. When I continue it gets overwritten one
 more time:

 {{{
 (gdb) c
 Continuing.

 Watchpoint 3: get_itbl(0x9815f8)->type

 Old value = 0
 New value = 16580
 scavenge_static () at rts/sm/Scav.c:1789
 1789        gct->scavenged_static_objects = flagged_p;

 (gdb) bt
 #0  scavenge_static () at rts/sm/Scav.c:1789
 #1  0x00000000009111f8 in scavenge_loop () at rts/sm/Scav.c:2185
 #2  0x00000000008e34bb in scavenge_until_all_done () at rts/sm/GC.c:1092
 #3  0x00000000008e2118 in GarbageCollect (collect_gen=1,
 do_heap_census=false, gc_type=0, cap=0xad4080 <MainCapability>,
 idle_cap=0x0) at rts/sm/GC.c:418
 #4  0x00000000008d4dfb in scheduleDoGC (pcap=0x7fffffffd630,
 task=0xaebd00, force_major=false) at rts/Schedule.c:1799
 #5  0x00000000008d4347 in schedule (initialCapability=0xad4080
 <MainCapability>, task=0xaebd00) at rts/Schedule.c:545
 #6  0x00000000008d57a1 in scheduleWaitThread (tso=0x4200105388, ret=0x0,
 pcap=0x7fffffffd720) at rts/Schedule.c:2533
 #7  0x00000000008d7997 in rts_evalLazyIO (cap=0x7fffffffd720, p=0x981710,
 ret=0x0) at rts/RtsAPI.c:530
 #8  0x00000000008d808a in hs_main (argc=1, argv=0x7fffffffd918,
 main_closure=0x981710, rts_config=...) at rts/RtsMain.c:72
 #9  0x000000000040d39a in main ()
 }}}

 The value `16580` is what we see in the error message.

 I don't know if this is a problem with GC, maybe it's something wrong with
 the code gen.

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15038#comment:14>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list