|
From: <sv...@va...> - 2005-09-21 12:01:46
|
Author: tom
Date: 2005-09-21 13:01:37 +0100 (Wed, 21 Sep 2005)
New Revision: 4719
Log:
Rework the address space sanity checker to check gaps between kernel
mappings as well as the mappings themselves and to not require there
to be exactly one valgrind segment for kernel gap/mapping.
Modified:
branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c
branches/ASPACEM/coregrind/m_aspacemgr/read_procselfmaps.c
branches/ASPACEM/coregrind/pub_core_aspacemgr.h
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-21 10:16:4=
9 UTC (rev 4718)
+++ branches/ASPACEM/coregrind/m_aspacemgr/aspacemgr.c 2005-09-21 12:01:3=
7 UTC (rev 4719)
@@ -809,49 +809,77 @@
static Int sync_check_i =3D 0;
static Bool sync_check_ok =3D False;
=20
-static void sync_check_callback ( Addr addr, SizeT len, UInt prot,
- UInt dev, UInt ino, ULong offset,=20
- const UChar* filename )
+static void sync_check_mapping_callback ( Addr addr, SizeT len, UInt pro=
t,
+ UInt dev, UInt ino, ULong offs=
et,=20
+ const UChar* filename )
{
- Bool same;
-
/* 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
- /* Advance sync_check_i to the first possible nsegment entry which
- could map the kernel's offering. It will have been left at the
- previous match. We are prepared to skip any sequence of free
- and reservation segments, but everything else must match the
- kernel's segments. */
- sync_check_i++;
+ /* 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;
+ }
=20
- while (sync_check_i < nsegments_used
- && (nsegments[sync_check_i].kind =3D=3D SkFree
- || nsegments[sync_check_i].kind =3D=3D SkResvn))
+ /* 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;
+ =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 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;
+ 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] );
+ goto show_kern_seg;
+ }
+
sync_check_i++;
+ }
=20
- aspacem_assert(sync_check_i >=3D 0 && sync_check_i <=3D nsegments_use=
d);
-
- if (sync_check_i =3D=3D nsegments_used) {
+ /* 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_callback: out of segments\n"=
);
+ 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;
}
=20
- /* compare the kernel's offering against ours. */
- same =3D nsegments[sync_check_i].start =3D=3D addr
- && nsegments[sync_check_i].end =3D=3D addr+len-1
- && nsegments[sync_check_i].dev =3D=3D dev
- && nsegments[sync_check_i].ino =3D=3D ino
- && nsegments[sync_check_i].offset =3D=3D offset;
- if (!same) {
+ /* 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_callback: segment mismatch: V's seg:\n=
");
- show_nsegment_full( 0, &nsegments[sync_check_i] );
+ VG_(debugLog)(0,"aspacem","sync_check_mapping_callback: out of seg=
ments\n");
goto show_kern_seg;
}
=20
@@ -860,7 +888,7 @@
=20
show_kern_seg:
VG_(debugLog)(0,"aspacem",
- "sync_check_callback: segment mismatch: kernel's seg:=
\n");
+ "sync_check_mapping_callback: segment mismatch: kerne=
l's seg:\n");
VG_(debugLog)(0,"aspacem",=20
"start=3D0x%llx end=3D0x%llx dev=3D%u ino=3D%u offset=
=3D%lld\n",
(ULong)addr, ((ULong)addr) + ((ULong)len) - 1,
@@ -868,13 +896,95 @@
return;
}
=20
+static void sync_check_gap_callback ( Addr addr, SizeT len )
+{
+ /* 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;
+
+ if (addr+len-1 > nsegments[nsegments_used-1].end)
+ len =3D nsegments[nsegments_used-1].end-addr+1;
+
+ /* 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;
+ }
+
+ /* 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;
+
+ /* 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;
+ 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] );
+ goto show_kern_gap;
+ }
+
+ sync_check_i++;
+ }
+
+ /* 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;
+
+ show_kern_gap:
+ VG_(debugLog)(0,"aspacem",
+ "sync_check_gap_callback: segment mismatch: kernel's =
gap:\n");
+ VG_(debugLog)(0,"aspacem",=20
+ "start=3D0x%llx end=3D0x%llx\n",
+ (ULong)addr, ((ULong)addr) + ((ULong)len) - 1 );
+ return;
+}
+
static Bool do_sync_check ( HChar* fn, HChar* file, Int line )
{
- sync_check_i =3D -1;
+ sync_check_i =3D 0;
sync_check_ok =3D True;
if (0)
VG_(debugLog)(0,"aspacem", "do_sync_check %s:%d\n", file,line);
- VG_(parse_procselfmaps)( sync_check_callback );
+ VG_(parse_procselfmaps)( sync_check_mapping_callback,
+ sync_check_gap_callback );
if (!sync_check_ok) {
VG_(debugLog)(0,"aspacem",=20
"sync check at %s:%d (%s): FAILED\n",
@@ -1369,7 +1479,7 @@
VG_(am_show_nsegments)(2, "Initial layout");
=20
VG_(debugLog)(2, "aspacem", "Reading /proc/self/maps\n");
- VG_(parse_procselfmaps) ( read_maps_callback );
+ VG_(parse_procselfmaps) ( read_maps_callback, NULL );
=20
VG_(am_show_nsegments)(2, "With contents of /proc/self/maps");
=20
Modified: branches/ASPACEM/coregrind/m_aspacemgr/read_procselfmaps.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/read_procselfmaps.c 2005-09-21=
10:16:49 UTC (rev 4718)
+++ branches/ASPACEM/coregrind/m_aspacemgr/read_procselfmaps.c 2005-09-21=
12:01:37 UTC (rev 4719)
@@ -44,6 +44,9 @@
/* Records length of /proc/self/maps read into procmap_buf. */
static Int buf_n_tot;
=20
+/* Minimum and maximum addresses */
+#define Addr_MIN ((Addr)0)
+#define Addr_MAX ((Addr)(-1ULL))
=20
/* Helper fns. */
=20
@@ -148,11 +151,12 @@
*/
void VG_(parse_procselfmaps) (
void (*record_mapping)( Addr addr, SizeT len, UInt prot,
- UInt dev, UInt ino, ULong foff, const UChar* filename )
+ UInt dev, UInt ino, ULong foff, const UChar* filename ),
+ void (*record_gap)( Addr addr, SizeT len )
)
{
Int i, j, i_eol;
- Addr start, endPlusOne;
+ Addr start, endPlusOne, gapStart;
UChar* filename;
UChar rr, ww, xx, pp, ch, tmp;
UInt ino, prot;
@@ -167,6 +171,7 @@
=20
/* Ok, it's safely aboard. Parse the entries. */
i =3D 0;
+ gapStart =3D Addr_MIN;
while (True) {
if (i >=3D buf_n_tot) break;
=20
@@ -265,6 +270,9 @@
if (ww =3D=3D 'w') prot |=3D VKI_PROT_WRITE;
if (xx =3D=3D 'x') prot |=3D VKI_PROT_EXEC;
=20
+ if (record_gap && gapStart < start)
+ (*record_gap) ( gapStart, start-gapStart );
+
(*record_mapping) ( start, endPlusOne-start,=20
prot, maj * 256 + min, ino,
foffset, filename );
@@ -274,7 +282,11 @@
}
=20
i =3D i_eol + 1;
+ gapStart =3D endPlusOne;
}
+
+ if (record_gap && gapStart < Addr_MAX)
+ (*record_gap) ( gapStart, Addr_MAX - gapStart + 1 );
}
=20
/*--------------------------------------------------------------------*/
Modified: branches/ASPACEM/coregrind/pub_core_aspacemgr.h
=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/pub_core_aspacemgr.h 2005-09-21 10:16:49 U=
TC (rev 4718)
+++ branches/ASPACEM/coregrind/pub_core_aspacemgr.h 2005-09-21 12:01:37 U=
TC (rev 4719)
@@ -46,7 +46,8 @@
void VG_(parse_procselfmaps) (
void (*record_mapping)( Addr addr, SizeT len, UInt prot,
UInt dev, UInt ino, ULong foff,
- const UChar *filename ) );
+ const UChar *filename ),
+ void (*record_gap)( Addr addr, SizeT len ) );
=20
//--------------------------------------------------------------
// Definition of address-space segments
|