diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2024-07-01 14:26:07 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2024-07-22 08:35:47 +0000 |
| commit | df655b64ffc2879b80e652329fb7a11508e50310 (patch) | |
| tree | a721bbe875f7e9bc53cf2a297ce2ce7bd06bd204 /executor | |
| parent | fb8445ca9a36aa91aed98a02092147cb88d49d9f (diff) | |
prog: restricts hints to at most 10 attempts per single kernel PC
We are getting too many generated candidates, the fuzzer may not keep up
with them at all (hints jobs keep growing infinitely). If a hint indeed came
from the input w/o transformation, then we should guess it on the first
attempt (or at least after few attempts). If it did not come from the input,
or came with a non-trivial transformation, then any number of attempts won't
help. So limit the total number of attempts (until the next restart).
Diffstat (limited to 'executor')
| -rw-r--r-- | executor/executor.cc | 26 |
1 files changed, 10 insertions, 16 deletions
diff --git a/executor/executor.cc b/executor/executor.cc index bcd75f612..5855ef9b4 100644 --- a/executor/executor.cc +++ b/executor/executor.cc @@ -462,7 +462,7 @@ static void copyin(char* addr, uint64 val, uint64 size, uint64 bf, uint64 bf_off static bool copyout(char* addr, uint64 size, uint64* res); static void setup_control_pipes(); static bool coverage_filter(uint64 pc); -static std::tuple<rpc::ComparisonRaw, bool, bool> convert(const kcov_comparison_t& cmp); +static rpc::ComparisonRaw convert(const kcov_comparison_t& cmp); static flatbuffers::span<uint8_t> finish_output(OutputData* output, int proc_id, uint64 req_id, uint64 elapsed, uint64 freshness, uint32 status, const std::vector<uint8_t>* process_output); @@ -1102,29 +1102,23 @@ uint32 write_comparisons(flatbuffers::FlatBufferBuilder& fbb, cover_t* cov) cover_unprotect(cov); rpc::ComparisonRaw* start = (rpc::ComparisonRaw*)cov_start; rpc::ComparisonRaw* end = start; - // We will convert kcov_comparison_t to ComparisonRaw inplace - // and potentially double number of elements, so ensure we have space. - static_assert(sizeof(kcov_comparison_t) >= 2 * sizeof(rpc::ComparisonRaw)); + // We will convert kcov_comparison_t to ComparisonRaw inplace. + static_assert(sizeof(kcov_comparison_t) >= sizeof(rpc::ComparisonRaw)); for (uint32 i = 0; i < ncomps; i++) { - auto [raw, swap, ok] = convert(cov_start[i]); - if (!ok) + auto raw = convert(cov_start[i]); + if (!raw.pc()) continue; *end++ = raw; - // Compiler marks comparisons with a const with KCOV_CMP_CONST flag. - // If the flag is set, then we need to export only one order of operands - // (because only one of them could potentially come from the input). - // If the flag is not set, then we export both orders as both operands - // could come from the input. - if (swap) - *end++ = {raw.op2(), raw.op1()}; } std::sort(start, end, [](rpc::ComparisonRaw a, rpc::ComparisonRaw b) -> bool { + if (a.pc() != b.pc()) + return a.pc() < b.pc(); if (a.op1() != b.op1()) return a.op1() < b.op1(); return a.op2() < b.op2(); }); ncomps = std::unique(start, end, [](rpc::ComparisonRaw a, rpc::ComparisonRaw b) -> bool { - return a.op1() == b.op1() && a.op2() == b.op2(); + return a.pc() == b.pc() && a.op1() == b.op1() && a.op2() == b.op2(); }) - start; cover_protect(cov); @@ -1646,7 +1640,7 @@ uint64 read_input(uint8** input_posp, bool peek) return v; } -std::tuple<rpc::ComparisonRaw, bool, bool> convert(const kcov_comparison_t& cmp) +rpc::ComparisonRaw convert(const kcov_comparison_t& cmp) { if (cmp.type > (KCOV_CMP_CONST | KCOV_CMP_SIZE_MASK)) failmsg("invalid kcov comp type", "type=%llx", cmp.type); @@ -1692,7 +1686,7 @@ std::tuple<rpc::ComparisonRaw, bool, bool> convert(const kcov_comparison_t& cmp) // Prog package expects operands in the opposite order (first operand may come from the input, // the second operand was computed in the kernel), so swap operands. - return {{arg2, arg1}, !(cmp.type & KCOV_CMP_CONST), true}; + return {cmp.pc, arg2, arg1, !!(cmp.type & KCOV_CMP_CONST)}; } void failmsg(const char* err, const char* msg, ...) |
