@@ -197,7 +197,6 @@ class Proc
197197 return ;
198198 }
199199
200- private:
201200 enum State : uint8 {
202201 // The process has just started.
203202 Started,
@@ -209,6 +208,43 @@ class Proc
209208 Executing,
210209 };
211210
211+ State GetState () const
212+ {
213+ return state_;
214+ }
215+
216+ void RunLeakChecker ()
217+ {
218+ debug (" proc %d: running leak checker\n " , id_);
219+ int stdout_pipe[2 ];
220+ if (pipe (stdout_pipe))
221+ fail (" leak checker pipe failed" );
222+
223+ const char * argv[] = {bin_, " leak" , nullptr };
224+ std::vector<std::pair<int , int >> fds = {
225+ {-1 , STDIN_FILENO}, // We don't need an stdin pipe. No communication is done in the parent -> child direction.
226+ {stdout_pipe[1 ], STDOUT_FILENO},
227+ {stdout_pipe[1 ], STDERR_FILENO},
228+ };
229+ Subprocess leak_process (argv, fds);
230+ close (stdout_pipe[1 ]);
231+
232+ std::vector<uint8_t > output;
233+ for (;;) {
234+ const size_t kChunk = 1024 ;
235+ output.resize (output.size () + kChunk );
236+ ssize_t n = read (stdout_pipe[0 ], output.data () + output.size () - kChunk , kChunk );
237+ output.resize (output.size () - kChunk + std::max<ssize_t >(n, 0 ));
238+ if (n <= 0 )
239+ break ;
240+ }
241+ output.push_back (0 );
242+ fprintf (stderr, " proc %d: leak checker output:\n %s\n " , id_, (const char *)output.data ());
243+
244+ close (stdout_pipe[0 ]);
245+ }
246+
247+ private:
212248 Connection& conn_;
213249 const char * const bin_;
214250 ProcIDPool& proc_id_pool_;
@@ -575,6 +611,7 @@ class Runner
575611 std::vector<std::string> leak_frames_;
576612 int restarting_ = 0 ;
577613 bool corpus_triaged_ = false ;
614+ uint64 proc_counter_ = 0 ;
578615 ProcOpts proc_opts_{};
579616
580617 friend std::ostream& operator <<(std::ostream& ss, const Runner& runner)
@@ -623,9 +660,19 @@ class Runner
623660
624661 for (auto & proc : procs_) {
625662 proc->Ready (select, now, requests_.empty ());
626- if (!requests_.empty ()) {
627- if (proc->Execute (requests_.front ()))
663+ constexpr uint64 kRunLeakCheckEvery = 5000 ;
664+ if (corpus_triaged_ && proc_counter_ && proc_counter_ % kRunLeakCheckEvery == 0 ) {
665+ if (std::all_of (procs_.begin (), procs_.end (), [](const auto & proc) {
666+ return proc->GetState () == Proc::State::Idle;
667+ })) {
668+ proc->RunLeakChecker ();
669+ ++proc_counter_;
670+ }
671+ } else if (!requests_.empty ()) {
672+ if (proc->Execute (requests_.front ())) {
628673 requests_.pop_front ();
674+ ++proc_counter_;
675+ }
629676 }
630677 }
631678
0 commit comments