xref: /aosp_15_r20/external/perfetto/src/profiling/common/proc_utils.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker  *
4*6dbdd20aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker  *
8*6dbdd20aSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker  *
10*6dbdd20aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker  * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker  */
16*6dbdd20aSAndroid Build Coastguard Worker 
17*6dbdd20aSAndroid Build Coastguard Worker #include "src/profiling/common/proc_utils.h"
18*6dbdd20aSAndroid Build Coastguard Worker 
19*6dbdd20aSAndroid Build Coastguard Worker #include <sys/stat.h>
20*6dbdd20aSAndroid Build Coastguard Worker #include <unistd.h>
21*6dbdd20aSAndroid Build Coastguard Worker 
22*6dbdd20aSAndroid Build Coastguard Worker #include <cinttypes>
23*6dbdd20aSAndroid Build Coastguard Worker #include <optional>
24*6dbdd20aSAndroid Build Coastguard Worker 
25*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/file_utils.h"
26*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/string_utils.h"
27*6dbdd20aSAndroid Build Coastguard Worker #include "src/profiling/common/proc_cmdline.h"
28*6dbdd20aSAndroid Build Coastguard Worker 
29*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
30*6dbdd20aSAndroid Build Coastguard Worker namespace profiling {
31*6dbdd20aSAndroid Build Coastguard Worker namespace {
32*6dbdd20aSAndroid Build Coastguard Worker 
ParseProcStatusSize(const std::string & status,const std::string & key)33*6dbdd20aSAndroid Build Coastguard Worker std::optional<uint32_t> ParseProcStatusSize(const std::string& status,
34*6dbdd20aSAndroid Build Coastguard Worker                                             const std::string& key) {
35*6dbdd20aSAndroid Build Coastguard Worker   auto entry_idx = status.find(key);
36*6dbdd20aSAndroid Build Coastguard Worker   if (entry_idx == std::string::npos)
37*6dbdd20aSAndroid Build Coastguard Worker     return {};
38*6dbdd20aSAndroid Build Coastguard Worker   entry_idx = status.find_first_not_of(" \t", entry_idx + key.size());
39*6dbdd20aSAndroid Build Coastguard Worker   if (entry_idx == std::string::npos)
40*6dbdd20aSAndroid Build Coastguard Worker     return {};
41*6dbdd20aSAndroid Build Coastguard Worker   int32_t val = atoi(status.c_str() + entry_idx);
42*6dbdd20aSAndroid Build Coastguard Worker   if (val < 0) {
43*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_ELOG("Unexpected value reading %s", key.c_str());
44*6dbdd20aSAndroid Build Coastguard Worker     return {};
45*6dbdd20aSAndroid Build Coastguard Worker   }
46*6dbdd20aSAndroid Build Coastguard Worker   return static_cast<uint32_t>(val);
47*6dbdd20aSAndroid Build Coastguard Worker }
48*6dbdd20aSAndroid Build Coastguard Worker }  // namespace
49*6dbdd20aSAndroid Build Coastguard Worker 
ReadStatus(pid_t pid)50*6dbdd20aSAndroid Build Coastguard Worker std::optional<std::string> ReadStatus(pid_t pid) {
51*6dbdd20aSAndroid Build Coastguard Worker   std::string path = "/proc/" + std::to_string(pid) + "/status";
52*6dbdd20aSAndroid Build Coastguard Worker   std::string status;
53*6dbdd20aSAndroid Build Coastguard Worker   bool read_proc = base::ReadFile(path, &status);
54*6dbdd20aSAndroid Build Coastguard Worker   if (!read_proc) {
55*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_ELOG("Failed to read %s", path.c_str());
56*6dbdd20aSAndroid Build Coastguard Worker     return std::nullopt;
57*6dbdd20aSAndroid Build Coastguard Worker   }
58*6dbdd20aSAndroid Build Coastguard Worker   return std::optional<std::string>(status);
59*6dbdd20aSAndroid Build Coastguard Worker }
60*6dbdd20aSAndroid Build Coastguard Worker 
GetRssAnonAndSwap(const std::string & status)61*6dbdd20aSAndroid Build Coastguard Worker std::optional<uint32_t> GetRssAnonAndSwap(const std::string& status) {
62*6dbdd20aSAndroid Build Coastguard Worker   auto anon_rss = ParseProcStatusSize(status, "RssAnon:");
63*6dbdd20aSAndroid Build Coastguard Worker   auto swap = ParseProcStatusSize(status, "VmSwap:");
64*6dbdd20aSAndroid Build Coastguard Worker   if (anon_rss.has_value() && swap.has_value()) {
65*6dbdd20aSAndroid Build Coastguard Worker     return *anon_rss + *swap;
66*6dbdd20aSAndroid Build Coastguard Worker   }
67*6dbdd20aSAndroid Build Coastguard Worker   return std::nullopt;
68*6dbdd20aSAndroid Build Coastguard Worker }
69*6dbdd20aSAndroid Build Coastguard Worker 
RemoveUnderAnonThreshold(uint32_t min_size_kb,std::set<pid_t> * pids)70*6dbdd20aSAndroid Build Coastguard Worker void RemoveUnderAnonThreshold(uint32_t min_size_kb, std::set<pid_t>* pids) {
71*6dbdd20aSAndroid Build Coastguard Worker   for (auto it = pids->begin(); it != pids->end();) {
72*6dbdd20aSAndroid Build Coastguard Worker     const pid_t pid = *it;
73*6dbdd20aSAndroid Build Coastguard Worker 
74*6dbdd20aSAndroid Build Coastguard Worker     std::optional<std::string> status = ReadStatus(pid);
75*6dbdd20aSAndroid Build Coastguard Worker     std::optional<uint32_t> rss_and_swap;
76*6dbdd20aSAndroid Build Coastguard Worker     if (status)
77*6dbdd20aSAndroid Build Coastguard Worker       rss_and_swap = GetRssAnonAndSwap(*status);
78*6dbdd20aSAndroid Build Coastguard Worker 
79*6dbdd20aSAndroid Build Coastguard Worker     if (rss_and_swap && rss_and_swap < min_size_kb) {
80*6dbdd20aSAndroid Build Coastguard Worker       PERFETTO_LOG("Removing pid %d from profiled set (anon: %d kB < %" PRIu32
81*6dbdd20aSAndroid Build Coastguard Worker                    ")",
82*6dbdd20aSAndroid Build Coastguard Worker                    pid, *rss_and_swap, min_size_kb);
83*6dbdd20aSAndroid Build Coastguard Worker       it = pids->erase(it);
84*6dbdd20aSAndroid Build Coastguard Worker     } else {
85*6dbdd20aSAndroid Build Coastguard Worker       ++it;
86*6dbdd20aSAndroid Build Coastguard Worker     }
87*6dbdd20aSAndroid Build Coastguard Worker   }
88*6dbdd20aSAndroid Build Coastguard Worker }
89*6dbdd20aSAndroid Build Coastguard Worker 
GetUids(const std::string & status)90*6dbdd20aSAndroid Build Coastguard Worker std::optional<Uids> GetUids(const std::string& status) {
91*6dbdd20aSAndroid Build Coastguard Worker   auto entry_idx = status.find("Uid:");
92*6dbdd20aSAndroid Build Coastguard Worker   if (entry_idx == std::string::npos)
93*6dbdd20aSAndroid Build Coastguard Worker     return std::nullopt;
94*6dbdd20aSAndroid Build Coastguard Worker 
95*6dbdd20aSAndroid Build Coastguard Worker   Uids uids;
96*6dbdd20aSAndroid Build Coastguard Worker   const char* str = &status[entry_idx + 4];
97*6dbdd20aSAndroid Build Coastguard Worker   char* endptr;
98*6dbdd20aSAndroid Build Coastguard Worker 
99*6dbdd20aSAndroid Build Coastguard Worker   uids.real = strtoull(str, &endptr, 10);
100*6dbdd20aSAndroid Build Coastguard Worker   if (*endptr != ' ' && *endptr != '\t')
101*6dbdd20aSAndroid Build Coastguard Worker     return std::nullopt;
102*6dbdd20aSAndroid Build Coastguard Worker 
103*6dbdd20aSAndroid Build Coastguard Worker   str = endptr;
104*6dbdd20aSAndroid Build Coastguard Worker   uids.effective = strtoull(str, &endptr, 10);
105*6dbdd20aSAndroid Build Coastguard Worker   if (*endptr != ' ' && *endptr != '\t')
106*6dbdd20aSAndroid Build Coastguard Worker     return std::nullopt;
107*6dbdd20aSAndroid Build Coastguard Worker 
108*6dbdd20aSAndroid Build Coastguard Worker   str = endptr;
109*6dbdd20aSAndroid Build Coastguard Worker   uids.saved_set = strtoull(str, &endptr, 10);
110*6dbdd20aSAndroid Build Coastguard Worker   if (*endptr != ' ' && *endptr != '\t')
111*6dbdd20aSAndroid Build Coastguard Worker     return std::nullopt;
112*6dbdd20aSAndroid Build Coastguard Worker 
113*6dbdd20aSAndroid Build Coastguard Worker   str = endptr;
114*6dbdd20aSAndroid Build Coastguard Worker   uids.filesystem = strtoull(str, &endptr, 10);
115*6dbdd20aSAndroid Build Coastguard Worker   if (*endptr != '\n' && *endptr != '\0')
116*6dbdd20aSAndroid Build Coastguard Worker     return std::nullopt;
117*6dbdd20aSAndroid Build Coastguard Worker   return uids;
118*6dbdd20aSAndroid Build Coastguard Worker }
119*6dbdd20aSAndroid Build Coastguard Worker 
120*6dbdd20aSAndroid Build Coastguard Worker // Normalize cmdline in place. Stores new beginning of string in *cmdline_ptr.
121*6dbdd20aSAndroid Build Coastguard Worker // Returns new size of string (from new beginning).
122*6dbdd20aSAndroid Build Coastguard Worker // Modifies string in *cmdline_ptr.
NormalizeCmdLine(char ** cmdline_ptr,size_t size)123*6dbdd20aSAndroid Build Coastguard Worker ssize_t NormalizeCmdLine(char** cmdline_ptr, size_t size) {
124*6dbdd20aSAndroid Build Coastguard Worker   char* cmdline = *cmdline_ptr;
125*6dbdd20aSAndroid Build Coastguard Worker   char* first_arg = static_cast<char*>(memchr(cmdline, '\0', size));
126*6dbdd20aSAndroid Build Coastguard Worker   if (first_arg == nullptr) {
127*6dbdd20aSAndroid Build Coastguard Worker     errno = EOVERFLOW;
128*6dbdd20aSAndroid Build Coastguard Worker     return -1;
129*6dbdd20aSAndroid Build Coastguard Worker   }
130*6dbdd20aSAndroid Build Coastguard Worker   // For consistency with what we do with Java app cmdlines, trim everything
131*6dbdd20aSAndroid Build Coastguard Worker   // after the @ sign of the first arg.
132*6dbdd20aSAndroid Build Coastguard Worker   char* first_at = static_cast<char*>(memchr(cmdline, '@', size));
133*6dbdd20aSAndroid Build Coastguard Worker   if (first_at != nullptr && first_at < first_arg) {
134*6dbdd20aSAndroid Build Coastguard Worker     *first_at = '\0';
135*6dbdd20aSAndroid Build Coastguard Worker     first_arg = first_at;
136*6dbdd20aSAndroid Build Coastguard Worker   }
137*6dbdd20aSAndroid Build Coastguard Worker   char* start = static_cast<char*>(
138*6dbdd20aSAndroid Build Coastguard Worker       memrchr(cmdline, '/', static_cast<size_t>(first_arg - cmdline)));
139*6dbdd20aSAndroid Build Coastguard Worker   if (start == nullptr) {
140*6dbdd20aSAndroid Build Coastguard Worker     start = cmdline;
141*6dbdd20aSAndroid Build Coastguard Worker   } else {
142*6dbdd20aSAndroid Build Coastguard Worker     // Skip the /.
143*6dbdd20aSAndroid Build Coastguard Worker     start++;
144*6dbdd20aSAndroid Build Coastguard Worker   }
145*6dbdd20aSAndroid Build Coastguard Worker   *cmdline_ptr = start;
146*6dbdd20aSAndroid Build Coastguard Worker   return first_arg - start;
147*6dbdd20aSAndroid Build Coastguard Worker }
148*6dbdd20aSAndroid Build Coastguard Worker 
NormalizeCmdlines(const std::vector<std::string> & cmdlines)149*6dbdd20aSAndroid Build Coastguard Worker std::optional<std::vector<std::string>> NormalizeCmdlines(
150*6dbdd20aSAndroid Build Coastguard Worker     const std::vector<std::string>& cmdlines) {
151*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> normalized_cmdlines;
152*6dbdd20aSAndroid Build Coastguard Worker   normalized_cmdlines.reserve(cmdlines.size());
153*6dbdd20aSAndroid Build Coastguard Worker 
154*6dbdd20aSAndroid Build Coastguard Worker   for (size_t i = 0; i < cmdlines.size(); i++) {
155*6dbdd20aSAndroid Build Coastguard Worker     std::string cmdline = cmdlines[i];  // mutable copy
156*6dbdd20aSAndroid Build Coastguard Worker     // Add nullbyte to make sure it's a C string.
157*6dbdd20aSAndroid Build Coastguard Worker     cmdline.resize(cmdline.size() + 1, '\0');
158*6dbdd20aSAndroid Build Coastguard Worker     char* cmdline_cstr = &(cmdline[0]);
159*6dbdd20aSAndroid Build Coastguard Worker     ssize_t size = NormalizeCmdLine(&cmdline_cstr, cmdline.size());
160*6dbdd20aSAndroid Build Coastguard Worker     if (size == -1) {
161*6dbdd20aSAndroid Build Coastguard Worker       PERFETTO_PLOG("Failed to normalize cmdline %s. Stopping the parse.",
162*6dbdd20aSAndroid Build Coastguard Worker                     cmdlines[i].c_str());
163*6dbdd20aSAndroid Build Coastguard Worker       return std::nullopt;
164*6dbdd20aSAndroid Build Coastguard Worker     }
165*6dbdd20aSAndroid Build Coastguard Worker     normalized_cmdlines.emplace_back(cmdline_cstr, static_cast<size_t>(size));
166*6dbdd20aSAndroid Build Coastguard Worker   }
167*6dbdd20aSAndroid Build Coastguard Worker   return std::make_optional(normalized_cmdlines);
168*6dbdd20aSAndroid Build Coastguard Worker }
169*6dbdd20aSAndroid Build Coastguard Worker 
170*6dbdd20aSAndroid Build Coastguard Worker // This is mostly the same as GetHeapprofdProgramProperty in
171*6dbdd20aSAndroid Build Coastguard Worker // https://android.googlesource.com/platform/bionic/+/main/libc/bionic/malloc_common.cpp
172*6dbdd20aSAndroid Build Coastguard Worker // This should give the same result as GetHeapprofdProgramProperty.
GetCmdlineForPID(pid_t pid,std::string * name)173*6dbdd20aSAndroid Build Coastguard Worker bool GetCmdlineForPID(pid_t pid, std::string* name) {
174*6dbdd20aSAndroid Build Coastguard Worker   std::string filename = "/proc/" + std::to_string(pid) + "/cmdline";
175*6dbdd20aSAndroid Build Coastguard Worker   base::ScopedFile fd(base::OpenFile(filename, O_RDONLY | O_CLOEXEC));
176*6dbdd20aSAndroid Build Coastguard Worker   if (!fd) {
177*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_DPLOG("Failed to open %s", filename.c_str());
178*6dbdd20aSAndroid Build Coastguard Worker     return false;
179*6dbdd20aSAndroid Build Coastguard Worker   }
180*6dbdd20aSAndroid Build Coastguard Worker   char cmdline[512];
181*6dbdd20aSAndroid Build Coastguard Worker   const size_t max_read_size = sizeof(cmdline) - 1;
182*6dbdd20aSAndroid Build Coastguard Worker   ssize_t rd = read(*fd, cmdline, max_read_size);
183*6dbdd20aSAndroid Build Coastguard Worker   if (rd == -1) {
184*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_DPLOG("Failed to read %s", filename.c_str());
185*6dbdd20aSAndroid Build Coastguard Worker     return false;
186*6dbdd20aSAndroid Build Coastguard Worker   }
187*6dbdd20aSAndroid Build Coastguard Worker 
188*6dbdd20aSAndroid Build Coastguard Worker   if (rd == 0) {
189*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_DLOG("Empty cmdline for %" PRIdMAX ". Skipping.",
190*6dbdd20aSAndroid Build Coastguard Worker                   static_cast<intmax_t>(pid));
191*6dbdd20aSAndroid Build Coastguard Worker     return false;
192*6dbdd20aSAndroid Build Coastguard Worker   }
193*6dbdd20aSAndroid Build Coastguard Worker 
194*6dbdd20aSAndroid Build Coastguard Worker   // In some buggy kernels (before http://bit.ly/37R7qwL) /proc/pid/cmdline is
195*6dbdd20aSAndroid Build Coastguard Worker   // not NUL-terminated (see b/147438623). If we read < max_read_size bytes
196*6dbdd20aSAndroid Build Coastguard Worker   // assume we are hitting the aforementioned kernel bug and terminate anyways.
197*6dbdd20aSAndroid Build Coastguard Worker   const size_t rd_u = static_cast<size_t>(rd);
198*6dbdd20aSAndroid Build Coastguard Worker   if (rd_u >= max_read_size && memchr(cmdline, '\0', rd_u) == nullptr) {
199*6dbdd20aSAndroid Build Coastguard Worker     // We did not manage to read the first argument.
200*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_DLOG("Overflow reading cmdline for %" PRIdMAX,
201*6dbdd20aSAndroid Build Coastguard Worker                   static_cast<intmax_t>(pid));
202*6dbdd20aSAndroid Build Coastguard Worker     errno = EOVERFLOW;
203*6dbdd20aSAndroid Build Coastguard Worker     return false;
204*6dbdd20aSAndroid Build Coastguard Worker   }
205*6dbdd20aSAndroid Build Coastguard Worker 
206*6dbdd20aSAndroid Build Coastguard Worker   cmdline[rd] = '\0';
207*6dbdd20aSAndroid Build Coastguard Worker   char* cmdline_start = cmdline;
208*6dbdd20aSAndroid Build Coastguard Worker   ssize_t size = NormalizeCmdLine(&cmdline_start, rd_u);
209*6dbdd20aSAndroid Build Coastguard Worker   if (size == -1)
210*6dbdd20aSAndroid Build Coastguard Worker     return false;
211*6dbdd20aSAndroid Build Coastguard Worker   name->assign(cmdline_start, static_cast<size_t>(size));
212*6dbdd20aSAndroid Build Coastguard Worker   return true;
213*6dbdd20aSAndroid Build Coastguard Worker }
214*6dbdd20aSAndroid Build Coastguard Worker 
FindAllProfilablePids(std::set<pid_t> * pids)215*6dbdd20aSAndroid Build Coastguard Worker void FindAllProfilablePids(std::set<pid_t>* pids) {
216*6dbdd20aSAndroid Build Coastguard Worker   ForEachPid([pids](pid_t pid) {
217*6dbdd20aSAndroid Build Coastguard Worker     if (pid == getpid())
218*6dbdd20aSAndroid Build Coastguard Worker       return;
219*6dbdd20aSAndroid Build Coastguard Worker 
220*6dbdd20aSAndroid Build Coastguard Worker     char filename_buf[128];
221*6dbdd20aSAndroid Build Coastguard Worker     snprintf(filename_buf, sizeof(filename_buf), "/proc/%d/%s", pid, "cmdline");
222*6dbdd20aSAndroid Build Coastguard Worker     struct stat statbuf;
223*6dbdd20aSAndroid Build Coastguard Worker     // Check if we have permission to the process.
224*6dbdd20aSAndroid Build Coastguard Worker     if (stat(filename_buf, &statbuf) == 0)
225*6dbdd20aSAndroid Build Coastguard Worker       pids->emplace(pid);
226*6dbdd20aSAndroid Build Coastguard Worker   });
227*6dbdd20aSAndroid Build Coastguard Worker }
228*6dbdd20aSAndroid Build Coastguard Worker 
FindPidsForCmdlines(const std::vector<std::string> & cmdlines,std::set<pid_t> * pids)229*6dbdd20aSAndroid Build Coastguard Worker void FindPidsForCmdlines(const std::vector<std::string>& cmdlines,
230*6dbdd20aSAndroid Build Coastguard Worker                          std::set<pid_t>* pids) {
231*6dbdd20aSAndroid Build Coastguard Worker   ForEachPid([&cmdlines, pids](pid_t pid) {
232*6dbdd20aSAndroid Build Coastguard Worker     if (pid == getpid())
233*6dbdd20aSAndroid Build Coastguard Worker       return;
234*6dbdd20aSAndroid Build Coastguard Worker     std::string process_cmdline;
235*6dbdd20aSAndroid Build Coastguard Worker     process_cmdline.reserve(512);
236*6dbdd20aSAndroid Build Coastguard Worker     GetCmdlineForPID(pid, &process_cmdline);
237*6dbdd20aSAndroid Build Coastguard Worker     for (const std::string& cmdline : cmdlines) {
238*6dbdd20aSAndroid Build Coastguard Worker       if (process_cmdline == cmdline)
239*6dbdd20aSAndroid Build Coastguard Worker         pids->emplace(static_cast<pid_t>(pid));
240*6dbdd20aSAndroid Build Coastguard Worker     }
241*6dbdd20aSAndroid Build Coastguard Worker   });
242*6dbdd20aSAndroid Build Coastguard Worker }
243*6dbdd20aSAndroid Build Coastguard Worker 
244*6dbdd20aSAndroid Build Coastguard Worker namespace glob_aware {
FindPidsForCmdlinePatterns(const std::vector<std::string> & patterns,std::set<pid_t> * pids)245*6dbdd20aSAndroid Build Coastguard Worker void FindPidsForCmdlinePatterns(const std::vector<std::string>& patterns,
246*6dbdd20aSAndroid Build Coastguard Worker                                 std::set<pid_t>* pids) {
247*6dbdd20aSAndroid Build Coastguard Worker   ForEachPid([&patterns, pids](pid_t pid) {
248*6dbdd20aSAndroid Build Coastguard Worker     if (pid == getpid())
249*6dbdd20aSAndroid Build Coastguard Worker       return;
250*6dbdd20aSAndroid Build Coastguard Worker     std::string cmdline;
251*6dbdd20aSAndroid Build Coastguard Worker     if (!glob_aware::ReadProcCmdlineForPID(pid, &cmdline))
252*6dbdd20aSAndroid Build Coastguard Worker       return;
253*6dbdd20aSAndroid Build Coastguard Worker     const char* binname =
254*6dbdd20aSAndroid Build Coastguard Worker         glob_aware::FindBinaryName(cmdline.c_str(), cmdline.size());
255*6dbdd20aSAndroid Build Coastguard Worker 
256*6dbdd20aSAndroid Build Coastguard Worker     for (const std::string& pattern : patterns) {
257*6dbdd20aSAndroid Build Coastguard Worker       if (glob_aware::MatchGlobPattern(pattern.c_str(), cmdline.c_str(),
258*6dbdd20aSAndroid Build Coastguard Worker                                        binname)) {
259*6dbdd20aSAndroid Build Coastguard Worker         pids->insert(pid);
260*6dbdd20aSAndroid Build Coastguard Worker       }
261*6dbdd20aSAndroid Build Coastguard Worker     }
262*6dbdd20aSAndroid Build Coastguard Worker   });
263*6dbdd20aSAndroid Build Coastguard Worker }
264*6dbdd20aSAndroid Build Coastguard Worker }  // namespace glob_aware
265*6dbdd20aSAndroid Build Coastguard Worker 
266*6dbdd20aSAndroid Build Coastguard Worker }  // namespace profiling
267*6dbdd20aSAndroid Build Coastguard Worker }  // namespace perfetto
268