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