summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Slusarz <marcin.slusarz@gmail.com>2011-09-17 14:14:42 +0200
committerMarcin Slusarz <marcin.slusarz@gmail.com>2011-09-17 23:07:05 +0200
commit51af6a1f03d61fb6a86abaa6226c52131b96bbb6 (patch)
treebcd4f4029c8876cc3970bebbc70dd572a1cc7c9d
parent25614a610f4fe5b6516696238161c476b63ab2ed (diff)
mmt: add runtime checks
-rw-r--r--mmt/mmt_instrument.c2
-rw-r--r--mmt/mmt_trace.c204
-rw-r--r--mmt/mmt_trace.h4
3 files changed, 208 insertions, 2 deletions
diff --git a/mmt/mmt_instrument.c b/mmt/mmt_instrument.c
index fa591c82..a428285b 100644
--- a/mmt/mmt_instrument.c
+++ b/mmt/mmt_instrument.c
@@ -28,8 +28,6 @@
#include "pub_tool_libcprint.h"
#include "pub_tool_libcassert.h"
-#define maybe_unused __attribute__((unused))
-
int dump_load = True, dump_store = True;
static maybe_unused void
diff --git a/mmt/mmt_trace.c b/mmt/mmt_trace.c
index 50c620e2..369f6d0f 100644
--- a/mmt/mmt_trace.c
+++ b/mmt/mmt_trace.c
@@ -57,6 +57,174 @@ static int neg_regions_number;
#define unlikely(x) __builtin_expect(!!(x), 0)
#define noinline __attribute__((noinline))
+static maybe_unused void dump_state(void)
+{
+ int i;
+ if (neg_regions_number == 0)
+ VG_(printf)("NEGative cache empty\n");
+ else
+ {
+ VG_(printf)("NEG vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n");
+ struct negative_region *reg = neg_regions;
+ for (i = 0; i < neg_regions_number; ++i, ++reg)
+ VG_(printf)("NEG <0x%016lx 0x%016lx> %16d\n", reg->start, reg->end, reg->score);
+ VG_(printf)("NEG ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
+ }
+
+ if (mmt_last_region < 0)
+ VG_(printf)("POS mmap list empty\n");
+ else
+ {
+ VG_(printf)("POS vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n");
+ struct mmt_mmap_data *region = mmt_mmaps;
+ for (i = 0; i <= mmt_last_region; ++i, ++region)
+ VG_(printf)("POS %05d, id: %05d, start: 0x%016lx, end: 0x%016lx\n", i, region->id, region->start, region->end);
+ VG_(printf)("POS ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n");
+ }
+}
+
+static maybe_unused void __verify_state(void)
+{
+ int i, j;
+ struct negative_region *neg1 = neg_regions;
+ struct negative_region *neg2;
+ struct mmt_mmap_data *pos1, *pos2;
+
+#ifdef MMT_DEBUG_VERBOSE
+ dump_state();
+#endif
+
+ for (i = 0; i < neg_regions_number; ++i, ++neg1)
+ {
+ tl_assert2(neg1->start <= neg1->end, "%p %p", (void *)neg1->start, (void *)neg1->end);
+
+ tl_assert2(neg1->score >= 0, "score: %d", neg1->score);
+
+ /* score order */
+ if (i > 0)
+ tl_assert2(neg1->score <= neg1[-1].score, "score: %d, prev score: %d", neg1->score, neg1[-1].score);
+
+ if (neg1->end > 0 && neg1->end != (Addr)-1)
+ {
+ int found = 0;
+ pos1 = mmt_mmaps;
+ for (j = 0; j <= mmt_last_region; ++j, ++pos1)
+ if (neg1->end == pos1->start)
+ {
+ found = 1;
+ break;
+ }
+ tl_assert2(found, "end of negative region %d (<%p, %p>) does not touch start of positive region",
+ i, (void *)neg1->start, (void *)neg1->end);
+ }
+
+ if (neg1->start > 0)
+ {
+ int found = 0;
+ pos1 = mmt_mmaps;
+ for (j = 0; j <= mmt_last_region; ++j, ++pos1)
+ if (neg1->start == pos1->end)
+ {
+ found = 1;
+ break;
+ }
+ tl_assert2(found, "start of negative region %d (<%p, %p>) does not touch end of positive region",
+ i, (void *)neg1->start, (void *)neg1->end);
+ }
+
+ neg2 = neg_regions;
+ for (j = 0; j < neg_regions_number; ++j, ++neg2)
+ {
+ if (i == j)
+ continue;
+
+ /* negative regions should not be adjacent */
+ tl_assert2(neg1->start != neg2->end, "<%p, %p> <%p, %p>",
+ (void *)neg1->start, (void *)neg1->end,
+ (void *)neg2->start, (void *)neg2->end);
+ tl_assert2(neg1->end != neg2->start, "<%p, %p> <%p, %p>",
+ (void *)neg1->start, (void *)neg1->end,
+ (void *)neg2->start, (void *)neg2->end);
+
+ /* start or end are not within other region */
+ tl_assert2(neg1->start < neg2->start || neg1->start >= neg2->end,
+ "<%p, %p> <%p, %p>",
+ (void *)neg1->start, (void *)neg1->end,
+ (void *)neg2->start, (void *)neg2->end);
+ tl_assert2(neg1->end < neg2->start || neg1->end >= neg2->end,
+ "<%p, %p> <%p, %p>",
+ (void *)neg1->start, (void *)neg1->end,
+ (void *)neg2->start, (void *)neg2->end);
+ }
+ }
+
+ /* negative regions after last should be empty */
+ for (i = neg_regions_number; i < NEG_REGS; ++i, ++neg1)
+ tl_assert(neg1->start == 0 && neg1->end == 0 && neg1->score == 0);
+
+ pos1 = mmt_mmaps;
+ for (i = 0; i <= mmt_last_region; ++i, ++pos1)
+ {
+ /* order */
+ tl_assert(pos1->start <= pos1->end);
+
+ /* all regions must have an id */
+ tl_assert(pos1->id > 0);
+
+ /* if it's a real region, it must have a file descriptor */
+ if (pos1->end > 0)
+ tl_assert(pos1->fd > 0);
+
+ pos2 = mmt_mmaps;
+ for (j = 0; j <= mmt_last_region; ++j, ++pos2)
+ {
+ if (i == j)
+ continue;
+
+ /* start or end are not within other region */
+ tl_assert2(pos1->start < pos2->start || pos1->start >= pos2->end,
+ "<%p, %p> <%p, %p>",
+ (void *)pos1->start, (void *)pos1->end,
+ (void *)pos2->start, (void *)pos2->end);
+ tl_assert2(pos1->end <= pos2->start || pos1->end >= pos2->end,
+ "<%p, %p> <%p, %p>",
+ (void *)pos1->start, (void *)pos1->end,
+ (void *)pos2->start, (void *)pos2->end);
+ }
+ }
+
+ /* positive regions after last should be empty */
+ for (i = mmt_last_region + 1; i < MMT_MAX_REGIONS; ++i, ++pos1)
+ {
+ tl_assert2(pos1->start == 0, "%p", (void *)pos1->start);
+ tl_assert2(pos1->end == 0, "%p", (void *)pos1->end);
+ tl_assert2(pos1->fd == 0, "%d", pos1->fd);
+ tl_assert2(pos1->id == 0, "%u", pos1->id);
+ tl_assert2(pos1->offset == 0, "%lld", pos1->offset);
+ tl_assert2(pos1->data1 == 0, "%lu", pos1->data1);
+ tl_assert2(pos1->data2 == 0, "%lu", pos1->data2);
+ }
+
+ if (last_used_region)
+ {
+ /* there must be at least one positive region, we are pointing at it! */
+ tl_assert(mmt_last_region >= 0);
+
+ /* within possible range */
+ tl_assert(last_used_region >= &mmt_mmaps[0]);
+ tl_assert(last_used_region <= &mmt_mmaps[mmt_last_region]);
+
+ /* it must be real region */
+ tl_assert(last_used_region->start < last_used_region->end);
+ }
+}
+static void verify_state(void)
+{
+#ifdef MMT_DEBUG
+ __verify_state();
+#endif
+}
+
static inline struct mmt_mmap_data *__mmt_bsearch(Addr addr, int *next)
{
int start = 0, end = mmt_last_region, middle;
@@ -67,6 +235,15 @@ static inline struct mmt_mmap_data *__mmt_bsearch(Addr addr, int *next)
middle = start + (end - start) / 2;
tmp = &mmt_mmaps[middle];
+#ifdef MMT_DEBUG
+ tl_assert2(start >= 0 && start <= mmt_last_region,
+ "%d %d", start, mmt_last_region);
+ tl_assert2(middle >= 0 && middle <= mmt_last_region,
+ "%d %d", middle, mmt_last_region);
+ tl_assert2(end >= 0 && end <= mmt_last_region,
+ "%d %d", end, mmt_last_region);
+#endif
+
if (addr < tmp->start)
{
if (end == middle)
@@ -80,16 +257,31 @@ static inline struct mmt_mmap_data *__mmt_bsearch(Addr addr, int *next)
}
*next = start;
+#ifdef MMT_DEBUG
+ for(start = 0; start <= mmt_last_region; ++start)
+ tl_assert2(addr < mmt_mmaps[start].start || addr >= mmt_mmaps[start].end,
+ "%p in %d<%p, %p>", (void *)addr, start, (void *)mmt_mmaps[start].start,
+ (void *)mmt_mmaps[start].end);
+ tl_assert2(*next <= mmt_last_region + 1, "*prev: %d, mmt_last_region: %d, addr: %p",
+ *next, mmt_last_region, (void *)addr);
+#endif
+
return NULL;
}
static void add_neg(Addr start, Addr end)
{
+#ifdef MMT_DEBUG_VERBOSE
+ VG_(printf)("adding negative entry: <%p, %p>\n", (void *)start, (void *)end);
+#endif
+
if (neg_regions_number < NEG_REGS)
neg_regions_number++;
neg_regions[neg_regions_number - 1].start = start;
neg_regions[neg_regions_number - 1].end = end;
neg_regions[neg_regions_number - 1].score = 0;
+
+ verify_state();
}
/* finds region to which addr belongs to */
@@ -262,6 +454,10 @@ void mmt_free_region(struct mmt_mmap_data *m)
Addr end = m->end;
int joined = 0;
+#ifdef MMT_DEBUG_VERBOSE
+ VG_(printf)("freeing region: <%p, %p>\n", (void *)start, (void *)end);
+#endif
+
/* are we freeing region adjacent to negative region?
* if yes, then extend negative region */
for (i = 0; i < neg_regions_number; ++i)
@@ -385,6 +581,8 @@ void mmt_free_region(struct mmt_mmap_data *m)
}
}
}
+
+ verify_state();
}
struct mmt_mmap_data *mmt_add_region(int fd, Addr start, Addr end,
@@ -393,6 +591,10 @@ struct mmt_mmap_data *mmt_add_region(int fd, Addr start, Addr end,
struct mmt_mmap_data *region;
int i;
+#ifdef MMT_DEBUG_VERBOSE
+ VG_(printf)("adding region: <%p, %p>\n", (void *)start, (void *)end);
+#endif
+
tl_assert2(mmt_last_region + 1 < MMT_MAX_REGIONS, "not enough space for new mmap!");
if (start >= mmt_mmaps[mmt_last_region].end)
@@ -434,6 +636,8 @@ struct mmt_mmap_data *mmt_add_region(int fd, Addr start, Addr end,
region->data1 = data1;
region->data2 = data2;
+ verify_state();
+
return region;
}
diff --git a/mmt/mmt_trace.h b/mmt/mmt_trace.h
index 06393634..d29876bd 100644
--- a/mmt/mmt_trace.h
+++ b/mmt/mmt_trace.h
@@ -10,6 +10,8 @@
#endif
//#define MMT_PRINT_FILENAMES
+#define MMT_DEBUG
+//#define MMT_DEBUG_VERBOSE
#define MMT_MAX_TRACE_FILES 10
#define MMT_MAX_REGIONS 1000
@@ -28,6 +30,8 @@ struct mmt_trace_file {
fd_set fds;
};
+#define maybe_unused __attribute__((unused))
+
extern int mmt_trace_opens;
extern struct mmt_trace_file mmt_trace_files[MMT_MAX_TRACE_FILES];
extern int mmt_trace_all_files;