diff options
author | Yabin Cui <yabinc@google.com> | 2022-03-24 21:25:51 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2022-03-24 21:25:51 +0000 |
commit | d14f308fe65d808bf4eb4400b9ea3c0357b3b9aa (patch) | |
tree | 676d240bdcb30b87a871d3f4e3ca4b00ec14893e | |
parent | 1ea3d5fc2e8b91eb36dcb4a364265858ca00e4d6 (diff) | |
parent | e5defe1549a03dcd37860728789d990cf45e7405 (diff) | |
download | extras-d14f308fe65d808bf4eb4400b9ea3c0357b3b9aa.tar.gz |
Merge "simpleperf: read jit descriptor and dex descriptor separately."
-rw-r--r-- | simpleperf/JITDebugReader.cpp | 78 | ||||
-rw-r--r-- | simpleperf/JITDebugReader.h | 27 |
2 files changed, 54 insertions, 51 deletions
diff --git a/simpleperf/JITDebugReader.cpp b/simpleperf/JITDebugReader.cpp index 52db2959..28058940 100644 --- a/simpleperf/JITDebugReader.cpp +++ b/simpleperf/JITDebugReader.cpp @@ -411,17 +411,15 @@ bool JITDebugReader::InitializeProcess(Process& process) { if (art_lib_path.empty()) { return false; } - process.is_64bit = art_lib_path.find("lib64") != std::string::npos; // 2. Read libart.so to find the addresses of __jit_debug_descriptor and __dex_debug_descriptor. - const DescriptorsLocation* location = GetDescriptorsLocation(art_lib_path, process.is_64bit); + const DescriptorsLocation* location = GetDescriptorsLocation(art_lib_path); if (location == nullptr) { return false; } - process.descriptors_addr = location->relative_addr + min_vaddr_in_memory; - process.descriptors_size = location->size; - process.jit_descriptor_offset = location->jit_descriptor_offset; - process.dex_descriptor_offset = location->dex_descriptor_offset; + process.is_64bit = location->is_64bit; + process.jit_descriptor_addr = location->jit_descriptor_addr + min_vaddr_in_memory; + process.dex_descriptor_addr = location->dex_descriptor_addr + min_vaddr_in_memory; for (auto& map : thread_mmaps) { if (StartsWith(map.name, kJITZygoteCacheMmapPrefix)) { @@ -434,10 +432,10 @@ bool JITDebugReader::InitializeProcess(Process& process) { } const JITDebugReader::DescriptorsLocation* JITDebugReader::GetDescriptorsLocation( - const std::string& art_lib_path, bool is_64bit) { + const std::string& art_lib_path) { auto it = descriptors_location_cache_.find(art_lib_path); if (it != descriptors_location_cache_.end()) { - return it->second.relative_addr == 0u ? nullptr : &it->second; + return it->second.jit_descriptor_addr == 0u ? nullptr : &it->second; } DescriptorsLocation& location = descriptors_location_cache_[art_lib_path]; @@ -469,18 +467,9 @@ const JITDebugReader::DescriptorsLocation* JITDebugReader::GetDescriptorsLocatio if (jit_addr == 0u || dex_addr == 0u) { return nullptr; } - location.relative_addr = std::min(jit_addr, dex_addr); - location.size = std::max(jit_addr, dex_addr) + - (is_64bit ? sizeof(JITDescriptor64) : sizeof(JITDescriptor32)) - - location.relative_addr; - if (location.size >= 4096u) { - PLOG(WARNING) << "The descriptors_size is unexpected large: " << location.size; - } - if (descriptors_buf_.size() < location.size) { - descriptors_buf_.resize(location.size); - } - location.jit_descriptor_offset = jit_addr - location.relative_addr; - location.dex_descriptor_offset = dex_addr - location.relative_addr; + location.is_64bit = elf->Is64Bit(); + location.jit_descriptor_addr = jit_addr; + location.dex_descriptor_addr = dex_addr; return &location; } @@ -505,14 +494,40 @@ bool JITDebugReader::ReadRemoteMem(Process& process, uint64_t remote_addr, uint6 bool JITDebugReader::ReadDescriptors(Process& process, Descriptor* jit_descriptor, Descriptor* dex_descriptor) { - if (!ReadRemoteMem(process, process.descriptors_addr, process.descriptors_size, - descriptors_buf_.data())) { + if (process.is_64bit) { + return ReadDescriptorsImpl<JITDescriptor64>(process, jit_descriptor, dex_descriptor); + } + return ReadDescriptorsImpl<JITDescriptor32>(process, jit_descriptor, dex_descriptor); +} + +template <typename DescriptorT> +bool JITDebugReader::ReadDescriptorsImpl(Process& process, Descriptor* jit_descriptor, + Descriptor* dex_descriptor) { + DescriptorT raw_jit_descriptor; + DescriptorT raw_dex_descriptor; + iovec local_iovs[2]; + local_iovs[0].iov_base = &raw_jit_descriptor; + local_iovs[0].iov_len = sizeof(DescriptorT); + local_iovs[1].iov_base = &raw_dex_descriptor; + local_iovs[1].iov_len = sizeof(DescriptorT); + iovec remote_iovs[2]; + remote_iovs[0].iov_base = + reinterpret_cast<void*>(static_cast<uintptr_t>(process.jit_descriptor_addr)); + remote_iovs[0].iov_len = sizeof(DescriptorT); + remote_iovs[1].iov_base = + reinterpret_cast<void*>(static_cast<uintptr_t>(process.dex_descriptor_addr)); + remote_iovs[1].iov_len = sizeof(DescriptorT); + ssize_t result = process_vm_readv(process.pid, local_iovs, 2, remote_iovs, 2, 0); + if (static_cast<size_t>(result) != sizeof(DescriptorT) * 2) { + PLOG(DEBUG) << "ReadDescriptor(pid " << process.pid << ", jit_addr " << std::hex + << process.jit_descriptor_addr << ", dex_addr " << process.dex_descriptor_addr + << ") failed"; + process.died = true; return false; } - if (!LoadDescriptor(process.is_64bit, &descriptors_buf_[process.jit_descriptor_offset], - jit_descriptor) || - !LoadDescriptor(process.is_64bit, &descriptors_buf_[process.dex_descriptor_offset], - dex_descriptor)) { + + if (!ParseDescriptor(raw_jit_descriptor, jit_descriptor) || + !ParseDescriptor(raw_dex_descriptor, dex_descriptor)) { return false; } jit_descriptor->type = DescriptorType::kJIT; @@ -520,17 +535,8 @@ bool JITDebugReader::ReadDescriptors(Process& process, Descriptor* jit_descripto return true; } -bool JITDebugReader::LoadDescriptor(bool is_64bit, const char* data, Descriptor* descriptor) { - if (is_64bit) { - return LoadDescriptorImpl<JITDescriptor64>(data, descriptor); - } - return LoadDescriptorImpl<JITDescriptor32>(data, descriptor); -} - template <typename DescriptorT> -bool JITDebugReader::LoadDescriptorImpl(const char* data, Descriptor* descriptor) { - DescriptorT raw_descriptor; - MoveFromBinaryFormat(raw_descriptor, data); +bool JITDebugReader::ParseDescriptor(const DescriptorT& raw_descriptor, Descriptor* descriptor) { if (!raw_descriptor.Valid()) { return false; } diff --git a/simpleperf/JITDebugReader.h b/simpleperf/JITDebugReader.h index 72f3790b..b9e984d5 100644 --- a/simpleperf/JITDebugReader.h +++ b/simpleperf/JITDebugReader.h @@ -162,13 +162,10 @@ class JITDebugReader { bool initialized = false; bool died = false; bool is_64bit = false; - // The jit descriptor and dex descriptor can be read in one process_vm_readv() call. - uint64_t descriptors_addr = 0; - uint64_t descriptors_size = 0; - // offset relative to descriptors_addr - uint64_t jit_descriptor_offset = 0; - // offset relative to descriptors_addr - uint64_t dex_descriptor_offset = 0; + // remote addr of jit descriptor + uint64_t jit_descriptor_addr = 0; + // remote addr of dex descriptor + uint64_t dex_descriptor_addr = 0; // The state we know about the remote jit debug descriptor. Descriptor last_jit_descriptor; @@ -181,10 +178,9 @@ class JITDebugReader { // The location of descriptors in libart.so. struct DescriptorsLocation { - uint64_t relative_addr = 0; - uint64_t size = 0; - uint64_t jit_descriptor_offset = 0; - uint64_t dex_descriptor_offset = 0; + bool is_64bit = false; + uint64_t jit_descriptor_addr = 0; + uint64_t dex_descriptor_addr = 0; }; bool ReadProcess(Process& process, std::vector<JITDebugInfo>* debug_info); @@ -192,12 +188,14 @@ class JITDebugReader { std::vector<JITDebugInfo>* debug_info); bool IsDescriptorChanged(Process& process, Descriptor& old_descriptor); bool InitializeProcess(Process& process); - const DescriptorsLocation* GetDescriptorsLocation(const std::string& art_lib_path, bool is_64bit); + const DescriptorsLocation* GetDescriptorsLocation(const std::string& art_lib_path); bool ReadRemoteMem(Process& process, uint64_t remote_addr, uint64_t size, void* data); bool ReadDescriptors(Process& process, Descriptor* jit_descriptor, Descriptor* dex_descriptor); - bool LoadDescriptor(bool is_64bit, const char* data, Descriptor* descriptor); template <typename DescriptorT> - bool LoadDescriptorImpl(const char* data, Descriptor* descriptor); + bool ReadDescriptorsImpl(Process& process, Descriptor* jit_descriptor, + Descriptor* dex_descriptor); + template <typename DescriptorT> + bool ParseDescriptor(const DescriptorT& raw_descriptor, Descriptor* descriptor); bool ReadNewCodeEntries(Process& process, const Descriptor& descriptor, uint64_t last_action_timestamp, uint32_t read_entry_limit, @@ -226,7 +224,6 @@ class JITDebugReader { // All monitored processes std::unordered_map<pid_t, Process> processes_; std::unordered_map<std::string, DescriptorsLocation> descriptors_location_cache_; - std::vector<char> descriptors_buf_; std::priority_queue<JITDebugInfo, std::vector<JITDebugInfo>, std::greater<JITDebugInfo>> debug_info_q_; |