
#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@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