OSDN Git Service

simpleperf: create one map for each jit symbol.
authorYabin Cui <yabinc@google.com>
Mon, 7 Oct 2019 22:57:56 +0000 (15:57 -0700)
committerYabin Cui <yabinc@google.com>
Mon, 7 Oct 2019 23:18:07 +0000 (16:18 -0700)
JIT debug interface in ART regularly repacks jit symbols, making
overlapped jit symfile maps:
For example, jit symfile A contains many symbols, in addr range [0xa000, 0xb000),
but excluding [0xa100, 0xa110]. And jit symfile B contains only one symbol, in
addr range [0xa100, 0xa108).
So jit symfile A and B have overlapped addr range, while the symbols in
them are all valid.

Simpleperf can't keep maps with overlapped addr range, thus fails to unwind in
this situation.
Fix it by creating one map for each jit symbol instead of jit symfile.

Bug: none
Test: run simpleperf_unit_test.
Test: run test.py TestRecordingRealApps.test_recording_displaybitmaps.
Change-Id: I8392bb331c98830dc9a98031a08c0567dd66ff4b

simpleperf/JITDebugReader.cpp

index c4406c9..8c5386d 100644 (file)
@@ -499,18 +499,6 @@ void JITDebugReader::ReadJITCodeDebugInfo(Process& process,
     if (!IsValidElfFileMagic(data.data(), jit_entry.symfile_size)) {
       continue;
     }
-    uint64_t min_addr = UINT64_MAX;
-    uint64_t max_addr = 0;
-    auto callback = [&](const ElfFileSymbol& symbol) {
-      min_addr = std::min(min_addr, symbol.vaddr);
-      max_addr = std::max(max_addr, symbol.vaddr + symbol.len);
-      LOG(VERBOSE) << "JITSymbol " << symbol.name << " at [" << std::hex << symbol.vaddr
-                   << " - " << (symbol.vaddr + symbol.len) << " with size " << symbol.len;
-    };
-    if (ParseSymbolsFromElfFileInMemory(data.data(), jit_entry.symfile_size, callback) !=
-        ElfStatus::NO_ERROR || min_addr >= max_addr) {
-      continue;
-    }
     std::unique_ptr<TemporaryFile> tmp_file = ScopedTempFiles::CreateTempFile(!keep_symfiles_);
     if (tmp_file == nullptr || !android::base::WriteFully(tmp_file->fd, data.data(),
                                                           jit_entry.symfile_size)) {
@@ -519,8 +507,13 @@ void JITDebugReader::ReadJITCodeDebugInfo(Process& process,
     if (keep_symfiles_) {
       tmp_file->DoNotRemove();
     }
-    debug_info->emplace_back(process.pid, jit_entry.timestamp, min_addr, max_addr - min_addr,
-                             tmp_file->path);
+    auto callback = [&](const ElfFileSymbol& symbol) {
+      LOG(VERBOSE) << "JITSymbol " << symbol.name << " at [" << std::hex << symbol.vaddr
+                   << " - " << (symbol.vaddr + symbol.len) << " with size " << symbol.len;
+      debug_info->emplace_back(process.pid, jit_entry.timestamp, symbol.vaddr, symbol.len,
+                               tmp_file->path);
+    };
+    ParseSymbolsFromElfFileInMemory(data.data(), jit_entry.symfile_size, callback);
   }
 }