aboutsummaryrefslogtreecommitdiffstats
path: root/executor
diff options
context:
space:
mode:
Diffstat (limited to 'executor')
-rw-r--r--executor/executor.cc5
-rw-r--r--executor/executor_linux.h12
2 files changed, 15 insertions, 2 deletions
diff --git a/executor/executor.cc b/executor/executor.cc
index 5b5e06422..603f23f73 100644
--- a/executor/executor.cc
+++ b/executor/executor.cc
@@ -362,6 +362,8 @@ struct cover_t {
// offset (VM_MIN_KERNEL_ADDRESS for AMD64) and then truncates the result to
// uint32_t. We get this from the 'offset' member in ksancov_trace.
intptr_t pc_offset;
+ // The coverage buffer has overflowed and we have truncated coverage.
+ bool overflow;
};
struct thread_t {
@@ -1177,6 +1179,7 @@ uint32 write_comparisons(flatbuffers::FlatBufferBuilder& fbb, cover_t* cov)
kcov_comparison_t* cov_start = (kcov_comparison_t*)(cov->data + sizeof(uint64));
if ((char*)(cov_start + ncomps) > cov->data_end)
failmsg("too many comparisons", "ncomps=%llu", ncomps);
+ cov->overflow = ((char*)(cov_start + ncomps + 1) > cov->data_end);
rpc::ComparisonRaw* start = (rpc::ComparisonRaw*)cov_start;
rpc::ComparisonRaw* end = start;
// We will convert kcov_comparison_t to ComparisonRaw inplace.
@@ -1295,6 +1298,8 @@ void write_output(int index, cover_t* cov, rpc::CallFlag flags, uint32 error, bo
}
rpc::CallInfoRawBuilder builder(*output_builder);
+ if (cov->overflow)
+ flags |= rpc::CallFlag::CoverageOverflow;
builder.add_flags(flags);
builder.add_error(error);
if (signal_off)
diff --git a/executor/executor_linux.h b/executor/executor_linux.h
index 82a1d559a..f2e9d4df6 100644
--- a/executor/executor_linux.h
+++ b/executor/executor_linux.h
@@ -180,14 +180,22 @@ static void cover_reset(cover_t* cov)
cover_unprotect(cov);
*(uint64*)cov->data = 0;
cover_protect(cov);
+ cov->overflow = false;
+}
+
+template <typename cover_data_t>
+static void cover_collect_impl(cover_t* cov)
+{
+ cov->size = *(cover_data_t*)cov->data;
+ cov->overflow = (cov->data + (cov->size + 2) * sizeof(cover_data_t)) > cov->data_end;
}
static void cover_collect(cover_t* cov)
{
if (is_kernel_64_bit)
- cov->size = *(uint64*)cov->data;
+ cover_collect_impl<uint64>(cov);
else
- cov->size = *(uint32*)cov->data;
+ cover_collect_impl<uint32>(cov);
}
// One does not simply exit.