diff options
author | Erik de Castro Lopo <erikd@mega-nerd.com> | 2016-05-05 15:10:24 +1000 |
---|---|---|
committer | Erik de Castro Lopo <erikd@mega-nerd.com> | 2016-05-05 15:21:30 +1000 |
commit | b59edda69f5a92b54920b1a0e61065e4115d69f9 (patch) | |
tree | 5f7331ea421d4ee16df0c5480409fa2ef265d539 | |
parent | 2d3a1b7722af767685b68d8ac425353075fded5a (diff) | |
download | haskell-wip/erikd/remove-nat.tar.gz |
rts: Fix segfault in profiling/debug/sanity checking modewip/erikd/remove-nat
The profiling code assumes that un-used memory at the start of a block
is zero filled so the profiling code can just skip over it. However, when
compiled in DEBUG mode and with the debug sanity checking RTS flag (`-DS`)
given on the command line, the memory allocator pre-fills new blocks with
`0xaa` which causes the profiling code to segfault.
The fix is just to detect debug sanity checking and ignore any `0xaa`
filled memory. It does however mean that profiling results when debug
sanity checking is enabled may produce incorrect results.
-rw-r--r-- | rts/LdvProfile.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/rts/LdvProfile.c b/rts/LdvProfile.c index 1dfdc56b34..42081ae129 100644 --- a/rts/LdvProfile.c +++ b/rts/LdvProfile.c @@ -184,7 +184,14 @@ processNurseryForDead( void ) for (bd = MainCapability.r.rNursery->blocks; bd != NULL; bd = bd->link) { p = bd->start; while (p < bd->free) { + // The start of the block may be zero filled which we need to skip + // over. while (p < bd->free && !*p) p++; // skip slop + + // In debug mode, with sanity checking enabled, the start of the + // block may be filled with `0xaa` so if we find it, we just break. + IF_DEBUG(sanity, if (*((StgWord32*)p) == 0xaaaaaaaa) break;); + if (p >= bd->free) break; p += processHeapClosureForDead((StgClosure *)p); } |