1*288bf522SAndroid Build Coastguard Worker /* 2*288bf522SAndroid Build Coastguard Worker * Copyright (C) 2018 The Android Open Source Project 3*288bf522SAndroid Build Coastguard Worker * 4*288bf522SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*288bf522SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*288bf522SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*288bf522SAndroid Build Coastguard Worker * 8*288bf522SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*288bf522SAndroid Build Coastguard Worker * 10*288bf522SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*288bf522SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*288bf522SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*288bf522SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*288bf522SAndroid Build Coastguard Worker * limitations under the License. 15*288bf522SAndroid Build Coastguard Worker */ 16*288bf522SAndroid Build Coastguard Worker 17*288bf522SAndroid Build Coastguard Worker #ifndef SIMPLE_PERF_JIT_DEBUG_READER_H_ 18*288bf522SAndroid Build Coastguard Worker #define SIMPLE_PERF_JIT_DEBUG_READER_H_ 19*288bf522SAndroid Build Coastguard Worker 20*288bf522SAndroid Build Coastguard Worker #include <unistd.h> 21*288bf522SAndroid Build Coastguard Worker 22*288bf522SAndroid Build Coastguard Worker #include <functional> 23*288bf522SAndroid Build Coastguard Worker #include <memory> 24*288bf522SAndroid Build Coastguard Worker #include <queue> 25*288bf522SAndroid Build Coastguard Worker #include <stack> 26*288bf522SAndroid Build Coastguard Worker #include <unordered_map> 27*288bf522SAndroid Build Coastguard Worker #include <unordered_set> 28*288bf522SAndroid Build Coastguard Worker #include <vector> 29*288bf522SAndroid Build Coastguard Worker 30*288bf522SAndroid Build Coastguard Worker #include <android-base/file.h> 31*288bf522SAndroid Build Coastguard Worker #include <android-base/logging.h> 32*288bf522SAndroid Build Coastguard Worker 33*288bf522SAndroid Build Coastguard Worker #include "IOEventLoop.h" 34*288bf522SAndroid Build Coastguard Worker #include "environment.h" 35*288bf522SAndroid Build Coastguard Worker #include "record.h" 36*288bf522SAndroid Build Coastguard Worker 37*288bf522SAndroid Build Coastguard Worker namespace simpleperf { 38*288bf522SAndroid Build Coastguard Worker 39*288bf522SAndroid Build Coastguard Worker inline constexpr const char* kJITAppCacheFile = "jit_app_cache"; 40*288bf522SAndroid Build Coastguard Worker inline constexpr const char* kJITZygoteCacheFile = "jit_zygote_cache"; 41*288bf522SAndroid Build Coastguard Worker inline constexpr const char* kDexFileInMemoryPrefix = "dexfile_in_memory"; 42*288bf522SAndroid Build Coastguard Worker 43*288bf522SAndroid Build Coastguard Worker namespace JITDebugReader_impl { 44*288bf522SAndroid Build Coastguard Worker 45*288bf522SAndroid Build Coastguard Worker enum class DescriptorType { 46*288bf522SAndroid Build Coastguard Worker kDEX, 47*288bf522SAndroid Build Coastguard Worker kJIT, 48*288bf522SAndroid Build Coastguard Worker }; 49*288bf522SAndroid Build Coastguard Worker 50*288bf522SAndroid Build Coastguard Worker // An arch-independent representation of JIT/dex debug descriptor. 51*288bf522SAndroid Build Coastguard Worker struct Descriptor { 52*288bf522SAndroid Build Coastguard Worker DescriptorType type; 53*288bf522SAndroid Build Coastguard Worker int version = 0; 54*288bf522SAndroid Build Coastguard Worker uint32_t action_seqlock = 0; // incremented before and after any modification 55*288bf522SAndroid Build Coastguard Worker uint64_t action_timestamp = 0; // CLOCK_MONOTONIC time of last action 56*288bf522SAndroid Build Coastguard Worker uint64_t first_entry_addr = 0; 57*288bf522SAndroid Build Coastguard Worker }; 58*288bf522SAndroid Build Coastguard Worker 59*288bf522SAndroid Build Coastguard Worker // An arch-independent representation of JIT/dex code entry. 60*288bf522SAndroid Build Coastguard Worker struct CodeEntry { 61*288bf522SAndroid Build Coastguard Worker uint64_t addr; 62*288bf522SAndroid Build Coastguard Worker uint64_t symfile_addr; 63*288bf522SAndroid Build Coastguard Worker uint64_t symfile_size; 64*288bf522SAndroid Build Coastguard Worker uint64_t timestamp; // CLOCK_MONOTONIC time of last action 65*288bf522SAndroid Build Coastguard Worker }; 66*288bf522SAndroid Build Coastguard Worker 67*288bf522SAndroid Build Coastguard Worker struct Process { 68*288bf522SAndroid Build Coastguard Worker pid_t pid = -1; 69*288bf522SAndroid Build Coastguard Worker bool initialized = false; 70*288bf522SAndroid Build Coastguard Worker bool died = false; 71*288bf522SAndroid Build Coastguard Worker bool is_64bit = false; 72*288bf522SAndroid Build Coastguard Worker // remote addr of jit descriptor 73*288bf522SAndroid Build Coastguard Worker uint64_t jit_descriptor_addr = 0; 74*288bf522SAndroid Build Coastguard Worker // remote addr of dex descriptor 75*288bf522SAndroid Build Coastguard Worker uint64_t dex_descriptor_addr = 0; 76*288bf522SAndroid Build Coastguard Worker 77*288bf522SAndroid Build Coastguard Worker // The state we know about the remote jit debug descriptor. 78*288bf522SAndroid Build Coastguard Worker Descriptor last_jit_descriptor; 79*288bf522SAndroid Build Coastguard Worker // The state we know about the remote dex debug descriptor. 80*288bf522SAndroid Build Coastguard Worker Descriptor last_dex_descriptor; 81*288bf522SAndroid Build Coastguard Worker 82*288bf522SAndroid Build Coastguard Worker // memory space for /memfd:jit-zygote-cache 83*288bf522SAndroid Build Coastguard Worker std::vector<std::pair<uint64_t, uint64_t>> jit_zygote_cache_ranges_; 84*288bf522SAndroid Build Coastguard Worker }; 85*288bf522SAndroid Build Coastguard Worker 86*288bf522SAndroid Build Coastguard Worker } // namespace JITDebugReader_impl 87*288bf522SAndroid Build Coastguard Worker 88*288bf522SAndroid Build Coastguard Worker // JITDebugInfo represents the debug info of a JITed Java method or a dex file. 89*288bf522SAndroid Build Coastguard Worker struct JITDebugInfo { 90*288bf522SAndroid Build Coastguard Worker enum { 91*288bf522SAndroid Build Coastguard Worker JIT_DEBUG_JIT_CODE, 92*288bf522SAndroid Build Coastguard Worker JIT_DEBUG_DEX_FILE, 93*288bf522SAndroid Build Coastguard Worker } type; 94*288bf522SAndroid Build Coastguard Worker pid_t pid; // Process of the debug info 95*288bf522SAndroid Build Coastguard Worker uint64_t timestamp; // Monotonic timestamp for the creation of the debug info 96*288bf522SAndroid Build Coastguard Worker 97*288bf522SAndroid Build Coastguard Worker union { 98*288bf522SAndroid Build Coastguard Worker struct { 99*288bf522SAndroid Build Coastguard Worker uint64_t jit_code_addr; // The start addr of the JITed code 100*288bf522SAndroid Build Coastguard Worker uint64_t jit_code_len; // The end addr of the JITed code 101*288bf522SAndroid Build Coastguard Worker }; 102*288bf522SAndroid Build Coastguard Worker uint64_t dex_file_offset; // The offset of the dex file in the file containing it 103*288bf522SAndroid Build Coastguard Worker }; 104*288bf522SAndroid Build Coastguard Worker // For JITed code, it is the path of a temporary ELF file storing its debug info. 105*288bf522SAndroid Build Coastguard Worker // For dex file, it is the path of the file containing the dex file. 106*288bf522SAndroid Build Coastguard Worker std::string file_path; 107*288bf522SAndroid Build Coastguard Worker uint64_t file_offset; 108*288bf522SAndroid Build Coastguard Worker 109*288bf522SAndroid Build Coastguard Worker // dex_file_map may be a dex file extracted in memory. On Android >= Q, ART may extract dex files 110*288bf522SAndroid Build Coastguard Worker // in apk files directly into memory, and name it using prctl(). The kernel doesn't generate a 111*288bf522SAndroid Build Coastguard Worker // new mmap record for it. So we need to dump it manually. 112*288bf522SAndroid Build Coastguard Worker // Or dex_file_map may be a dex file created in memory. In that case, symbols are read from the 113*288bf522SAndroid Build Coastguard Worker // dex file. 114*288bf522SAndroid Build Coastguard Worker std::shared_ptr<ThreadMmap> dex_file_map; 115*288bf522SAndroid Build Coastguard Worker std::vector<Symbol> symbols; 116*288bf522SAndroid Build Coastguard Worker JITDebugInfoJITDebugInfo117*288bf522SAndroid Build Coastguard Worker JITDebugInfo(pid_t pid, uint64_t timestamp, uint64_t jit_code_addr, uint64_t jit_code_len, 118*288bf522SAndroid Build Coastguard Worker const std::string& file_path, uint64_t file_offset) 119*288bf522SAndroid Build Coastguard Worker : type(JIT_DEBUG_JIT_CODE), 120*288bf522SAndroid Build Coastguard Worker pid(pid), 121*288bf522SAndroid Build Coastguard Worker timestamp(timestamp), 122*288bf522SAndroid Build Coastguard Worker jit_code_addr(jit_code_addr), 123*288bf522SAndroid Build Coastguard Worker jit_code_len(jit_code_len), 124*288bf522SAndroid Build Coastguard Worker file_path(file_path), 125*288bf522SAndroid Build Coastguard Worker file_offset(file_offset) {} 126*288bf522SAndroid Build Coastguard Worker JITDebugInfoJITDebugInfo127*288bf522SAndroid Build Coastguard Worker JITDebugInfo(pid_t pid, uint64_t timestamp, uint64_t dex_file_offset, 128*288bf522SAndroid Build Coastguard Worker const std::string& file_path, const std::shared_ptr<ThreadMmap>& dex_file_map, 129*288bf522SAndroid Build Coastguard Worker std::vector<Symbol> symbols) 130*288bf522SAndroid Build Coastguard Worker : type(JIT_DEBUG_DEX_FILE), 131*288bf522SAndroid Build Coastguard Worker pid(pid), 132*288bf522SAndroid Build Coastguard Worker timestamp(timestamp), 133*288bf522SAndroid Build Coastguard Worker dex_file_offset(dex_file_offset), 134*288bf522SAndroid Build Coastguard Worker file_path(file_path), 135*288bf522SAndroid Build Coastguard Worker file_offset(0), 136*288bf522SAndroid Build Coastguard Worker dex_file_map(dex_file_map), 137*288bf522SAndroid Build Coastguard Worker symbols(std::move(symbols)) {} 138*288bf522SAndroid Build Coastguard Worker 139*288bf522SAndroid Build Coastguard Worker bool operator>(const JITDebugInfo& other) const { return timestamp > other.timestamp; } 140*288bf522SAndroid Build Coastguard Worker }; 141*288bf522SAndroid Build Coastguard Worker 142*288bf522SAndroid Build Coastguard Worker class TempSymFile; 143*288bf522SAndroid Build Coastguard Worker 144*288bf522SAndroid Build Coastguard Worker // JITDebugReader reads debug info of JIT code and dex files of processes using ART. The 145*288bf522SAndroid Build Coastguard Worker // corresponding debug interface in ART is at art/runtime/jit/debugger_interface.cc. 146*288bf522SAndroid Build Coastguard Worker class JITDebugReader { 147*288bf522SAndroid Build Coastguard Worker public: 148*288bf522SAndroid Build Coastguard Worker using Descriptor = JITDebugReader_impl::Descriptor; 149*288bf522SAndroid Build Coastguard Worker using CodeEntry = JITDebugReader_impl::CodeEntry; 150*288bf522SAndroid Build Coastguard Worker using Process = JITDebugReader_impl::Process; 151*288bf522SAndroid Build Coastguard Worker 152*288bf522SAndroid Build Coastguard Worker enum class SymFileOption { 153*288bf522SAndroid Build Coastguard Worker kDropSymFiles, // JIT symfiles are dropped after recording. 154*288bf522SAndroid Build Coastguard Worker kKeepSymFiles, // JIT symfiles are kept after recording, usually for debug unwinding. 155*288bf522SAndroid Build Coastguard Worker }; 156*288bf522SAndroid Build Coastguard Worker 157*288bf522SAndroid Build Coastguard Worker enum class SyncOption { 158*288bf522SAndroid Build Coastguard Worker kNoSync, // Don't sync debug info with records. 159*288bf522SAndroid Build Coastguard Worker kSyncWithRecords, // Sync debug info with records based on monotonic timestamp. 160*288bf522SAndroid Build Coastguard Worker }; 161*288bf522SAndroid Build Coastguard Worker 162*288bf522SAndroid Build Coastguard Worker // symfile_prefix: JITDebugReader creates temporary file to store symfiles for JIT code. Add this 163*288bf522SAndroid Build Coastguard Worker // prefix to avoid conflicts. 164*288bf522SAndroid Build Coastguard Worker JITDebugReader(const std::string& symfile_prefix, SymFileOption symfile_option, 165*288bf522SAndroid Build Coastguard Worker SyncOption sync_option); 166*288bf522SAndroid Build Coastguard Worker 167*288bf522SAndroid Build Coastguard Worker ~JITDebugReader(); 168*288bf522SAndroid Build Coastguard Worker SyncWithRecords()169*288bf522SAndroid Build Coastguard Worker bool SyncWithRecords() const { return sync_option_ == SyncOption::kSyncWithRecords; } 170*288bf522SAndroid Build Coastguard Worker 171*288bf522SAndroid Build Coastguard Worker typedef std::function<bool(std::vector<JITDebugInfo>, bool)> debug_info_callback_t; 172*288bf522SAndroid Build Coastguard Worker bool RegisterDebugInfoCallback(IOEventLoop* loop, const debug_info_callback_t& callback); 173*288bf522SAndroid Build Coastguard Worker 174*288bf522SAndroid Build Coastguard Worker // There are two ways to select which processes to monitor. One is using MonitorProcess(), the 175*288bf522SAndroid Build Coastguard Worker // other is finding all processes having libart.so using records. 176*288bf522SAndroid Build Coastguard Worker bool MonitorProcess(pid_t pid); 177*288bf522SAndroid Build Coastguard Worker bool UpdateRecord(const Record* record); 178*288bf522SAndroid Build Coastguard Worker 179*288bf522SAndroid Build Coastguard Worker // Read new debug info from all monitored processes. 180*288bf522SAndroid Build Coastguard Worker bool ReadAllProcesses(); 181*288bf522SAndroid Build Coastguard Worker // Read new debug info from one process. 182*288bf522SAndroid Build Coastguard Worker bool ReadProcess(pid_t pid); 183*288bf522SAndroid Build Coastguard Worker 184*288bf522SAndroid Build Coastguard Worker // Flush all debug info registered before timestamp. 185*288bf522SAndroid Build Coastguard Worker bool FlushDebugInfo(uint64_t timestamp); 186*288bf522SAndroid Build Coastguard Worker IsPathInJITSymFile(const std::string & path)187*288bf522SAndroid Build Coastguard Worker static bool IsPathInJITSymFile(const std::string& path) { 188*288bf522SAndroid Build Coastguard Worker return path.find(std::string("_") + kJITAppCacheFile + ":") != path.npos || 189*288bf522SAndroid Build Coastguard Worker path.find(std::string("_") + kJITZygoteCacheFile + ":") != path.npos; 190*288bf522SAndroid Build Coastguard Worker } 191*288bf522SAndroid Build Coastguard Worker 192*288bf522SAndroid Build Coastguard Worker // exported for testing 193*288bf522SAndroid Build Coastguard Worker void ReadDexFileDebugInfo(Process& process, const std::vector<CodeEntry>& dex_entries, 194*288bf522SAndroid Build Coastguard Worker std::vector<JITDebugInfo>* debug_info); 195*288bf522SAndroid Build Coastguard Worker 196*288bf522SAndroid Build Coastguard Worker private: 197*288bf522SAndroid Build Coastguard Worker // The location of descriptors in libart.so. 198*288bf522SAndroid Build Coastguard Worker struct DescriptorsLocation { 199*288bf522SAndroid Build Coastguard Worker bool is_64bit = false; 200*288bf522SAndroid Build Coastguard Worker uint64_t jit_descriptor_addr = 0; 201*288bf522SAndroid Build Coastguard Worker uint64_t dex_descriptor_addr = 0; 202*288bf522SAndroid Build Coastguard Worker }; 203*288bf522SAndroid Build Coastguard Worker 204*288bf522SAndroid Build Coastguard Worker bool ReadProcess(Process& process, std::vector<JITDebugInfo>* debug_info); 205*288bf522SAndroid Build Coastguard Worker bool ReadDebugInfo(Process& process, Descriptor& new_descriptor, 206*288bf522SAndroid Build Coastguard Worker std::vector<JITDebugInfo>* debug_info); 207*288bf522SAndroid Build Coastguard Worker bool IsDescriptorChanged(Process& process, Descriptor& old_descriptor); 208*288bf522SAndroid Build Coastguard Worker bool InitializeProcess(Process& process); 209*288bf522SAndroid Build Coastguard Worker const DescriptorsLocation* GetDescriptorsLocation(const std::string& art_lib_path); 210*288bf522SAndroid Build Coastguard Worker bool ReadRemoteMem(Process& process, uint64_t remote_addr, uint64_t size, void* data); 211*288bf522SAndroid Build Coastguard Worker bool ReadDescriptors(Process& process, Descriptor* jit_descriptor, Descriptor* dex_descriptor); 212*288bf522SAndroid Build Coastguard Worker template <typename DescriptorT> 213*288bf522SAndroid Build Coastguard Worker bool ReadDescriptorsImpl(Process& process, Descriptor* jit_descriptor, 214*288bf522SAndroid Build Coastguard Worker Descriptor* dex_descriptor); 215*288bf522SAndroid Build Coastguard Worker template <typename DescriptorT> 216*288bf522SAndroid Build Coastguard Worker bool ParseDescriptor(const DescriptorT& raw_descriptor, Descriptor* descriptor); 217*288bf522SAndroid Build Coastguard Worker 218*288bf522SAndroid Build Coastguard Worker bool ReadNewCodeEntries(Process& process, const Descriptor& descriptor, 219*288bf522SAndroid Build Coastguard Worker uint64_t last_action_timestamp, uint32_t read_entry_limit, 220*288bf522SAndroid Build Coastguard Worker std::vector<CodeEntry>* new_code_entries); 221*288bf522SAndroid Build Coastguard Worker template <typename CodeEntryT> 222*288bf522SAndroid Build Coastguard Worker bool ReadNewCodeEntriesImpl(Process& process, const Descriptor& descriptor, 223*288bf522SAndroid Build Coastguard Worker uint64_t last_action_timestamp, uint32_t read_entry_limit, 224*288bf522SAndroid Build Coastguard Worker std::vector<CodeEntry>* new_code_entries); 225*288bf522SAndroid Build Coastguard Worker 226*288bf522SAndroid Build Coastguard Worker bool ReadJITCodeDebugInfo(Process& process, const std::vector<CodeEntry>& jit_entries, 227*288bf522SAndroid Build Coastguard Worker std::vector<JITDebugInfo>* debug_info); 228*288bf522SAndroid Build Coastguard Worker TempSymFile* GetTempSymFile(Process& process, const CodeEntry& jit_entry); 229*288bf522SAndroid Build Coastguard Worker std::vector<Symbol> ReadDexFileSymbolsInMemory(Process& process, uint64_t addr, uint64_t size); 230*288bf522SAndroid Build Coastguard Worker bool AddDebugInfo(std::vector<JITDebugInfo> debug_info, bool sync_kernel_records); 231*288bf522SAndroid Build Coastguard Worker 232*288bf522SAndroid Build Coastguard Worker const std::string symfile_prefix_; 233*288bf522SAndroid Build Coastguard Worker SymFileOption symfile_option_; 234*288bf522SAndroid Build Coastguard Worker SyncOption sync_option_; 235*288bf522SAndroid Build Coastguard Worker IOEventRef read_event_ = nullptr; 236*288bf522SAndroid Build Coastguard Worker debug_info_callback_t debug_info_callback_; 237*288bf522SAndroid Build Coastguard Worker 238*288bf522SAndroid Build Coastguard Worker // Keys are pids of processes having libart.so, values show whether a process has been monitored. 239*288bf522SAndroid Build Coastguard Worker std::unordered_map<pid_t, bool> pids_with_art_lib_; 240*288bf522SAndroid Build Coastguard Worker 241*288bf522SAndroid Build Coastguard Worker // All monitored processes 242*288bf522SAndroid Build Coastguard Worker std::unordered_map<pid_t, Process> processes_; 243*288bf522SAndroid Build Coastguard Worker std::unordered_map<std::string, DescriptorsLocation> descriptors_location_cache_; 244*288bf522SAndroid Build Coastguard Worker 245*288bf522SAndroid Build Coastguard Worker std::priority_queue<JITDebugInfo, std::vector<JITDebugInfo>, std::greater<JITDebugInfo>> 246*288bf522SAndroid Build Coastguard Worker debug_info_q_; 247*288bf522SAndroid Build Coastguard Worker 248*288bf522SAndroid Build Coastguard Worker // temporary files used to store jit symfiles created by the app process and the zygote process. 249*288bf522SAndroid Build Coastguard Worker std::unique_ptr<TempSymFile> app_symfile_; 250*288bf522SAndroid Build Coastguard Worker std::unique_ptr<TempSymFile> zygote_symfile_; 251*288bf522SAndroid Build Coastguard Worker }; 252*288bf522SAndroid Build Coastguard Worker 253*288bf522SAndroid Build Coastguard Worker } // namespace simpleperf 254*288bf522SAndroid Build Coastguard Worker 255*288bf522SAndroid Build Coastguard Worker #endif // SIMPLE_PERF_JIT_DEBUG_READER_H_ 256