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 #include <unordered_set> 22 23 #include "perfetto/ext/base/flat_hash_map.h" 24 #include "perfetto/ext/base/string_view.h" 25 #include "src/trace_processor/importers/common/args_tracker.h" 26 #include "src/trace_processor/storage/trace_storage.h" 27 #include "src/trace_processor/types/trace_processor_context.h" 28 29 namespace perfetto { 30 namespace trace_processor { 31 32 // Thread names can come from different sources, and we don't always want to 33 // overwrite the previously set name. This enum determines the priority of 34 // different sources. 35 enum class ThreadNamePriority { 36 kOther = 0, 37 kFtrace = 1, 38 kProcessTree = 2, 39 kTrackDescriptorThreadType = 3, 40 kTrackDescriptor = 4, 41 42 // Priority when trace processor hardcodes a name for a process (e.g. calling 43 // the idle thread "swapper" when parsing ftrace). 44 // Keep this last. 45 kTraceProcessorConstant = 5, 46 }; 47 48 class ProcessTracker { 49 public: 50 explicit ProcessTracker(TraceProcessorContext*); 51 ProcessTracker(const ProcessTracker&) = delete; 52 ProcessTracker& operator=(const ProcessTracker&) = delete; 53 virtual ~ProcessTracker(); 54 55 using UniqueThreadIterator = std::vector<UniqueTid>::const_iterator; 56 using UniqueThreadBounds = 57 std::pair<UniqueThreadIterator, UniqueThreadIterator>; 58 59 // TODO(b/110409911): Invalidation of process and threads is yet to be 60 // implemented. This will include passing timestamps into the below methods 61 // to ensure the correct upid/utid is found. 62 63 // Called when a task_newtask is observed. This force the tracker to start 64 // a new UTID for the thread, which is needed for TID-recycling resolution. 65 UniqueTid StartNewThread(base::Optional<int64_t> timestamp, uint32_t tid); 66 67 // Returns whether a thread is considered alive by the process tracker. 68 bool IsThreadAlive(UniqueTid utid); 69 70 // Called when sched_process_exit is observed. This forces the tracker to 71 // end the thread lifetime for the utid associated with the given tid. 72 void EndThread(int64_t timestamp, uint32_t tid); 73 74 // Returns the thread utid or base::nullopt if it doesn't exist. 75 base::Optional<UniqueTid> GetThreadOrNull(uint32_t tid); 76 77 // Returns the thread utid (or creates a new entry if not present) 78 UniqueTid GetOrCreateThread(uint32_t tid); 79 80 // Assigns the given name to the thread if the new name has a higher priority 81 // than the existing one. Returns the utid of the thread. 82 virtual UniqueTid UpdateThreadName(uint32_t tid, 83 StringId thread_name_id, 84 ThreadNamePriority priority); 85 86 // Assigns the given name to the thread if the new name has a higher priority 87 // than the existing one. The thread is identified by utid. 88 virtual void UpdateThreadNameByUtid(UniqueTid utid, 89 StringId thread_name_id, 90 ThreadNamePriority priority); 91 92 // Called when a thread is seen the process tree. Retrieves the matching utid 93 // for the tid and the matching upid for the tgid and stores both. 94 // Virtual for testing. 95 virtual UniqueTid UpdateThread(uint32_t tid, uint32_t tgid); 96 97 // Associates trusted_pid with track UUID. 98 void UpdateTrustedPid(uint32_t trusted_pid, uint64_t uuid); 99 100 // Returns the trusted_pid associated with the track UUID, or base::nullopt if 101 // not found. 102 base::Optional<uint32_t> GetTrustedPid(uint64_t uuid); 103 104 // Performs namespace-local to root-level resolution of thread or process id, 105 // given tid (can be root-level or namespace-local, but we don't know 106 // beforehand) and root-level pid/tgid that the thread belongs to. 107 // Returns the root-level thread id for tid on successful resolution; 108 // otherwise, returns base::nullopt on resolution failure, or the thread of 109 // tid isn't running in a pid namespace. 110 base::Optional<uint32_t> ResolveNamespacedTid(uint32_t root_level_pid, 111 uint32_t tid); 112 113 // Called when a task_newtask without the CLONE_THREAD flag is observed. 114 // This force the tracker to start both a new UTID and a new UPID. 115 UniquePid StartNewProcess(base::Optional<int64_t> timestamp, 116 base::Optional<uint32_t> parent_tid, 117 uint32_t pid, 118 StringId main_thread_name, 119 ThreadNamePriority priority); 120 121 // Called when a process is seen in a process tree. Retrieves the UniquePid 122 // for that pid or assigns a new one. 123 // Virtual for testing. 124 virtual UniquePid SetProcessMetadata(uint32_t pid, 125 base::Optional<uint32_t> ppid, 126 base::StringView name, 127 base::StringView cmdline); 128 129 // Sets the process user id. 130 void SetProcessUid(UniquePid upid, uint32_t uid); 131 132 // Assigns the given name to the process identified by |upid| if it does not 133 // have a name yet. 134 virtual void SetProcessNameIfUnset(UniquePid upid, StringId process_name_id); 135 136 // Sets the start timestamp to the process identified by |upid| if it doesn't 137 // have a timestamp yet. 138 void SetStartTsIfUnset(UniquePid upid, int64_t start_ts_nanoseconds); 139 140 // Called on a task rename event to set the thread name and possibly process 141 // name (if the tid provided is the main thread of the process). 142 void UpdateThreadNameAndMaybeProcessName(uint32_t tid, 143 StringId thread_name, 144 ThreadNamePriority priority); 145 146 // Called when a process is seen in a process tree. Retrieves the UniquePid 147 // for that pid or assigns a new one. 148 // Virtual for testing. 149 virtual UniquePid GetOrCreateProcess(uint32_t pid); 150 151 // Returns the upid for a given pid. UpidForPidForTesting(uint32_t pid)152 base::Optional<UniquePid> UpidForPidForTesting(uint32_t pid) { 153 auto it = pids_.Find(pid); 154 return it ? base::make_optional(*it) : base::nullopt; 155 } 156 157 // Returns the bounds of a range that includes all UniqueTids that have the 158 // requested tid. UtidsForTidForTesting(uint32_t tid)159 UniqueThreadBounds UtidsForTidForTesting(uint32_t tid) { 160 const auto& deque = tids_[tid]; 161 return std::make_pair(deque.begin(), deque.end()); 162 } 163 164 // Marks the two threads as belonging to the same process, even if we don't 165 // know which one yet. If one of the two threads is later mapped to a process, 166 // the other will be mapped to the same process. The order of the two threads 167 // is irrelevant, Associate(A, B) has the same effect of Associate(B, A). 168 void AssociateThreads(UniqueTid, UniqueTid); 169 170 // Creates the mapping from tid 0 <-> utid 0 and pid 0 <-> upid 0. This is 171 // done for Linux-based system traces (proto or ftrace format) as for these 172 // traces, we always have the "swapper" (idle) process having tid/pid 0. 173 void SetPidZeroIgnoredForIdleProcess(); 174 175 // Returns a BoundInserter to add arguments to the arg set of a process. 176 // Arguments are flushed into trace storage only after the trace was loaded in 177 // its entirety. 178 ArgsTracker::BoundInserter AddArgsTo(UniquePid upid); 179 180 // Called when the trace was fully loaded. 181 void NotifyEndOfFile(); 182 183 // Tracks the namespace-local pids for a process running in a pid namespace. 184 void UpdateNamespacedProcess(uint32_t pid, std::vector<uint32_t> nspid); 185 186 // Tracks the namespace-local thread ids for a thread running in a pid 187 // namespace. 188 void UpdateNamespacedThread(uint32_t pid, 189 uint32_t tid, 190 std::vector<uint32_t> nstid); 191 192 private: 193 // Returns the utid of a thread having |tid| and |pid| as the parent process. 194 // pid == base::nullopt matches all processes. 195 // Returns base::nullopt if such a thread doesn't exist. 196 base::Optional<uint32_t> GetThreadOrNull(uint32_t tid, 197 base::Optional<uint32_t> pid); 198 199 // Called whenever we discover that the passed thread belongs to the passed 200 // process. The |pending_assocs_| vector is scanned to see if there are any 201 // other threads associated to the passed thread. 202 void ResolvePendingAssociations(UniqueTid, UniquePid); 203 204 // Writes the association that the passed thread belongs to the passed 205 // process. 206 void AssociateThreadToProcess(UniqueTid, UniquePid); 207 208 TraceProcessorContext* const context_; 209 210 ArgsTracker args_tracker_; 211 212 // Mapping for tid to the vector of possible UniqueTids. 213 // TODO(lalitm): this is a one-many mapping because this code was written 214 // before global sorting was a thing so multiple threads could be "active" 215 // simultaneously. This is no longer the case so this should be removed 216 // (though it seems like there are subtle things which break in Chrome if this 217 // changes). 218 base::FlatHashMap<uint32_t /* tid */, std::vector<UniqueTid>> tids_; 219 220 // Mapping of the most recently seen pid to the associated upid. 221 base::FlatHashMap<uint32_t /* pid (aka tgid) */, UniquePid> pids_; 222 223 // Pending thread associations. The meaning of a pair<ThreadA, ThreadB> in 224 // this vector is: we know that A and B belong to the same process, but we 225 // don't know yet which process. A and A are idempotent, as in, pair<A,B> is 226 // equivalent to pair<B,A>. 227 std::vector<std::pair<UniqueTid, UniqueTid>> pending_assocs_; 228 229 // Pending parent process associations. The meaning of pair<ThreadA, ProcessB> 230 // in this vector is: we know that A created process B but we don't know the 231 // process of A. That is, we don't know the parent *process* of B. 232 std::vector<std::pair<UniqueTid, UniquePid>> pending_parent_assocs_; 233 234 // A mapping from utid to the priority of a thread name source. 235 std::vector<ThreadNamePriority> thread_name_priorities_; 236 237 // A mapping from track UUIDs to trusted pids. 238 std::unordered_map<uint64_t, uint32_t> trusted_pids_; 239 240 struct NamespacedThread { 241 uint32_t pid; // Root-level pid. 242 uint32_t tid; // Root-level tid. 243 std::vector<uint32_t> nstid; // Namespace-local tids. 244 }; 245 // Keeps track of pid-namespaced threads, keyed by root-level thread ids. 246 std::unordered_map<uint32_t /* tid */, NamespacedThread> namespaced_threads_; 247 248 struct NamespacedProcess { 249 uint32_t pid; // Root-level pid. 250 std::vector<uint32_t> nspid; // Namespace-local pids. 251 std::unordered_set<uint32_t> threads; // Root-level thread IDs. 252 }; 253 // Keeps track pid-namespaced processes, keyed by root-level pids. 254 std::unordered_map<uint32_t /* pid (aka tgid) */, NamespacedProcess> 255 namespaced_processes_; 256 }; 257 258 } // namespace trace_processor 259 } // namespace perfetto 260 261 #endif // SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_PROCESS_TRACKER_H_ 262