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