• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_PROCESS_TRACKER_H_
18 #define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_PROCESS_TRACKER_H_
19 
20 #include <tuple>
21 
22 #include "perfetto/ext/base/string_view.h"
23 #include "src/trace_processor/importers/common/args_tracker.h"
24 #include "src/trace_processor/storage/trace_storage.h"
25 #include "src/trace_processor/types/trace_processor_context.h"
26 
27 namespace perfetto {
28 namespace trace_processor {
29 
30 // Thread names can come from different sources, and we don't always want to
31 // overwrite the previously set name. This enum determines the priority of
32 // different sources.
33 enum class ThreadNamePriority {
34   kOther = 0,
35   kFtrace = 1,
36   kProcessTree = 2,
37   kTrackDescriptorThreadType = 3,
38   kTrackDescriptor = 4,
39 
40   // Priority when trace processor hardcodes a name for a process (e.g. calling
41   // the idle thread "swapper" when parsing ftrace).
42   // Keep this last.
43   kTraceProcessorConstant = 5,
44 };
45 
46 class ProcessTracker {
47  public:
48   explicit ProcessTracker(TraceProcessorContext*);
49   ProcessTracker(const ProcessTracker&) = delete;
50   ProcessTracker& operator=(const ProcessTracker&) = delete;
51   virtual ~ProcessTracker();
52 
53   using UniqueProcessIterator =
54       std::multimap<uint32_t, UniquePid>::const_iterator;
55   using UniqueProcessBounds =
56       std::pair<UniqueProcessIterator, UniqueProcessIterator>;
57 
58   using UniqueThreadIterator = std::vector<UniqueTid>::const_iterator;
59   using UniqueThreadBounds =
60       std::pair<UniqueThreadIterator, UniqueThreadIterator>;
61 
62   // TODO(b/110409911): Invalidation of process and threads is yet to be
63   // implemented. This will include passing timestamps into the below methods
64   // to ensure the correct upid/utid is found.
65 
66   // Called when a task_newtask is observed. This force the tracker to start
67   // a new UTID for the thread, which is needed for TID-recycling resolution.
68   UniqueTid StartNewThread(base::Optional<int64_t> timestamp, uint32_t tid);
69 
70   // Returns whether a thread is considered alive by the process tracker.
71   bool IsThreadAlive(UniqueTid utid);
72 
73   // Called when sched_process_exit is observed. This forces the tracker to
74   // end the thread lifetime for the utid associated with the given tid.
75   void EndThread(int64_t timestamp, uint32_t tid);
76 
77   // Returns the thread utid or base::nullopt if it doesn't exist.
78   base::Optional<UniqueTid> GetThreadOrNull(uint32_t tid);
79 
80   // Returns the thread utid (or creates a new entry if not present)
81   UniqueTid GetOrCreateThread(uint32_t tid);
82 
83   // Assigns the given name to the thread if the new name has a higher priority
84   // than the existing one. Returns the utid of the thread.
85   virtual UniqueTid UpdateThreadName(uint32_t tid,
86                                      StringId thread_name_id,
87                                      ThreadNamePriority priority);
88 
89   // Assigns the given name to the thread if the new name has a higher priority
90   // than the existing one. The thread is identified by utid.
91   virtual void UpdateThreadNameByUtid(UniqueTid utid,
92                                       StringId thread_name_id,
93                                       ThreadNamePriority priority);
94 
95   // Called when a thread is seen the process tree. Retrieves the matching utid
96   // for the tid and the matching upid for the tgid and stores both.
97   // Virtual for testing.
98   virtual UniqueTid UpdateThread(uint32_t tid, uint32_t tgid);
99 
100   // Called when a task_newtask without the CLONE_THREAD flag is observed.
101   // This force the tracker to start both a new UTID and a new UPID.
102   UniquePid StartNewProcess(base::Optional<int64_t> timestamp,
103                             base::Optional<uint32_t> parent_tid,
104                             uint32_t pid,
105                             StringId main_thread_name);
106 
107   // Called when a process is seen in a process tree. Retrieves the UniquePid
108   // for that pid or assigns a new one.
109   // Virtual for testing.
110   virtual UniquePid SetProcessMetadata(uint32_t pid,
111                                        base::Optional<uint32_t> ppid,
112                                        base::StringView name,
113                                        base::StringView cmdline);
114 
115   // Sets the process user id.
116   void SetProcessUid(UniquePid upid, uint32_t uid);
117 
118   // Assigns the given name to the process identified by |upid| if it does not
119   // have a name yet.
120   virtual void SetProcessNameIfUnset(UniquePid upid, StringId process_name_id);
121 
122   // Sets the start timestamp to the process identified by |upid| if it doesn't
123   // have a timestamp yet.
124   void SetStartTsIfUnset(UniquePid upid, int64_t start_ts_nanoseconds);
125 
126   // Called on a task rename event to set the process name if the tid provided
127   // is the main thread of the process.
128   void UpdateProcessNameFromThreadName(uint32_t tid, StringId thread_name);
129 
130   // Called when a process is seen in a process tree. Retrieves the UniquePid
131   // for that pid or assigns a new one.
132   // Virtual for testing.
133   virtual UniquePid GetOrCreateProcess(uint32_t pid);
134 
135   // Returns the bounds of a range that includes all UniquePids that have the
136   // requested pid.
UpidsForPidForTesting(uint32_t pid)137   UniqueProcessBounds UpidsForPidForTesting(uint32_t pid) {
138     return pids_.equal_range(pid);
139   }
140 
141   // Returns the bounds of a range that includes all UniqueTids that have the
142   // requested tid.
UtidsForTidForTesting(uint32_t tid)143   UniqueThreadBounds UtidsForTidForTesting(uint32_t tid) {
144     const auto& deque = tids_[tid];
145     return std::make_pair(deque.begin(), deque.end());
146   }
147 
148   // Marks the two threads as belonging to the same process, even if we don't
149   // know which one yet. If one of the two threads is later mapped to a process,
150   // the other will be mapped to the same process. The order of the two threads
151   // is irrelevant, Associate(A, B) has the same effect of Associate(B, A).
152   void AssociateThreads(UniqueTid, UniqueTid);
153 
154   // Creates the mapping from tid 0 <-> utid 0 and pid 0 <-> upid 0. This is
155   // done for Linux-based system traces (proto or ftrace format) as for these
156   // traces, we always have the "swapper" (idle) process having tid/pid 0.
157   void SetPidZeroIgnoredForIdleProcess();
158 
159   // Returns a BoundInserter to add arguments to the arg set of a process.
160   // Arguments are flushed into trace storage only after the trace was loaded in
161   // its entirety.
162   ArgsTracker::BoundInserter AddArgsTo(UniquePid upid);
163 
164   // Called when the trace was fully loaded.
165   void NotifyEndOfFile();
166 
167  private:
168   // Returns the utid of a thread having |tid| and |pid| as the parent process.
169   // pid == base::nullopt matches all processes.
170   // Returns base::nullopt if such a thread doesn't exist.
171   base::Optional<uint32_t> GetThreadOrNull(uint32_t tid,
172                                            base::Optional<uint32_t> pid);
173 
174   // Called whenever we discover that the passed thread belongs to the passed
175   // process. The |pending_assocs_| vector is scanned to see if there are any
176   // other threads associated to the passed thread.
177   void ResolvePendingAssociations(UniqueTid, UniquePid);
178 
179   // Writes the association that the passed thread belongs to the passed
180   // process.
181   void AssociateThreadToProcess(UniqueTid, UniquePid);
182 
183   TraceProcessorContext* const context_;
184 
185   ArgsTracker args_tracker_;
186 
187   // Each tid can have multiple UniqueTid entries, a new UniqueTid is assigned
188   // each time a thread is seen in the trace.
189   std::map<uint32_t /* tid */, std::vector<UniqueTid>> tids_;
190 
191   // Each pid can have multiple UniquePid entries, a new UniquePid is assigned
192   // each time a process is seen in the trace.
193   std::map<uint32_t /* pid (aka tgid) */, UniquePid> pids_;
194 
195   // Pending thread associations. The meaning of a pair<ThreadA, ThreadB> in
196   // this vector is: we know that A and B belong to the same process, but we
197   // don't know yet which process. A and A are idempotent, as in, pair<A,B> is
198   // equivalent to pair<B,A>.
199   std::vector<std::pair<UniqueTid, UniqueTid>> pending_assocs_;
200 
201   // Pending parent process associations. The meaning of pair<ThreadA, ProcessB>
202   // in this vector is: we know that A created process B but we don't know the
203   // process of A. That is, we don't know the parent *process* of B.
204   std::vector<std::pair<UniqueTid, UniquePid>> pending_parent_assocs_;
205 
206   // A mapping from utid to the priority of a thread name source.
207   std::vector<ThreadNamePriority> thread_name_priorities_;
208 };
209 
210 }  // namespace trace_processor
211 }  // namespace perfetto
212 
213 #endif  // SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_PROCESS_TRACKER_H_
214