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