summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2022-03-24 21:25:51 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2022-03-24 21:25:51 +0000
commitd14f308fe65d808bf4eb4400b9ea3c0357b3b9aa (patch)
tree676d240bdcb30b87a871d3f4e3ca4b00ec14893e
parent1ea3d5fc2e8b91eb36dcb4a364265858ca00e4d6 (diff)
parente5defe1549a03dcd37860728789d990cf45e7405 (diff)
downloadextras-d14f308fe65d808bf4eb4400b9ea3c0357b3b9aa.tar.gz
Merge "simpleperf: read jit descriptor and dex descriptor separately."
-rw-r--r--simpleperf/JITDebugReader.cpp78
-rw-r--r--simpleperf/JITDebugReader.h27
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_;