diff options
author | Yabin Cui <yabinc@google.com> | 2019-11-05 14:31:17 -0800 |
---|---|---|
committer | Yabin Cui <yabinc@google.com> | 2019-11-05 14:59:12 -0800 |
commit | 95d8395bcaf09d7079fe0fbbf7514631990ae47d (patch) | |
tree | 57c82f9357e59db16081b4d883547cf5584f85cb | |
parent | a3ae53117165460a18b5ea7eaab8231b62c63025 (diff) | |
download | extras-95d8395bcaf09d7079fe0fbbf7514631990ae47d.tar.gz |
simpleperf: add temporary work around for debug interface change.
To fix a libunwindstack problem, ART appends new debug entries to the
end of the debug entry list, insteading prepending to it. This breaks
CtsSimpleperfTestCases.
This CL adds a temporary work around in simpleperf, so we have time
to try other fixes in ART.
Bug: 143375574
Test: run simpleperf_unit_test
Change-Id: I5d73792996fb89d22a664b982e667ba0a4ee8276
-rw-r--r-- | simpleperf/JITDebugReader.cpp | 45 | ||||
-rw-r--r-- | simpleperf/JITDebugReader.h | 4 |
2 files changed, 47 insertions, 2 deletions
diff --git a/simpleperf/JITDebugReader.cpp b/simpleperf/JITDebugReader.cpp index e48e2270..7ef3f25f 100644 --- a/simpleperf/JITDebugReader.cpp +++ b/simpleperf/JITDebugReader.cpp @@ -531,10 +531,10 @@ bool JITDebugReader::ReadNewCodeEntries(Process& process, const Descriptor& desc } if (descriptor.version == 2) { if (process.is_64bit) { - return ReadNewCodeEntriesImpl<JITCodeEntry64V2>( + return ReadNewCodeEntriesImplV2<JITCodeEntry64V2>( process, descriptor, last_action_timestamp, read_entry_limit, new_code_entries); } - return ReadNewCodeEntriesImpl<JITCodeEntry32V2>( + return ReadNewCodeEntriesImplV2<JITCodeEntry32V2>( process, descriptor, last_action_timestamp, read_entry_limit, new_code_entries); } return false; @@ -548,6 +548,7 @@ bool JITDebugReader::ReadNewCodeEntriesImpl(Process& process, const Descriptor& uint64_t current_entry_addr = descriptor.first_entry_addr; uint64_t prev_entry_addr = 0u; std::unordered_set<uint64_t> entry_addr_set; + for (size_t i = 0u; i < read_entry_limit && current_entry_addr != 0u; ++i) { if (entry_addr_set.find(current_entry_addr) != entry_addr_set.end()) { // We enter a loop, which means a broken linked list. @@ -581,6 +582,46 @@ bool JITDebugReader::ReadNewCodeEntriesImpl(Process& process, const Descriptor& return true; } +// Temporary work around for patch "JIT mini-debug-info: Append packed entries towards end.", which +// adds new entries at the end of the list and forces simpleperf to read the whole list. +template <typename CodeEntryT> +bool JITDebugReader::ReadNewCodeEntriesImplV2(Process& process, const Descriptor& descriptor, + uint64_t last_action_timestamp, + uint32_t /* read_entry_limit */, + std::vector<CodeEntry>* new_code_entries) { + uint64_t current_entry_addr = descriptor.first_entry_addr; + uint64_t prev_entry_addr = 0u; + std::unordered_set<uint64_t> entry_addr_set; + const size_t READ_ENTRY_LIMIT = 10000; // to avoid endless loop + + for (size_t i = 0u; i < READ_ENTRY_LIMIT && current_entry_addr != 0u; ++i) { + if (entry_addr_set.find(current_entry_addr) != entry_addr_set.end()) { + // We enter a loop, which means a broken linked list. + return false; + } + CodeEntryT entry; + if (!ReadRemoteMem(process, current_entry_addr, sizeof(entry), &entry)) { + return false; + } + if (entry.prev_addr != prev_entry_addr || !entry.Valid()) { + // A broken linked list + return false; + } + if (entry.symfile_size > 0 && entry.register_timestamp > last_action_timestamp) { + CodeEntry code_entry; + code_entry.addr = current_entry_addr; + code_entry.symfile_addr = entry.symfile_addr; + code_entry.symfile_size = entry.symfile_size; + code_entry.timestamp = entry.register_timestamp; + new_code_entries->push_back(code_entry); + } + entry_addr_set.insert(current_entry_addr); + prev_entry_addr = current_entry_addr; + current_entry_addr = entry.next_addr; + } + return true; +} + void JITDebugReader::ReadJITCodeDebugInfo(Process& process, const std::vector<CodeEntry>& jit_entries, std::vector<JITDebugInfo>* debug_info) { diff --git a/simpleperf/JITDebugReader.h b/simpleperf/JITDebugReader.h index 3be124e6..1a3b5e69 100644 --- a/simpleperf/JITDebugReader.h +++ b/simpleperf/JITDebugReader.h @@ -169,6 +169,10 @@ class JITDebugReader { bool ReadNewCodeEntriesImpl(Process& process, const Descriptor& descriptor, uint64_t last_action_timestamp, uint32_t read_entry_limit, std::vector<CodeEntry>* new_code_entries); + template <typename CodeEntryT> + bool ReadNewCodeEntriesImplV2(Process& process, const Descriptor& descriptor, + uint64_t last_action_timestamp, uint32_t read_entry_limit, + std::vector<CodeEntry>* new_code_entries); void ReadJITCodeDebugInfo(Process& process, const std::vector<CodeEntry>& jit_entries, std::vector<JITDebugInfo>* debug_info); |