|
From: Jeremy F. <je...@go...> - 2005-02-09 23:08:34
|
CVS commit by fitzhardinge:
Fix mmap-related sanity failure. If we merge segments over-eagerly (ie,
we do it, but the kernel doesn't merge the corresponding mappings),
the segment/map sanity check fails. Not merging is always safe, so
avoid merging on mappings for now.
BUGS:98966
M +24 -6 coregrind/vg_memory.c 1.89
M +2 -0 coregrind/vg_scheduler.c 1.220
M +3 -0 coregrind/vg_signals.c 1.120
M +1 -1 coregrind/vg_syscalls.c 1.244
M +1 -0 none/tests/map_unmap.vgtest 1.2
M +1 -0 none/tests/sigstackgrowth.vgtest 1.2
M +1 -0 none/tests/stackgrowth.vgtest 1.2
--- valgrind/coregrind/vg_memory.c #1.88:1.89
@@ -191,4 +191,5 @@ void VG_(unmap_range)(Addr addr, SizeT l
vg_assert((len & (VKI_PAGE_SIZE-1)) == 0);
+ /* For each segment in the range covered by the unmap... */
for(s = VG_(SkipList_Find_Before)(&sk_segments, &addr);
s != NULL && s->addr < (addr+len);
@@ -226,5 +227,5 @@ void VG_(unmap_range)(Addr addr, SizeT l
-> truncate head
*/
- Int delta = end - s->addr;
+ UInt delta = end - s->addr;
if (debug)
@@ -440,5 +441,11 @@ void VG_(map_file_segment)(Addr addr, Si
}
- /* clean up */
+ /* Don't merge for now. The problem is that if we over-merge (we
+ merge segments, but the kernel didn't merge the corresponding
+ mappings), it confuses the sanity-checking machinery.
+ Under-merging (the kernel merges but we don't) is not a problem.
+ FIXME: stack growth probably creates lots of mergable segments;
+ maybe there should be a separate segment-extending call. */
+ if (0)
merge_segments(addr, len);
}
@@ -1061,9 +1068,10 @@ const Char *VG_(prot_str)(UInt prot)
static Bool segment_maps_ok;
static Addr prevmapstart, prevmapend;
+static Bool check_verbose;
static void check_segment_maps(Addr addr, SizeT len, UInt prot,
UInt dev, UInt ino, ULong foff, const UChar *filename)
{
- static const Bool debug = 0;
+ const Bool debug = 0 || check_verbose;
Addr segend;
@@ -1269,6 +1277,7 @@ Bool VG_(sanity_check_memory)(void)
}
- next_segment = VG_(first_segment)();
+ check_verbose = False;
segment_maps_ok = True;
+ next_segment = VG_(first_segment)();
prevmapstart = prevmapend = 0;
VG_(parse_procselfmaps)(check_segment_maps);
@@ -1281,4 +1290,13 @@ Bool VG_(sanity_check_memory)(void)
}
+ if (!segment_maps_ok) {
+ VG_(printf)("\n\nvvvvv SEGMENT MAPS NOT OK vvvvv\n");
+ check_verbose = True;
+ next_segment = VG_(first_segment)();
+ prevmapstart = prevmapend = 0;
+ VG_(parse_procselfmaps)(check_segment_maps);
+ VG_(printf)("^^^^^ SEGMENT MAPS NOT OK ^^^^^\n\n");
+ }
+
ok = ok && segment_maps_ok;
--- valgrind/coregrind/vg_scheduler.c #1.219:1.220
@@ -723,4 +723,6 @@ VgSchedReturnCode VG_(scheduler) ( Threa
case VG_TRC_EBP_JMP_SYSCALL:
handle_syscall(tid);
+ if (VG_(clo_sanity_level) > 2)
+ VG_(sanity_check_general)(True); /* sanity-check every syscall */
break;
--- valgrind/coregrind/vg_signals.c #1.119:1.120
@@ -1669,4 +1669,7 @@ Bool VG_(extend_stack)(Addr addr, UInt m
base, newsize);
+ if (VG_(clo_sanity_level) > 2)
+ VG_(sanity_check_general)(False);
+
return True;
}
--- valgrind/coregrind/vg_syscalls.c #1.243:1.244
@@ -4327,5 +4327,5 @@ PRE(sys_mmap2, 0)
// - the file offset is specified in pagesize units rather than bytes,
// so that it can be used for files bigger than 2^32 bytes.
- PRINT("sys_mmap2 ( %p, %llu, %d, %d, %d, %d )",
+ PRINT("sys_mmap2 ( %p, %llu, 0x%x, 0x%x, %d, %d )",
arg1, (ULong)arg2, arg3, arg4, arg5, arg6 );
PRE_REG_READ6(long, "mmap2",
--- valgrind/none/tests/map_unmap.vgtest #1.1:1.2
@@ -1 +1,2 @@
prog: map_unmap
+vgopts: --sanity-level=3
--- valgrind/none/tests/sigstackgrowth.vgtest #1.1:1.2
@@ -1 +1,2 @@
prog: sigstackgrowth
+vgopts: --sanity-level=3
--- valgrind/none/tests/stackgrowth.vgtest #1.1:1.2
@@ -1 +1,2 @@
prog: stackgrowth
+vgopts: --sanity-level=3
|