[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