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