From: Jeremy Fitzhardinge Date: Mon, 22 Dec 2003 10:58:06 +0000 (+0000) Subject: Fixed munmap bug - split_segment wasn't updating the lengths properly. X-Git-Tag: svn/VALGRIND_2_1_1~158 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e468324c92b9858fd1e62aaa90eeacd7cb2c8242;p=thirdparty%2Fvalgrind.git Fixed munmap bug - split_segment wasn't updating the lengths properly. Turn off debug printing. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2144 --- diff --git a/coregrind/vg_memory.c b/coregrind/vg_memory.c index c8b42baabe..ecb1d5c108 100644 --- a/coregrind/vg_memory.c +++ b/coregrind/vg_memory.c @@ -141,6 +141,7 @@ Segment *VG_(split_segment)(Addr a) ns->addr += delta; ns->offset += delta; ns->len -= delta; + s->len = delta; if (s->filename != NULL) ns->filename = VG_(arena_strdup)(VG_AR_CORE, s->filename); @@ -159,7 +160,7 @@ void VG_(unmap_range)(Addr addr, UInt len) { Segment *s; Segment *next; - static const Bool debug = True || mem_debug; + static const Bool debug = False || mem_debug; Addr end; if (len == 0) @@ -206,30 +207,30 @@ void VG_(unmap_range)(Addr addr, UInt len) if (debug) VG_(printf)(" case 1: s->len=%d\n", s->len); - } else if (addr <= s->addr && end >= seg_end) { - /* this segment is completely contained within [addr, addr+len) - -> delete segment - */ - Segment *rs = VG_(SkipList_Remove)(&sk_segments, &s->addr); - vg_assert(rs == s); - freeseg(s); - - if (debug) - VG_(printf)(" case 2: s==%p deleted\n", s); } else if (addr <= s->addr && end > s->addr && end < seg_end) { /* this segment's head is truncated by [addr, addr+len) -> truncate head */ - Int delta = (addr+len) - s->addr; + Int delta = end - s->addr; if (debug) - VG_(printf)(" case 3: s->addr=%p s->len=%d delta=%d\n", s->addr, s->len, delta); + VG_(printf)(" case 2: s->addr=%p s->len=%d delta=%d\n", s->addr, s->len, delta); s->addr += delta; s->offset += delta; s->len -= delta; vg_assert(s->len != 0); + } else if (addr <= s->addr && end >= seg_end) { + /* this segment is completely contained within [addr, addr+len) + -> delete segment + */ + Segment *rs = VG_(SkipList_Remove)(&sk_segments, &s->addr); + vg_assert(rs == s); + freeseg(s); + + if (debug) + VG_(printf)(" case 3: s==%p deleted\n", s); } else if (addr > s->addr && end < seg_end) { /* [addr, addr+len) is contained within a single segment -> split segment into 3, delete middle portion @@ -488,9 +489,9 @@ void VG_(mprotect_range)(Addr a, UInt len, UInt prot) Addr VG_(find_map_space)(Addr addr, UInt len, Bool for_client) { + static const Bool debug = False || mem_debug; Segment *s; Addr ret; - static const Bool debug = False || mem_debug; Addr limit = (for_client ? VG_(client_end) : VG_(valgrind_mmap_end)); if (addr == 0) diff --git a/none/tests/map_unmap.c b/none/tests/map_unmap.c index 16a6d11e57..db47d240d6 100644 --- a/none/tests/map_unmap.c +++ b/none/tests/map_unmap.c @@ -26,15 +26,24 @@ static void nibblemap(void *p) int off; int i; - off = (random() & ~0x1fff) % LEN; + off = (random() % LEN) & ~(pagesize-1); for(i = 0; i < PAGES; i++) { + /* printf("unmapping off=%d\n", off/pagesize); */ munmap((char *)p + off, pagesize); off += 619*pagesize; off %= LEN; } } +static void prmaps() +{ + char buf[100]; + sprintf(buf, "/bin/cat /proc/%d/maps", getpid()); + system(buf); + exit(1); +} + int main() { int i; @@ -46,19 +55,22 @@ int main() expect2 = domap(); munmap(expect1, LEN); munmap(expect2, LEN); + for(i = 0; i < 1000; i++) { void *m1, *m2; m1 = domap(); if (m1 != expect1) { - printf("FAIL: m=%p expect=%p\n", - m1, expect1); + printf("FAIL i=%d: m1=%p expect1=%p\n", + i, m1, expect1); + prmaps(); return 1; } m2 = domap(); if (m2 != expect2) { - printf("FAIL: m=%p expect=%p\n", - m2, expect2); + printf("FAIL i=%d: m2=%p expect2=%p\n", + i, m2, expect2); + prmaps(); return 1; } nibblemap(m2);