|
From: <sv...@va...> - 2005-09-22 23:58:44
|
Author: sewardj
Date: 2005-09-23 00:58:38 +0100 (Fri, 23 Sep 2005)
New Revision: 4724
Log:
Simplify the sanity checker a little, and make it able to deal with
the case where one SkAnon? segment is corresponds to two adjacent
un-merged kernel segments.
Modified:
branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c
Modified: branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c 2005-09-22 21:28:1=
1 UTC (rev 4723)
+++ branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c 2005-09-22 23:58:3=
8 UTC (rev 4724)
@@ -124,7 +124,11 @@
=20
/* ------ end of STATE for the address-space manager ------ */
=20
+// Forwards decls
+static void aspacem_exit ( Int );
+static Int find_nsegment_idx ( Addr a );
=20
+
/*-----------------------------------------------------------------*/
/*--- ---*/
/*--- Stuff to make aspacem almost completely independent of ---*/
@@ -132,9 +136,6 @@
/*--- ---*/
/*-----------------------------------------------------------------*/
=20
-// Forwards decl
-static void aspacem_exit ( Int );
-
//--------------------------------------------------------------
// Simple assert and assert-like fns, which avoid dependence on
// m_libcassert, and hence on the entire debug-info reader swamp
@@ -804,85 +805,90 @@
/* Check the segment array corresponds with the kernel's view of
memory layout. sync_check_ok returns True if no anomalies were
found, else False. In the latter case the mismatching segments are
- displayed. */
+ displayed.=20
=20
-static Int sync_check_i =3D 0;
+ The general idea is: we get the kernel to show us all its segments
+ and also the gaps in between. For each such interval, try and find
+ a sequence of appropriate intervals in our segment array which
+ cover or more than cover the kernel's interval, and which all have
+ suitable kinds/permissions etc.=20
+
+ Although any specific kernel interval is not matched exactly to a
+ valgrind interval or sequence thereof, eventually any disagreement
+ on mapping boundaries will be detected. This is because, if for
+ example valgrind's intervals cover a greater range than the current
+ kernel interval, it must be the case that a neighbouring free-space
+ interval belonging to valgrind cannot cover the neighbouring
+ free-space interval belonging to the kernel. So the disagreement
+ is detected.
+
+ In other words, we examine each kernel interval in turn, and check
+ we do not disagree over the range of that interval. Because all of
+ the address space is examined, any disagreements must eventually be
+ detected.
+*/
+
static Bool sync_check_ok =3D False;
=20
static void sync_check_mapping_callback ( Addr addr, SizeT len, UInt pro=
t,
UInt dev, UInt ino, ULong offs=
et,=20
const UChar* filename )
{
+ Int iLo, iHi, i;
+
/* If a problem has already been detected, don't continue comparing
segments, so as to avoid flooding the output with error
messages. */
if (!sync_check_ok)
return;
=20
- /* The start of this kernel mapping should fall within the
- current segment.*/
- if (addr < nsegments[sync_check_i].start ||
- addr > nsegments[sync_check_i].end) {
- sync_check_ok =3D False;
- VG_(debugLog)(0,"aspacem",
- "sync_check_mapping_callback: segment mismatch: V's =
seg:\n");
- show_nsegment_full( 0, &nsegments[sync_check_i] );
- goto show_kern_seg;
- }
+ if (len =3D=3D 0)
+ return;
=20
- /* Check that any segments that fall within this mapping
- have attributes which match the mapping. */
- while (sync_check_i < nsegments_used &&
- nsegments[sync_check_i].start < addr+len &&
- nsegments[sync_check_i].end >=3D addr ) {
- Bool same;
+ /* The kernel should not give us wraparounds. */
+ aspacem_assert(addr <=3D addr + len - 1);=20
+
+ iLo =3D find_nsegment_idx( addr );
+ iHi =3D find_nsegment_idx( addr + len - 1 );
+
+ /* These 5 should be guaranteed by find_nsegment_idx. */
+ aspacem_assert(0 <=3D iLo && iLo < nsegments_used);
+ aspacem_assert(0 <=3D iHi && iHi < nsegments_used);
+ aspacem_assert(iLo <=3D iHi);
+ aspacem_assert(nsegments[iLo].start <=3D addr );
+ aspacem_assert(nsegments[iHi].end >=3D addr + len - 1 );
+
+ /* NSegments iLo .. iHi inclusive should agree with the presented
+ data. */
+ for (i =3D iLo; i <=3D iHi; i++) {
+
+ Bool same, cmp_offsets;
=20
/* compare the kernel's offering against ours. */
- same =3D nsegments[sync_check_i].kind =3D=3D SkAnonC
- || nsegments[sync_check_i].kind =3D=3D SkAnonV
- || nsegments[sync_check_i].kind =3D=3D SkFileC
- || nsegments[sync_check_i].kind =3D=3D SkFileV;
+ same =3D nsegments[i].kind =3D=3D SkAnonC
+ || nsegments[i].kind =3D=3D SkAnonV
+ || nsegments[i].kind =3D=3D SkFileC
+ || nsegments[i].kind =3D=3D SkFileV;
+
+ cmp_offsets
+ =3D nsegments[i].kind =3D=3D SkFileC || nsegments[i].kind =3D=3D=
SkFileV;
+
same =3D same
- && nsegments[sync_check_i].dev =3D=3D dev
- && nsegments[sync_check_i].ino =3D=3D ino
- && nsegments[sync_check_i].start-nsegments[sync_check_i].of=
fset =3D=3D addr-offset;
+ && nsegments[i].dev =3D=3D dev
+ && nsegments[i].ino =3D=3D ino
+ && (cmp_offsets=20
+ ? nsegments[i].start-nsegments[i].offset =3D=3D addr-=
offset
+ : True);
if (!same) {
sync_check_ok =3D False;
- VG_(debugLog)(0,"aspacem",
- "sync_check_mapping_callback: segment mismatch: V=
's seg:\n");
- show_nsegment_full( 0, &nsegments[sync_check_i] );
+ VG_(debugLog)(
+ 0,"aspacem",
+ "sync_check_mapping_callback: segment mismatch: V's seg:\n=
");
+ show_nsegment_full( 0, &nsegments[i] );
goto show_kern_seg;
}
-
- sync_check_i++;
}
=20
- /* The end of this kernel mapping should fall within the
- previous segment.*/
- if (addr+len-1 < nsegments[sync_check_i-1].start ||
- addr+len-1 > nsegments[sync_check_i-1].end) {
- sync_check_ok =3D False;
- VG_(debugLog)(0,"aspacem",
- "sync_check_mapping_callback: segment mismatch: V's =
seg:\n");
- show_nsegment_full( 0, &nsegments[sync_check_i-1] );
- goto show_kern_seg;
- }
-
- /* If this mapping ended in the middle of a segment then reduce
- sync_check_i by one so that we continue from that segment with
- the next mapping or gap. */
- if (addr+len-1 < nsegments[sync_check_i-1].end)
- sync_check_i--;
-
- /* If we've run out of segments and there is still part of a
- mapping unaccounted for then fail. */
- if (sync_check_i =3D=3D nsegments_used &&
- addr+len-1 > nsegments[sync_check_i-1].end) {
- sync_check_ok =3D False;
- VG_(debugLog)(0,"aspacem","sync_check_mapping_callback: out of seg=
ments\n");
- goto show_kern_seg;
- }
-
/* Looks harmless. Keep going. */
return;
=20
@@ -898,73 +904,50 @@
=20
static void sync_check_gap_callback ( Addr addr, SizeT len )
{
+ Int iLo, iHi, i;
+
/* If a problem has already been detected, don't continue comparing
segments, so as to avoid flooding the output with error
messages. */
if (!sync_check_ok)
return;
=20
- if (addr+len-1 > nsegments[nsegments_used-1].end)
- len =3D nsegments[nsegments_used-1].end-addr+1;
+ if (len =3D=3D 0)
+ return;
=20
- /* The start of this kernel mapping should fall within the
- current segment.*/
- if (addr < nsegments[sync_check_i].start ||
- addr > nsegments[sync_check_i].end) {
- sync_check_ok =3D False;
- VG_(debugLog)(0,"aspacem",
- "sync_check_gap_callback: segment mismatch: V's seg:=
\n");
- show_nsegment_full( 0, &nsegments[sync_check_i] );
- goto show_kern_gap;
- }
+ /* The kernel should not give us wraparounds. */
+ aspacem_assert(addr <=3D addr + len - 1);=20
=20
- /* Check that any segments that fall within this gap
- have attributes which match the mapping. */
- while (sync_check_i < nsegments_used &&
- nsegments[sync_check_i].start <=3D addr+len-1 &&
- nsegments[sync_check_i].end >=3D addr ) {
- Bool same;
+ iLo =3D find_nsegment_idx( addr );
+ iHi =3D find_nsegment_idx( addr + len - 1 );
=20
+ /* These 5 should be guaranteed by find_nsegment_idx. */
+ aspacem_assert(0 <=3D iLo && iLo < nsegments_used);
+ aspacem_assert(0 <=3D iHi && iHi < nsegments_used);
+ aspacem_assert(iLo <=3D iHi);
+ aspacem_assert(nsegments[iLo].start <=3D addr );
+ aspacem_assert(nsegments[iHi].end >=3D addr + len - 1 );
+
+ /* NSegments iLo .. iHi inclusive should agree with the presented
+ data. */
+ for (i =3D iLo; i <=3D iHi; i++) {
+
+ Bool same;
+ =20
/* compare the kernel's offering against ours. */
- same =3D nsegments[sync_check_i].kind =3D=3D SkFree
- || nsegments[sync_check_i].kind =3D=3D SkResvn;
+ same =3D nsegments[i].kind =3D=3D SkFree
+ || nsegments[i].kind =3D=3D SkResvn;
+
if (!same) {
sync_check_ok =3D False;
- VG_(debugLog)(0,"aspacem",
- "sync_check_gap_callback: segment mismatch: V's s=
eg:\n");
- show_nsegment_full( 0, &nsegments[sync_check_i] );
+ VG_(debugLog)(
+ 0,"aspacem",
+ "sync_check_mapping_callback: segment mismatch: V's gap:\n=
");
+ show_nsegment_full( 0, &nsegments[i] );
goto show_kern_gap;
}
-
- sync_check_i++;
}
=20
- /* The end of this kernel mapping should fall within the
- previous segment.*/
- if (addr+len-1 < nsegments[sync_check_i-1].start ||
- addr+len-1 > nsegments[sync_check_i-1].end) {
- sync_check_ok =3D False;
- VG_(debugLog)(0,"aspacem",
- "sync_check_gap_callback: segment mismatch: V's seg:=
\n");
- show_nsegment_full( 0, &nsegments[sync_check_i-1] );
- goto show_kern_gap;
- }
-
- /* If this gap ended in the middle of a segment then reduce
- sync_check_i by one so that we continue from that segment with
- the next mapping or gap. */
- if (addr+len-1 < nsegments[sync_check_i-1].end)=20
- sync_check_i--;
-
- /* If we've run out of segments and there is still part of a
- gap unaccounted for then fail. */
- if (sync_check_i =3D=3D nsegments_used &&
- addr+len-1 > nsegments[sync_check_i-1].end) {
- sync_check_ok =3D False;
- VG_(debugLog)(0,"aspacem","sync_check_gap_callback: out of segment=
s\n");
- goto show_kern_gap;
- }
-
/* Looks harmless. Keep going. */
return;
=20
@@ -977,9 +960,9 @@
return;
}
=20
-static Bool do_sync_check ( HChar* fn, HChar* file, Int line )
+
+ Bool do_sync_check ( HChar* fn, HChar* file, Int line )
{
- sync_check_i =3D 0;
sync_check_ok =3D True;
if (0)
VG_(debugLog)(0,"aspacem", "do_sync_check %s:%d\n", file,line);
@@ -994,7 +977,7 @@
# if 0
{
HChar buf[100];
- VG_(am_show_nsegments)(0,"post segfault");
+ VG_(am_show_nsegments)(0,"post syncheck failure");
VG_(sprintf)(buf, "/bin/cat /proc/%d/maps", VG_(getpid)());
VG_(system)(buf);
}
|