• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "JITDebugReader.h"
18 
19 #include <inttypes.h>
20 #include <stdio.h>
21 #include <sys/mman.h>
22 #include <sys/uio.h>
23 #include <sys/user.h>
24 #include <unistd.h>
25 
26 #include <algorithm>
27 #include <unordered_map>
28 #include <unordered_set>
29 #include <vector>
30 
31 #include <android-base/file.h>
32 #include <android-base/logging.h>
33 #include <android-base/stringprintf.h>
34 #include <android-base/strings.h>
35 
36 #include "JITDebugReader_impl.h"
37 #include "dso.h"
38 #include "environment.h"
39 #include "read_apk.h"
40 #include "read_elf.h"
41 #include "utils.h"
42 
43 namespace simpleperf {
44 
45 using android::base::StartsWith;
46 using android::base::StringPrintf;
47 
48 // If the size of a symfile is larger than EXPECTED_MAX_SYMFILE_SIZE, we don't want to read it
49 // remotely.
50 static constexpr size_t MAX_JIT_SYMFILE_SIZE = 1024 * 1024u;
51 
52 // It takes about 30us-130us on Pixel (depending on the cpu frequency) to check if the descriptors
53 // have been updated (most time spent in process_vm_preadv). We want to know if the JIT debug info
54 // changed as soon as possible, while not wasting too much time checking for updates. So use a
55 // period of 100 ms.
56 // In system wide profiling, we may need to check JIT debug info changes for many processes, to
57 // avoid spending all time checking, wait 100 ms between any two checks.
58 static constexpr size_t kUpdateJITDebugInfoIntervalInMs = 100;
59 
60 // map name used for jit zygote cache
61 static const char* kJITZygoteCacheMmapPrefix = "/memfd:jit-zygote-cache";
62 
63 // Match the format of JITDescriptor in art/runtime/jit/debugger_interface.cc.
64 template <typename ADDRT>
65 struct JITDescriptor {
66   uint32_t version;
67   uint32_t action_flag;
68   ADDRT relevant_entry_addr;
69   ADDRT first_entry_addr;
70   uint8_t magic[8];
71   uint32_t flags;
72   uint32_t sizeof_descriptor;
73   uint32_t sizeof_entry;
74   uint32_t action_seqlock;    // incremented before and after any modification
75   uint64_t action_timestamp;  // CLOCK_MONOTONIC time of last action
76 
77   bool Valid() const;
78 
AndroidVersionsimpleperf::JITDescriptor79   int AndroidVersion() const { return magic[7] - '0'; }
80 };
81 
82 // Match the format of JITCodeEntry in art/runtime/jit/debugger_interface.cc
83 // with JITDescriptor.magic == "Android1".
84 template <typename ADDRT>
85 struct JITCodeEntry {
86   ADDRT next_addr;
87   ADDRT prev_addr;
88   ADDRT symfile_addr;
89   uint64_t symfile_size;
90   uint64_t register_timestamp;  // CLOCK_MONOTONIC time of entry registration
91 
Validsimpleperf::JITCodeEntry92   bool Valid() const { return symfile_addr > 0u && symfile_size > 0u; }
93 };
94 
95 // Match the format of JITCodeEntry in art/runtime/jit/debugger_interface.cc
96 // with JITDescriptor.magic == "Android1".
97 template <typename ADDRT>
98 struct __attribute__((packed)) PackedJITCodeEntry {
99   ADDRT next_addr;
100   ADDRT prev_addr;
101   ADDRT symfile_addr;
102   uint64_t symfile_size;
103   uint64_t register_timestamp;
104 
Validsimpleperf::PackedJITCodeEntry105   bool Valid() const { return symfile_addr > 0u && symfile_size > 0u; }
106 };
107 
108 // Match the format of JITCodeEntry in art/runtime/jit/debugger_interface.cc
109 // with JITDescriptor.magic == "Android2".
110 template <typename ADDRT>
111 struct JITCodeEntryV2 {
112   ADDRT next_addr;
113   ADDRT prev_addr;
114   ADDRT symfile_addr;
115   uint64_t symfile_size;
116   uint64_t register_timestamp;  // CLOCK_MONOTONIC time of entry registration
117   uint32_t seqlock;             // even value if valid
118 
Validsimpleperf::JITCodeEntryV2119   bool Valid() const { return (seqlock & 1) == 0; }
120 };
121 
122 // Match the format of JITCodeEntry in art/runtime/jit/debugger_interface.cc
123 // with JITDescriptor.magic == "Android2".
124 template <typename ADDRT>
125 struct __attribute__((packed)) PackedJITCodeEntryV2 {
126   ADDRT next_addr;
127   ADDRT prev_addr;
128   ADDRT symfile_addr;
129   uint64_t symfile_size;
130   uint64_t register_timestamp;
131   uint32_t seqlock;
132 
Validsimpleperf::PackedJITCodeEntryV2133   bool Valid() const { return (seqlock & 1) == 0; }
134 };
135 
136 // Match the format of JITCodeEntry in art/runtime/jit/debugger_interface.cc
137 // with JITDescriptor.magic == "Android2".
138 template <typename ADDRT>
139 struct __attribute__((packed)) PaddedJITCodeEntryV2 {
140   ADDRT next_addr;
141   ADDRT prev_addr;
142   ADDRT symfile_addr;
143   uint64_t symfile_size;
144   uint64_t register_timestamp;
145   uint32_t seqlock;
146   uint32_t pad;
147 
Validsimpleperf::PaddedJITCodeEntryV2148   bool Valid() const { return (seqlock & 1) == 0; }
149 };
150 
151 using JITDescriptor32 = JITDescriptor<uint32_t>;
152 using JITDescriptor64 = JITDescriptor<uint64_t>;
153 
154 #if defined(__x86_64__)
155 // Make sure simpleperf built for i386 and x86_64 see the correct JITCodeEntry layout of i386.
156 using JITCodeEntry32 = PackedJITCodeEntry<uint32_t>;
157 using JITCodeEntry32V2 = PackedJITCodeEntryV2<uint32_t>;
158 #else
159 using JITCodeEntry32 = JITCodeEntry<uint32_t>;
160 using JITCodeEntry32V2 = JITCodeEntryV2<uint32_t>;
161 #endif
162 
163 using JITCodeEntry64 = JITCodeEntry<uint64_t>;
164 #if defined(__i386__)
165 // Make sure simpleperf built for i386 and x86_64 see the correct JITCodeEntry layout of x86_64.
166 using JITCodeEntry64V2 = PaddedJITCodeEntryV2<uint64_t>;
167 #else
168 using JITCodeEntry64V2 = JITCodeEntryV2<uint64_t>;
169 #endif
170 
171 template <typename ADDRT>
Valid() const172 bool JITDescriptor<ADDRT>::Valid() const {
173   const char* magic_str = reinterpret_cast<const char*>(magic);
174   if (version != 1 ||
175       !(strncmp(magic_str, "Android1", 8) == 0 || strncmp(magic_str, "Android2", 8) == 0)) {
176     return false;
177   }
178   if (sizeof(*this) != sizeof_descriptor) {
179     return false;
180   }
181   if (sizeof(ADDRT) == 4) {
182     return sizeof_entry == (AndroidVersion() == 1) ? sizeof(JITCodeEntry32)
183                                                    : sizeof(JITCodeEntry32V2);
184   }
185   return sizeof_entry == (AndroidVersion() == 1) ? sizeof(JITCodeEntry64)
186                                                  : sizeof(JITCodeEntry64V2);
187 }
188 
189 // We want to support both 64-bit and 32-bit simpleperf when profiling either 64-bit or 32-bit
190 // apps. So using static_asserts to make sure that simpleperf on arm and aarch64 having the same
191 // view of structures, and simpleperf on i386 and x86_64 having the same view of structures.
192 static_assert(sizeof(JITDescriptor32) == 48, "");
193 static_assert(sizeof(JITDescriptor64) == 56, "");
194 
195 #if defined(__i386__) or defined(__x86_64__)
196 static_assert(sizeof(JITCodeEntry32) == 28, "");
197 static_assert(sizeof(JITCodeEntry32V2) == 32, "");
198 static_assert(sizeof(JITCodeEntry64) == 40, "");
199 static_assert(sizeof(JITCodeEntry64V2) == 48, "");
200 #else
201 static_assert(sizeof(JITCodeEntry32) == 32, "");
202 static_assert(sizeof(JITCodeEntry32V2) == 40, "");
203 static_assert(sizeof(JITCodeEntry64) == 40, "");
204 static_assert(sizeof(JITCodeEntry64V2) == 48, "");
205 #endif
206 
JITDebugReader(const std::string & symfile_prefix,SymFileOption symfile_option,SyncOption sync_option)207 JITDebugReader::JITDebugReader(const std::string& symfile_prefix, SymFileOption symfile_option,
208                                SyncOption sync_option)
209     : symfile_prefix_(symfile_prefix), symfile_option_(symfile_option), sync_option_(sync_option) {}
210 
~JITDebugReader()211 JITDebugReader::~JITDebugReader() {}
212 
RegisterDebugInfoCallback(IOEventLoop * loop,const debug_info_callback_t & callback)213 bool JITDebugReader::RegisterDebugInfoCallback(IOEventLoop* loop,
214                                                const debug_info_callback_t& callback) {
215   debug_info_callback_ = callback;
216   read_event_ = loop->AddPeriodicEvent(SecondToTimeval(kUpdateJITDebugInfoIntervalInMs / 1000.0),
217                                        [this]() { return ReadAllProcesses(); });
218   return (read_event_ != nullptr && IOEventLoop::DisableEvent(read_event_));
219 }
220 
MonitorProcess(pid_t pid)221 bool JITDebugReader::MonitorProcess(pid_t pid) {
222   if (processes_.find(pid) == processes_.end()) {
223     processes_[pid].pid = pid;
224     LOG(DEBUG) << "Start monitoring process " << pid;
225     if (processes_.size() == 1u) {
226       if (!IOEventLoop::EnableEvent(read_event_)) {
227         return false;
228       }
229     }
230   }
231   return true;
232 }
233 
IsArtLib(const std::string & filename)234 static bool IsArtLib(const std::string& filename) {
235   return android::base::EndsWith(filename, "libart.so") ||
236          android::base::EndsWith(filename, "libartd.so");
237 }
238 
UpdateRecord(const Record * record)239 bool JITDebugReader::UpdateRecord(const Record* record) {
240   if (record->type() == PERF_RECORD_MMAP) {
241     auto r = static_cast<const MmapRecord*>(record);
242     if (IsArtLib(r->filename)) {
243       pids_with_art_lib_.emplace(r->data->pid, false);
244     }
245   } else if (record->type() == PERF_RECORD_MMAP2) {
246     auto r = static_cast<const Mmap2Record*>(record);
247     if (IsArtLib(r->filename)) {
248       pids_with_art_lib_.emplace(r->data->pid, false);
249     }
250   } else if (record->type() == PERF_RECORD_FORK) {
251     auto r = static_cast<const ForkRecord*>(record);
252     if (r->data->pid != r->data->ppid &&
253         pids_with_art_lib_.find(r->data->ppid) != pids_with_art_lib_.end()) {
254       pids_with_art_lib_.emplace(r->data->pid, false);
255     }
256   } else if (record->type() == PERF_RECORD_SAMPLE) {
257     auto r = static_cast<const SampleRecord*>(record);
258     auto it = pids_with_art_lib_.find(r->tid_data.pid);
259     if (it != pids_with_art_lib_.end() && !it->second) {
260       it->second = true;
261       if (!MonitorProcess(r->tid_data.pid)) {
262         return false;
263       }
264       return ReadProcess(r->tid_data.pid);
265     }
266   }
267   return FlushDebugInfo(record->Timestamp());
268 }
269 
FlushDebugInfo(uint64_t timestamp)270 bool JITDebugReader::FlushDebugInfo(uint64_t timestamp) {
271   if (sync_option_ == SyncOption::kSyncWithRecords) {
272     if (!debug_info_q_.empty() && debug_info_q_.top().timestamp < timestamp) {
273       std::vector<JITDebugInfo> debug_info;
274       while (!debug_info_q_.empty() && debug_info_q_.top().timestamp < timestamp) {
275         debug_info.emplace_back(debug_info_q_.top());
276         debug_info_q_.pop();
277       }
278       return debug_info_callback_(debug_info, false);
279     }
280   }
281   return true;
282 }
283 
ReadAllProcesses()284 bool JITDebugReader::ReadAllProcesses() {
285   if (!IOEventLoop::DisableEvent(read_event_)) {
286     return false;
287   }
288   std::vector<JITDebugInfo> debug_info;
289   for (auto it = processes_.begin(); it != processes_.end();) {
290     Process& process = it->second;
291     if (!ReadProcess(process, &debug_info)) {
292       return false;
293     }
294     if (process.died) {
295       LOG(DEBUG) << "Stop monitoring process " << process.pid;
296       it = processes_.erase(it);
297     } else {
298       ++it;
299     }
300   }
301   if (!AddDebugInfo(debug_info, true)) {
302     return false;
303   }
304   if (!processes_.empty()) {
305     return IOEventLoop::EnableEvent(read_event_);
306   }
307   return true;
308 }
309 
ReadProcess(pid_t pid)310 bool JITDebugReader::ReadProcess(pid_t pid) {
311   auto it = processes_.find(pid);
312   if (it != processes_.end()) {
313     std::vector<JITDebugInfo> debug_info;
314     return ReadProcess(it->second, &debug_info) && AddDebugInfo(debug_info, false);
315   }
316   return true;
317 }
318 
ReadProcess(Process & process,std::vector<JITDebugInfo> * debug_info)319 bool JITDebugReader::ReadProcess(Process& process, std::vector<JITDebugInfo>* debug_info) {
320   if (process.died || (!process.initialized && !InitializeProcess(process))) {
321     return true;
322   }
323   // 1. Read descriptors.
324   Descriptor jit_descriptor;
325   Descriptor dex_descriptor;
326   if (!ReadDescriptors(process, &jit_descriptor, &dex_descriptor)) {
327     return true;
328   }
329   // 2. Return if descriptors are not changed.
330   if (jit_descriptor.action_seqlock == process.last_jit_descriptor.action_seqlock &&
331       dex_descriptor.action_seqlock == process.last_dex_descriptor.action_seqlock) {
332     return true;
333   }
334 
335   // 3. Read new symfiles.
336   return ReadDebugInfo(process, jit_descriptor, debug_info) &&
337          ReadDebugInfo(process, dex_descriptor, debug_info);
338 }
339 
ReadDebugInfo(Process & process,Descriptor & new_descriptor,std::vector<JITDebugInfo> * debug_info)340 bool JITDebugReader::ReadDebugInfo(Process& process, Descriptor& new_descriptor,
341                                    std::vector<JITDebugInfo>* debug_info) {
342   DescriptorType type = new_descriptor.type;
343   Descriptor* old_descriptor =
344       (type == DescriptorType::kJIT) ? &process.last_jit_descriptor : &process.last_dex_descriptor;
345 
346   bool has_update = new_descriptor.action_seqlock != old_descriptor->action_seqlock &&
347                     (new_descriptor.action_seqlock & 1) == 0;
348   LOG(DEBUG) << (type == DescriptorType::kJIT ? "JIT" : "Dex") << " symfiles of pid " << process.pid
349              << ": old seqlock " << old_descriptor->action_seqlock << ", new seqlock "
350              << new_descriptor.action_seqlock;
351   if (!has_update) {
352     return true;
353   }
354   std::vector<CodeEntry> new_entries;
355   // Adding or removing one code entry will make two increments of action_seqlock. So we should
356   // not read more than (seqlock_diff / 2) new entries.
357   uint32_t read_entry_limit = (new_descriptor.action_seqlock - old_descriptor->action_seqlock) / 2;
358   if (!ReadNewCodeEntries(process, new_descriptor, old_descriptor->action_timestamp,
359                           read_entry_limit, &new_entries)) {
360     return true;
361   }
362   // If the descriptor was changed while we were reading new entries, skip reading debug info this
363   // time.
364   if (IsDescriptorChanged(process, new_descriptor)) {
365     return true;
366   }
367   LOG(DEBUG) << (type == DescriptorType::kJIT ? "JIT" : "Dex") << " symfiles of pid " << process.pid
368              << ": read " << new_entries.size() << " new entries";
369 
370   if (!new_entries.empty()) {
371     if (type == DescriptorType::kJIT) {
372       if (!ReadJITCodeDebugInfo(process, new_entries, debug_info)) {
373         return false;
374       }
375     } else {
376       ReadDexFileDebugInfo(process, new_entries, debug_info);
377     }
378   }
379   *old_descriptor = new_descriptor;
380   return true;
381 }
382 
IsDescriptorChanged(Process & process,Descriptor & prev_descriptor)383 bool JITDebugReader::IsDescriptorChanged(Process& process, Descriptor& prev_descriptor) {
384   Descriptor tmp_jit_descriptor;
385   Descriptor tmp_dex_descriptor;
386   if (!ReadDescriptors(process, &tmp_jit_descriptor, &tmp_dex_descriptor)) {
387     return true;
388   }
389   if (prev_descriptor.type == DescriptorType::kJIT) {
390     return prev_descriptor.action_seqlock != tmp_jit_descriptor.action_seqlock;
391   }
392   return prev_descriptor.action_seqlock != tmp_dex_descriptor.action_seqlock;
393 }
394 
InitializeProcess(Process & process)395 bool JITDebugReader::InitializeProcess(Process& process) {
396   // 1. Read map file to find the location of libart.so.
397   std::vector<ThreadMmap> thread_mmaps;
398   if (!GetThreadMmapsInProcess(process.pid, &thread_mmaps)) {
399     process.died = true;
400     return false;
401   }
402   std::string art_lib_path;
403   uint64_t min_vaddr_in_memory;
404   for (auto& map : thread_mmaps) {
405     if ((map.prot & PROT_EXEC) && IsArtLib(map.name)) {
406       art_lib_path = map.name;
407       min_vaddr_in_memory = map.start_addr;
408       break;
409     }
410   }
411   if (art_lib_path.empty()) {
412     return false;
413   }
414 
415   // 2. Read libart.so to find the addresses of __jit_debug_descriptor and __dex_debug_descriptor.
416   const DescriptorsLocation* location = GetDescriptorsLocation(art_lib_path);
417   if (location == nullptr) {
418     return false;
419   }
420   process.is_64bit = location->is_64bit;
421   process.jit_descriptor_addr = location->jit_descriptor_addr + min_vaddr_in_memory;
422   process.dex_descriptor_addr = location->dex_descriptor_addr + min_vaddr_in_memory;
423 
424   for (auto& map : thread_mmaps) {
425     if (StartsWith(map.name, kJITZygoteCacheMmapPrefix)) {
426       process.jit_zygote_cache_ranges_.emplace_back(map.start_addr, map.start_addr + map.len);
427     }
428   }
429 
430   process.initialized = true;
431   return true;
432 }
433 
GetDescriptorsLocation(const std::string & art_lib_path)434 const JITDebugReader::DescriptorsLocation* JITDebugReader::GetDescriptorsLocation(
435     const std::string& art_lib_path) {
436   auto it = descriptors_location_cache_.find(art_lib_path);
437   if (it != descriptors_location_cache_.end()) {
438     return it->second.jit_descriptor_addr == 0u ? nullptr : &it->second;
439   }
440   DescriptorsLocation& location = descriptors_location_cache_[art_lib_path];
441 
442   // Read libart.so to find the addresses of __jit_debug_descriptor and __dex_debug_descriptor.
443   ElfStatus status;
444   auto elf = ElfFile::Open(art_lib_path, &status);
445   if (!elf) {
446     LOG(ERROR) << "failed to read min_exec_vaddr from " << art_lib_path << ": " << status;
447     return nullptr;
448   }
449   uint64_t file_offset;
450   uint64_t min_vaddr_in_file = elf->ReadMinExecutableVaddr(&file_offset);
451   // min_vaddr_in_file is the min vaddr of executable segments. It may not be page aligned.
452   // And dynamic linker will create map mapping to (segment.p_vaddr & PAGE_MASK).
453   uint64_t aligned_segment_vaddr = min_vaddr_in_file & PAGE_MASK;
454   const char* jit_str = "__jit_debug_descriptor";
455   const char* dex_str = "__dex_debug_descriptor";
456   uint64_t jit_addr = 0u;
457   uint64_t dex_addr = 0u;
458 
459   auto callback = [&](const ElfFileSymbol& symbol) {
460     if (symbol.name == jit_str) {
461       jit_addr = symbol.vaddr - aligned_segment_vaddr;
462     } else if (symbol.name == dex_str) {
463       dex_addr = symbol.vaddr - aligned_segment_vaddr;
464     }
465   };
466   elf->ParseDynamicSymbols(callback);
467   if (jit_addr == 0u || dex_addr == 0u) {
468     return nullptr;
469   }
470   location.is_64bit = elf->Is64Bit();
471   location.jit_descriptor_addr = jit_addr;
472   location.dex_descriptor_addr = dex_addr;
473   return &location;
474 }
475 
ReadRemoteMem(Process & process,uint64_t remote_addr,uint64_t size,void * data)476 bool JITDebugReader::ReadRemoteMem(Process& process, uint64_t remote_addr, uint64_t size,
477                                    void* data) {
478   iovec local_iov;
479   local_iov.iov_base = data;
480   local_iov.iov_len = size;
481   iovec remote_iov;
482   remote_iov.iov_base = reinterpret_cast<void*>(static_cast<uintptr_t>(remote_addr));
483   remote_iov.iov_len = size;
484   ssize_t result = process_vm_readv(process.pid, &local_iov, 1, &remote_iov, 1, 0);
485   if (static_cast<size_t>(result) != size) {
486     PLOG(DEBUG) << "ReadRemoteMem("
487                 << " pid " << process.pid << ", addr " << std::hex << remote_addr << ", size "
488                 << size << ") failed";
489     process.died = true;
490     return false;
491   }
492   return true;
493 }
494 
ReadDescriptors(Process & process,Descriptor * jit_descriptor,Descriptor * dex_descriptor)495 bool JITDebugReader::ReadDescriptors(Process& process, Descriptor* jit_descriptor,
496                                      Descriptor* dex_descriptor) {
497   if (process.is_64bit) {
498     return ReadDescriptorsImpl<JITDescriptor64>(process, jit_descriptor, dex_descriptor);
499   }
500   return ReadDescriptorsImpl<JITDescriptor32>(process, jit_descriptor, dex_descriptor);
501 }
502 
503 template <typename DescriptorT>
ReadDescriptorsImpl(Process & process,Descriptor * jit_descriptor,Descriptor * dex_descriptor)504 bool JITDebugReader::ReadDescriptorsImpl(Process& process, Descriptor* jit_descriptor,
505                                          Descriptor* dex_descriptor) {
506   DescriptorT raw_jit_descriptor;
507   DescriptorT raw_dex_descriptor;
508   iovec local_iovs[2];
509   local_iovs[0].iov_base = &raw_jit_descriptor;
510   local_iovs[0].iov_len = sizeof(DescriptorT);
511   local_iovs[1].iov_base = &raw_dex_descriptor;
512   local_iovs[1].iov_len = sizeof(DescriptorT);
513   iovec remote_iovs[2];
514   remote_iovs[0].iov_base =
515       reinterpret_cast<void*>(static_cast<uintptr_t>(process.jit_descriptor_addr));
516   remote_iovs[0].iov_len = sizeof(DescriptorT);
517   remote_iovs[1].iov_base =
518       reinterpret_cast<void*>(static_cast<uintptr_t>(process.dex_descriptor_addr));
519   remote_iovs[1].iov_len = sizeof(DescriptorT);
520   ssize_t result = process_vm_readv(process.pid, local_iovs, 2, remote_iovs, 2, 0);
521   if (static_cast<size_t>(result) != sizeof(DescriptorT) * 2) {
522     PLOG(DEBUG) << "ReadDescriptor(pid " << process.pid << ", jit_addr " << std::hex
523                 << process.jit_descriptor_addr << ", dex_addr " << process.dex_descriptor_addr
524                 << ") failed";
525     process.died = true;
526     return false;
527   }
528 
529   if (!ParseDescriptor(raw_jit_descriptor, jit_descriptor) ||
530       !ParseDescriptor(raw_dex_descriptor, dex_descriptor)) {
531     return false;
532   }
533   jit_descriptor->type = DescriptorType::kJIT;
534   dex_descriptor->type = DescriptorType::kDEX;
535   return true;
536 }
537 
538 template <typename DescriptorT>
ParseDescriptor(const DescriptorT & raw_descriptor,Descriptor * descriptor)539 bool JITDebugReader::ParseDescriptor(const DescriptorT& raw_descriptor, Descriptor* descriptor) {
540   if (!raw_descriptor.Valid()) {
541     return false;
542   }
543   descriptor->action_seqlock = raw_descriptor.action_seqlock;
544   descriptor->action_timestamp = raw_descriptor.action_timestamp;
545   descriptor->first_entry_addr = raw_descriptor.first_entry_addr;
546   descriptor->version = raw_descriptor.AndroidVersion();
547   return true;
548 }
549 
550 // Read new code entries with timestamp > last_action_timestamp.
551 // Since we don't stop the app process while reading code entries, it is possible we are reading
552 // broken data. So return false once we detect that the data is broken.
ReadNewCodeEntries(Process & process,const Descriptor & descriptor,uint64_t last_action_timestamp,uint32_t read_entry_limit,std::vector<CodeEntry> * new_code_entries)553 bool JITDebugReader::ReadNewCodeEntries(Process& process, const Descriptor& descriptor,
554                                         uint64_t last_action_timestamp, uint32_t read_entry_limit,
555                                         std::vector<CodeEntry>* new_code_entries) {
556   if (descriptor.version == 1) {
557     if (process.is_64bit) {
558       return ReadNewCodeEntriesImpl<JITCodeEntry64>(process, descriptor, last_action_timestamp,
559                                                     read_entry_limit, new_code_entries);
560     }
561     return ReadNewCodeEntriesImpl<JITCodeEntry32>(process, descriptor, last_action_timestamp,
562                                                   read_entry_limit, new_code_entries);
563   }
564   if (descriptor.version == 2) {
565     if (process.is_64bit) {
566       return ReadNewCodeEntriesImpl<JITCodeEntry64V2>(process, descriptor, last_action_timestamp,
567                                                       read_entry_limit, new_code_entries);
568     }
569     return ReadNewCodeEntriesImpl<JITCodeEntry32V2>(process, descriptor, last_action_timestamp,
570                                                     read_entry_limit, new_code_entries);
571   }
572   return false;
573 }
574 
575 template <typename CodeEntryT>
ReadNewCodeEntriesImpl(Process & process,const Descriptor & descriptor,uint64_t last_action_timestamp,uint32_t read_entry_limit,std::vector<CodeEntry> * new_code_entries)576 bool JITDebugReader::ReadNewCodeEntriesImpl(Process& process, const Descriptor& descriptor,
577                                             uint64_t last_action_timestamp,
578                                             uint32_t read_entry_limit,
579                                             std::vector<CodeEntry>* new_code_entries) {
580   uint64_t current_entry_addr = descriptor.first_entry_addr;
581   uint64_t prev_entry_addr = 0u;
582   std::unordered_set<uint64_t> entry_addr_set;
583   for (size_t i = 0u; i < read_entry_limit && current_entry_addr != 0u; ++i) {
584     if (entry_addr_set.find(current_entry_addr) != entry_addr_set.end()) {
585       // We enter a loop, which means a broken linked list.
586       return false;
587     }
588     CodeEntryT entry;
589     if (!ReadRemoteMem(process, current_entry_addr, sizeof(entry), &entry)) {
590       return false;
591     }
592     if (entry.prev_addr != prev_entry_addr || !entry.Valid()) {
593       // A broken linked list
594       return false;
595     }
596     if (entry.register_timestamp <= last_action_timestamp) {
597       // The linked list has entries with timestamp in decreasing order. So stop searching
598       // once we hit an entry with timestamp <= last_action_timestmap.
599       break;
600     }
601     if (entry.symfile_size > 0) {
602       CodeEntry code_entry;
603       code_entry.addr = current_entry_addr;
604       code_entry.symfile_addr = entry.symfile_addr;
605       code_entry.symfile_size = entry.symfile_size;
606       code_entry.timestamp = entry.register_timestamp;
607       new_code_entries->push_back(code_entry);
608     }
609     entry_addr_set.insert(current_entry_addr);
610     prev_entry_addr = current_entry_addr;
611     current_entry_addr = entry.next_addr;
612   }
613   return true;
614 }
615 
ReadJITCodeDebugInfo(Process & process,const std::vector<CodeEntry> & jit_entries,std::vector<JITDebugInfo> * debug_info)616 bool JITDebugReader::ReadJITCodeDebugInfo(Process& process,
617                                           const std::vector<CodeEntry>& jit_entries,
618                                           std::vector<JITDebugInfo>* debug_info) {
619   std::vector<char> data;
620 
621   for (auto& jit_entry : jit_entries) {
622     if (jit_entry.symfile_size > MAX_JIT_SYMFILE_SIZE) {
623       continue;
624     }
625     if (data.size() < jit_entry.symfile_size) {
626       data.resize(jit_entry.symfile_size);
627     }
628     if (!ReadRemoteMem(process, jit_entry.symfile_addr, jit_entry.symfile_size, data.data())) {
629       continue;
630     }
631     if (!IsValidElfFileMagic(data.data(), jit_entry.symfile_size)) {
632       continue;
633     }
634     TempSymFile* symfile = GetTempSymFile(process, jit_entry);
635     if (symfile == nullptr) {
636       return false;
637     }
638     uint64_t file_offset = symfile->GetOffset();
639     if (!symfile->WriteEntry(data.data(), jit_entry.symfile_size)) {
640       return false;
641     }
642 
643     auto callback = [&](const ElfFileSymbol& symbol) {
644       if (symbol.len == 0) {  // Some arm labels can have zero length.
645         return;
646       }
647       // Pass out the location of the symfile for unwinding and symbolization.
648       std::string location_in_file =
649           StringPrintf(":%" PRIu64 "-%" PRIu64, file_offset, file_offset + jit_entry.symfile_size);
650       debug_info->emplace_back(process.pid, jit_entry.timestamp, symbol.vaddr, symbol.len,
651                                symfile->GetPath() + location_in_file, file_offset);
652 
653       LOG(VERBOSE) << "JITSymbol " << symbol.name << " at [" << std::hex << symbol.vaddr << " - "
654                    << (symbol.vaddr + symbol.len) << " with size " << symbol.len << " in "
655                    << symfile->GetPath() << location_in_file;
656     };
657     ElfStatus status;
658     auto elf = ElfFile::Open(data.data(), jit_entry.symfile_size, &status);
659     if (elf) {
660       elf->ParseSymbols(callback);
661     }
662   }
663 
664   if (app_symfile_) {
665     app_symfile_->Flush();
666   }
667   if (zygote_symfile_) {
668     zygote_symfile_->Flush();
669   }
670   return true;
671 }
672 
GetTempSymFile(Process & process,const CodeEntry & jit_entry)673 TempSymFile* JITDebugReader::GetTempSymFile(Process& process, const CodeEntry& jit_entry) {
674   bool is_zygote = false;
675   for (const auto& range : process.jit_zygote_cache_ranges_) {
676     if (jit_entry.symfile_addr >= range.first && jit_entry.symfile_addr < range.second) {
677       is_zygote = true;
678       break;
679     }
680   }
681   if (is_zygote) {
682     if (!zygote_symfile_) {
683       std::string path = symfile_prefix_ + "_" + kJITZygoteCacheFile;
684       zygote_symfile_ =
685           TempSymFile::Create(std::move(path), symfile_option_ == SymFileOption::kDropSymFiles);
686     }
687     return zygote_symfile_.get();
688   }
689   if (!app_symfile_) {
690     std::string path = symfile_prefix_ + "_" + kJITAppCacheFile;
691     app_symfile_ =
692         TempSymFile::Create(std::move(path), symfile_option_ == SymFileOption::kDropSymFiles);
693   }
694   return app_symfile_.get();
695 }
696 
ReadDexFileDebugInfo(Process & process,const std::vector<CodeEntry> & dex_entries,std::vector<JITDebugInfo> * debug_info)697 void JITDebugReader::ReadDexFileDebugInfo(Process& process,
698                                           const std::vector<CodeEntry>& dex_entries,
699                                           std::vector<JITDebugInfo>* debug_info) {
700   std::vector<ThreadMmap> thread_mmaps;
701   if (!GetThreadMmapsInProcess(process.pid, &thread_mmaps)) {
702     process.died = true;
703     return;
704   }
705   auto comp = [](const ThreadMmap& map, uint64_t addr) { return map.start_addr <= addr; };
706   for (auto& dex_entry : dex_entries) {
707     auto it =
708         std::lower_bound(thread_mmaps.begin(), thread_mmaps.end(), dex_entry.symfile_addr, comp);
709     if (it == thread_mmaps.begin()) {
710       continue;
711     }
712     --it;
713     if (it->start_addr + it->len < dex_entry.symfile_addr + dex_entry.symfile_size) {
714       continue;
715     }
716     std::string file_path;
717     std::string zip_path;
718     std::string entry_path;
719     std::shared_ptr<ThreadMmap> extracted_dex_file_map;
720     if (ParseExtractedInMemoryPath(it->name, &zip_path, &entry_path)) {
721       file_path = GetUrlInApk(zip_path, entry_path);
722       extracted_dex_file_map = std::make_shared<ThreadMmap>(*it);
723     } else {
724       if (!IsRegularFile(it->name)) {
725         // TODO: read dex file only exist in memory?
726         continue;
727       }
728       file_path = it->name;
729     }
730     // Offset of dex file in .vdex file or .apk file.
731     uint64_t dex_file_offset = dex_entry.symfile_addr - it->start_addr + it->pgoff;
732     debug_info->emplace_back(process.pid, dex_entry.timestamp, dex_file_offset, file_path,
733                              extracted_dex_file_map);
734     LOG(VERBOSE) << "DexFile " << file_path << "+" << std::hex << dex_file_offset << " in map ["
735                  << it->start_addr << " - " << (it->start_addr + it->len) << "] with size "
736                  << dex_entry.symfile_size;
737   }
738 }
739 
AddDebugInfo(const std::vector<JITDebugInfo> & debug_info,bool sync_kernel_records)740 bool JITDebugReader::AddDebugInfo(const std::vector<JITDebugInfo>& debug_info,
741                                   bool sync_kernel_records) {
742   if (!debug_info.empty()) {
743     if (sync_option_ == SyncOption::kSyncWithRecords) {
744       for (auto& info : debug_info) {
745         debug_info_q_.push(std::move(info));
746       }
747     } else {
748       return debug_info_callback_(debug_info, sync_kernel_records);
749     }
750   }
751   return true;
752 }
753 
754 }  // namespace simpleperf
755