Skip to content

Commit ed8ce2c

Browse files
committed
executor: enable periodic leak checking
This commit enables the periodic execution of a leak checker within the executor. The leak checker will now run every 2 * num_procs executions, but only after the corpus has been triaged and all executor processes are in an idle state. Fixes #4728.
1 parent 86341da commit ed8ce2c

File tree

1 file changed

+59
-3
lines changed

1 file changed

+59
-3
lines changed

executor/executor_runner.h

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright 2024 syzkaller project authors. All rights reserved.
22
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
33

4+
#include <cstring>
45
#include <fcntl.h>
56
#include <signal.h>
67
#include <sys/mman.h>
@@ -17,6 +18,8 @@
1718
#include <utility>
1819
#include <vector>
1920

21+
#include "pkg/flatrpc/flatrpc.h"
22+
2023
inline std::ostream& operator<<(std::ostream& ss, const rpc::ExecRequestRawT& req)
2124
{
2225
return ss << "id=" << req.id
@@ -197,7 +200,6 @@ class Proc
197200
return;
198201
}
199202

200-
private:
201203
enum State : uint8 {
202204
// The process has just started.
203205
Started,
@@ -209,6 +211,12 @@ class Proc
209211
Executing,
210212
};
211213

214+
State GetState() const
215+
{
216+
return state_;
217+
}
218+
219+
private:
212220
Connection& conn_;
213221
const char* const bin_;
214222
ProcIDPool& proc_id_pool_;
@@ -575,6 +583,8 @@ class Runner
575583
std::vector<std::string> leak_frames_;
576584
int restarting_ = 0;
577585
bool corpus_triaged_ = false;
586+
bool is_leak_enabled_ = false;
587+
uint64 exec_count_ = 0;
578588
ProcOpts proc_opts_{};
579589

580590
friend std::ostream& operator<<(std::ostream& ss, const Runner& runner)
@@ -621,11 +631,35 @@ class Runner
621631
failmsg("unknown host message type", "type=%d", static_cast<int>(raw.msg.type));
622632
}
623633

634+
#if GOOS_linux
635+
const uint64 kRunLeakCheckEvery = 2 * procs_.size();
636+
constexpr auto IsProcIdle = [](const std::unique_ptr<Proc>& proc) {
637+
return proc->GetState() == Proc::State::Idle;
638+
};
639+
const bool isScheduledForLeakCheck =
640+
is_leak_enabled_ &&
641+
corpus_triaged_ &&
642+
exec_count_ > 0 &&
643+
exec_count_ % kRunLeakCheckEvery == 0;
644+
645+
if (isScheduledForLeakCheck && std::all_of(procs_.begin(), procs_.end(), IsProcIdle)) {
646+
const int len = leak_frames_.size();
647+
auto leakFrames = GetArrOfCStr(leak_frames_);
648+
check_leaks(leakFrames, len);
649+
FreeArrOfCStr(leakFrames, len);
650+
++exec_count_;
651+
}
652+
#else
653+
constexpr bool isScheduledForLeakCheck = false;
654+
#endif
655+
624656
for (auto& proc : procs_) {
625657
proc->Ready(select, now, requests_.empty());
626-
if (!requests_.empty()) {
627-
if (proc->Execute(requests_.front()))
658+
if (!isScheduledForLeakCheck && !requests_.empty()) {
659+
if (proc->Execute(requests_.front())) {
628660
requests_.pop_front();
661+
++exec_count_;
662+
}
629663
}
630664
}
631665

@@ -667,6 +701,7 @@ class Runner
667701
conn_reply.slowdown, conn_reply.syscall_timeout_ms,
668702
conn_reply.program_timeout_ms, static_cast<uint64>(conn_reply.features));
669703
leak_frames_ = conn_reply.leak_frames;
704+
is_leak_enabled_ = static_cast<bool>(conn_reply.features & rpc::Feature::Leak);
670705

671706
proc_opts_.use_cover_edges = conn_reply.cover_edges;
672707
proc_opts_.is_kernel_64_bit = is_kernel_64_bit = conn_reply.kernel_64_bit;
@@ -857,6 +892,27 @@ class Runner
857892

858893
return {status == kFailStatus ? "process failed" : "", std::move(output)};
859894
}
895+
896+
#if GOOS_linux
897+
char** GetArrOfCStr(const std::vector<std::string>& vec)
898+
{
899+
char** arr = new char*[vec.size()];
900+
std::transform(vec.cbegin(), vec.cend(), arr, [](const std::string& str) {
901+
char* c_str = new char[str.size() + 1];
902+
memcpy(c_str, str.c_str(), str.size() + 1);
903+
return c_str;
904+
});
905+
return arr;
906+
}
907+
908+
void FreeArrOfCStr(char**& arr, int len)
909+
{
910+
for (int i = 0; i < len; ++i)
911+
delete[] arr[i];
912+
913+
delete[] arr;
914+
}
915+
#endif
860916
};
861917

862918
static void SigintHandler(int sig)

0 commit comments

Comments
 (0)