• 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/storage/trace_storage.h"
24 #include "src/trace_processor/types/trace_processor_context.h"
25 
26 namespace perfetto {
27 namespace trace_processor {
28 
29 class ProcessTracker {
30  public:
31   explicit ProcessTracker(TraceProcessorContext*);
32   ProcessTracker(const ProcessTracker&) = delete;
33   ProcessTracker& operator=(const ProcessTracker&) = delete;
34   virtual ~ProcessTracker();
35 
36   using UniqueProcessIterator =
37       std::multimap<uint32_t, UniquePid>::const_iterator;
38   using UniqueProcessBounds =
39       std::pair<UniqueProcessIterator, UniqueProcessIterator>;
40 
41   using UniqueThreadIterator = std::vector<UniqueTid>::const_iterator;
42   using UniqueThreadBounds =
43       std::pair<UniqueThreadIterator, UniqueThreadIterator>;
44 
45   // TODO(b/110409911): Invalidation of process and threads is yet to be
46   // implemented. This will include passing timestamps into the below methods
47   // to ensure the correct upid/utid is found.
48 
49   // Called when a task_newtask is observed. This force the tracker to start
50   // a new UTID for the thread, which is needed for TID-recycling resolution.
51   UniqueTid StartNewThread(base::Optional<int64_t> timestamp,
52                            uint32_t tid,
53                            StringId thread_name_id);
54 
55   // Returns whether a thread is considered alive by the process tracker.
56   bool IsThreadAlive(UniqueTid utid);
57 
58   // Called when sched_process_exit is observed. This forces the tracker to
59   // end the thread lifetime for the utid associated with the given tid.
60   void EndThread(int64_t timestamp, uint32_t tid);
61 
62   // Returns the thread utid or base::nullopt if it doesn't exist.
63   base::Optional<UniqueTid> GetThreadOrNull(uint32_t tid);
64 
65   // Returns the thread utid (or creates a new entry if not present)
66   UniqueTid GetOrCreateThread(uint32_t tid);
67 
68   // Called when a sched switch event is seen in the trace. Retrieves the
69   // UniqueTid that matches the tid or assigns a new UniqueTid and stores
70   // the thread_name_id.
71   virtual UniqueTid UpdateThreadName(uint32_t tid, StringId thread_name_id);
72 
73   // Assigns the given name to the thread identified |utid| if it does not
74   // have a name yet.
75   virtual void SetThreadNameIfUnset(UniqueTid utid, StringId thread_name_id);
76 
77   // Called when a thread is seen the process tree. Retrieves the matching utid
78   // for the tid and the matching upid for the tgid and stores both.
79   // Virtual for testing.
80   virtual UniqueTid UpdateThread(uint32_t tid, uint32_t tgid);
81 
82   // Called when a task_newtask without the CLONE_THREAD flag is observed.
83   // This force the tracker to start both a new UTID and a new UPID.
84   UniquePid StartNewProcess(base::Optional<int64_t> timestamp,
85                             base::Optional<uint32_t> parent_tid,
86                             uint32_t pid,
87                             StringId main_thread_name);
88 
89   // Called when a process is seen in a process tree. Retrieves the UniquePid
90   // for that pid or assigns a new one.
91   // Virtual for testing.
92   virtual UniquePid SetProcessMetadata(uint32_t pid,
93                                        base::Optional<uint32_t> ppid,
94                                        base::StringView name);
95 
96   // Sets the process user id.
97   void SetProcessUid(UniquePid upid, uint32_t uid);
98 
99   // Assigns the given name to the process identified by |upid| if it does not
100   // have a name yet.
101   virtual void SetProcessNameIfUnset(UniquePid upid, StringId process_name_id);
102 
103   // Called on a task rename event to set the process name if the tid provided
104   // is the main thread of the process.
105   void UpdateProcessNameFromThreadName(uint32_t tid, StringId 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 GetOrCreateProcess(uint32_t pid);
111 
112   // Returns the bounds of a range that includes all UniquePids that have the
113   // requested pid.
UpidsForPidForTesting(uint32_t pid)114   UniqueProcessBounds UpidsForPidForTesting(uint32_t pid) {
115     return pids_.equal_range(pid);
116   }
117 
118   // Returns the bounds of a range that includes all UniqueTids that have the
119   // requested tid.
UtidsForTidForTesting(uint32_t tid)120   UniqueThreadBounds UtidsForTidForTesting(uint32_t tid) {
121     const auto& deque = tids_[tid];
122     return std::make_pair(deque.begin(), deque.end());
123   }
124 
125   // Marks the two threads as belonging to the same process, even if we don't
126   // know which one yet. If one of the two threads is later mapped to a process,
127   // the other will be mapped to the same process. The order of the two threads
128   // is irrelevant, Associate(A, B) has the same effect of Associate(B, A).
129   void AssociateThreads(UniqueTid, UniqueTid);
130 
131   // Creates the mapping from tid 0 <-> utid 0 and pid 0 <-> upid 0. This is
132   // done for Linux-based system traces (proto or ftrace format) as for these
133   // traces, we always have the "swapper" (idle) process having tid/pid 0.
134   void SetPidZeroIgnoredForIdleProcess();
135 
136  private:
137   // Returns the utid of a thread having |tid| and |pid| as the parent process.
138   // pid == base::nullopt matches all processes.
139   // Returns base::nullopt if such a thread doesn't exist.
140   base::Optional<uint32_t> GetThreadOrNull(uint32_t tid,
141                                            base::Optional<uint32_t> pid);
142 
143   // Called whenever we discover that the passed thread belongs to the passed
144   // process. The |pending_assocs_| vector is scanned to see if there are any
145   // other threads associated to the passed thread.
146   void ResolvePendingAssociations(UniqueTid, UniquePid);
147 
148   // Writes the association that the passed thread belongs to the passed
149   // process.
150   void AssociateThreadToProcess(UniqueTid, UniquePid);
151 
152   TraceProcessorContext* const context_;
153 
154   // Each tid can have multiple UniqueTid entries, a new UniqueTid is assigned
155   // each time a thread is seen in the trace.
156   std::map<uint32_t /* tid */, std::vector<UniqueTid>> tids_;
157 
158   // Each pid can have multiple UniquePid entries, a new UniquePid is assigned
159   // each time a process is seen in the trace.
160   std::map<uint32_t /* pid (aka tgid) */, UniquePid> pids_;
161 
162   // Pending thread associations. The meaning of a pair<ThreadA, ThreadB> in
163   // this vector is: we know that A and B belong to the same process, but we
164   // don't know yet which process. A and A are idempotent, as in, pair<A,B> is
165   // equivalent to pair<B,A>.
166   std::vector<std::pair<UniqueTid, UniqueTid>> pending_assocs_;
167 
168   // Pending parent process associations. The meaning of pair<ThreadA, ProcessB>
169   // in this vector is: we know that A created process B but we don't know the
170   // process of A. That is, we don't know the parent *process* of B.
171   std::vector<std::pair<UniqueTid, UniquePid>> pending_parent_assocs_;
172 };
173 
174 }  // namespace trace_processor
175 }  // namespace perfetto
176 
177 #endif  // SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_PROCESS_TRACKER_H_
178