diff --git a/src/wtf/server.h b/src/wtf/server.h index 9495a57..e398468 100644 --- a/src/wtf/server.h +++ b/src/wtf/server.h @@ -328,6 +328,12 @@ class Server_t { tsl::robin_set Coverage_; + // + // File where the aggregated code-coverage is written. + // + + FILE *FileCoverage_ = nullptr; + // // Number of mutations we have performed. // @@ -346,6 +352,11 @@ class Server_t { // ~Server_t() { + if (FileCoverage_) { + fclose(FileCoverage_); + FileCoverage_ = nullptr; + } + for (const auto &[Fd, _] : Clients_) { CloseSocket(Fd); } @@ -366,6 +377,23 @@ class Server_t { fmt::print("Seeded with {}\n", Opts_.Seed); + // + // Open the file where the aggregated coverage is written to. + // + + const char *FileCoverageName = "aggregate.cov"; + if (fs::exists(FileCoverageName)) { + fmt::print("Please remove / save the {} file to continue\n", + FileCoverageName); + return EXIT_FAILURE; + } + + FileCoverage_ = fopen(FileCoverageName, "a"); + if (FileCoverage_ == nullptr) { + fmt::print("Failed to open {}\n", FileCoverageName); + return EXIT_FAILURE; + } + // // Initialize our internal state. // @@ -725,7 +753,7 @@ class Server_t { yas::mem_ostream Os; yas::binary_oarchive Oa(Os); - Oa &Testcase; + Oa & Testcase; const auto &Buf = Os.get_intrusive_buffer(); if (!Send(Fd, (uint8_t *)Buf.data, Buf.size)) { fmt::print("Send failed\n"); @@ -774,7 +802,7 @@ class Server_t { TestcaseResult_t &Result) { yas::mem_istream Is(Buffer.data(), Buffer.size_bytes()); yas::binary_iarchive Ia(Is); - Ia &ReceivedTestcase &Coverage &Result; + Ia & ReceivedTestcase & Coverage & Result; return true; } @@ -816,11 +844,16 @@ class Server_t { if (Coverage.size() > 0) { // - // Emplace the new coverage in our data. + // Emplace the new coverage in our data and update the file on disk. // const size_t SizeBefore = Coverage_.size(); - Coverage_.insert(Coverage.cbegin(), Coverage.cend()); + for (const auto &Gva : Coverage) { + const auto &[_, NewCoverage] = Coverage_.emplace(Gva); + if (NewCoverage) { + fmt::print(FileCoverage_, "{:#x}\n", Gva.U64()); + } + } // // If the coverage size has changed, it means that this testcase @@ -830,6 +863,13 @@ class Server_t { const bool NewCoverage = Coverage_.size() > SizeBefore; if (NewCoverage) { + // + // New coverage means that we added new content to the file, so let's + // flush it. + // + + fflush(FileCoverage_); + // // Allocate a test that will get moved into the corpus and maybe // saved on disk.