• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 #define _GNU_SOURCE 1
18 #include <elf.h>
19 #include <inttypes.h>
20 #include <stdint.h>
21 #include <string.h>
22 #include <sys/mman.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 
26 #include <algorithm>
27 #include <memory>
28 
29 #include <android-base/file.h>
30 #include <android-base/stringprintf.h>
31 
32 #include <unwindstack/DexFiles.h>
33 #include <unwindstack/Elf.h>
34 #include <unwindstack/JitDebug.h>
35 #include <unwindstack/MapInfo.h>
36 #include <unwindstack/Maps.h>
37 #include <unwindstack/Memory.h>
38 #include <unwindstack/Unwinder.h>
39 
40 #include "Check.h"
41 
42 // Use the demangler from libc++.
43 extern "C" char* __cxa_demangle(const char*, char*, size_t*, int* status);
44 
45 namespace unwindstack {
46 
47 // Inject extra 'virtual' frame that represents the dex pc data.
48 // The dex pc is a magic register defined in the Mterp interpreter,
49 // and thus it will be restored/observed in the frame after it.
50 // Adding the dex frame first here will create something like:
51 //   #7 pc 0015fa20 core.vdex   java.util.Arrays.binarySearch+8
52 //   #8 pc 006b1ba1 libartd.so  ExecuteMterpImpl+14625
53 //   #9 pc 0039a1ef libartd.so  art::interpreter::Execute+719
FillInDexFrame()54 void Unwinder::FillInDexFrame() {
55   size_t frame_num = frames_.size();
56   frames_.resize(frame_num + 1);
57   FrameData* frame = &frames_.at(frame_num);
58   frame->num = frame_num;
59 
60   uint64_t dex_pc = regs_->dex_pc();
61   frame->pc = dex_pc;
62   frame->sp = regs_->sp();
63 
64   frame->map_info = maps_->Find(dex_pc);
65   if (frame->map_info != nullptr) {
66     frame->rel_pc = dex_pc - frame->map_info->start();
67     // Initialize the load bias for this map so subsequent calls
68     // to GetLoadBias() will always return data.
69     frame->map_info->set_load_bias(0);
70   } else {
71     frame->rel_pc = dex_pc;
72     warnings_ |= WARNING_DEX_PC_NOT_IN_MAP;
73     return;
74   }
75 
76   if (!resolve_names_) {
77     return;
78   }
79 
80 #if defined(DEXFILE_SUPPORT)
81   if (dex_files_ == nullptr) {
82     return;
83   }
84 
85   dex_files_->GetFunctionName(maps_, dex_pc, &frame->function_name, &frame->function_offset);
86 #endif
87 }
88 
FillInFrame(std::shared_ptr<MapInfo> & map_info,Elf *,uint64_t rel_pc,uint64_t pc_adjustment)89 FrameData* Unwinder::FillInFrame(std::shared_ptr<MapInfo>& map_info, Elf* /*elf*/, uint64_t rel_pc,
90                                  uint64_t pc_adjustment) {
91   size_t frame_num = frames_.size();
92   frames_.resize(frame_num + 1);
93   FrameData* frame = &frames_.at(frame_num);
94   frame->num = frame_num;
95   frame->sp = regs_->sp();
96   frame->rel_pc = rel_pc - pc_adjustment;
97   frame->pc = regs_->pc() - pc_adjustment;
98 
99   if (map_info == nullptr) {
100     // Nothing else to update.
101     return nullptr;
102   }
103 
104   frame->map_info = map_info;
105 
106   return frame;
107 }
108 
ShouldStop(const std::vector<std::string> * map_suffixes_to_ignore,const std::string & map_name)109 static bool ShouldStop(const std::vector<std::string>* map_suffixes_to_ignore,
110                        const std::string& map_name) {
111   if (map_suffixes_to_ignore == nullptr) {
112     return false;
113   }
114   auto pos = map_name.find_last_of('.');
115   if (pos == std::string::npos) {
116     return false;
117   }
118 
119   return std::find(map_suffixes_to_ignore->begin(), map_suffixes_to_ignore->end(),
120                    map_name.substr(pos + 1)) != map_suffixes_to_ignore->end();
121 }
122 
Unwind(const std::vector<std::string> * initial_map_names_to_skip,const std::vector<std::string> * map_suffixes_to_ignore)123 void Unwinder::Unwind(const std::vector<std::string>* initial_map_names_to_skip,
124                       const std::vector<std::string>* map_suffixes_to_ignore) {
125   CHECK(arch_ != ARCH_UNKNOWN);
126   ClearErrors();
127 
128   frames_.clear();
129 
130   // Clear any cached data from previous unwinds.
131   process_memory_->Clear();
132 
133   if (maps_->Find(regs_->pc()) == nullptr) {
134     regs_->fallback_pc();
135   }
136 
137   bool return_address_attempt = false;
138   bool adjust_pc = false;
139   for (; frames_.size() < max_frames_;) {
140     uint64_t cur_pc = regs_->pc();
141     uint64_t cur_sp = regs_->sp();
142 
143     std::shared_ptr<MapInfo> map_info = maps_->Find(regs_->pc());
144     uint64_t pc_adjustment = 0;
145     uint64_t step_pc;
146     uint64_t rel_pc;
147     Elf* elf;
148     bool ignore_frame = false;
149     if (map_info == nullptr) {
150       step_pc = regs_->pc();
151       rel_pc = step_pc;
152       // If we get invalid map via return_address_attempt, don't hide error for the previous frame.
153       if (!return_address_attempt || last_error_.code == ERROR_NONE) {
154         last_error_.code = ERROR_INVALID_MAP;
155         last_error_.address = step_pc;
156       }
157       elf = nullptr;
158     } else {
159       ignore_frame =
160           initial_map_names_to_skip != nullptr &&
161           std::find(initial_map_names_to_skip->begin(), initial_map_names_to_skip->end(),
162                     android::base::Basename(map_info->name())) != initial_map_names_to_skip->end();
163       if (!ignore_frame && ShouldStop(map_suffixes_to_ignore, map_info->name())) {
164         break;
165       }
166       elf = map_info->GetElf(process_memory_, arch_);
167       step_pc = regs_->pc();
168       rel_pc = elf->GetRelPc(step_pc, map_info.get());
169       // Everyone except elf data in gdb jit debug maps uses the relative pc.
170       if (!(map_info->flags() & MAPS_FLAGS_JIT_SYMFILE_MAP)) {
171         step_pc = rel_pc;
172       }
173       if (adjust_pc) {
174         pc_adjustment = GetPcAdjustment(rel_pc, elf, arch_);
175       } else {
176         pc_adjustment = 0;
177       }
178       step_pc -= pc_adjustment;
179 
180       // If the pc is in an invalid elf file, try and get an Elf object
181       // using the jit debug information.
182       if (!elf->valid() && jit_debug_ != nullptr && (map_info->flags() & PROT_EXEC)) {
183         uint64_t adjusted_jit_pc = regs_->pc() - pc_adjustment;
184         Elf* jit_elf = jit_debug_->Find(maps_, adjusted_jit_pc);
185         if (jit_elf != nullptr) {
186           // The jit debug information requires a non relative adjusted pc.
187           step_pc = adjusted_jit_pc;
188           elf = jit_elf;
189         }
190       }
191     }
192 
193     FrameData* frame = nullptr;
194     if (!ignore_frame) {
195       if (regs_->dex_pc() != 0) {
196         // Add a frame to represent the dex file.
197         FillInDexFrame();
198         // Clear the dex pc so that we don't repeat this frame later.
199         regs_->set_dex_pc(0);
200 
201         // Make sure there is enough room for the real frame.
202         if (frames_.size() == max_frames_) {
203           last_error_.code = ERROR_MAX_FRAMES_EXCEEDED;
204           break;
205         }
206       }
207 
208       frame = FillInFrame(map_info, elf, rel_pc, pc_adjustment);
209 
210       // Once a frame is added, stop skipping frames.
211       initial_map_names_to_skip = nullptr;
212     }
213     adjust_pc = true;
214 
215     bool stepped = false;
216     bool in_device_map = false;
217     bool finished = false;
218     if (map_info != nullptr) {
219       if (map_info->flags() & MAPS_FLAGS_DEVICE_MAP) {
220         // Do not stop here, fall through in case we are
221         // in the speculative unwind path and need to remove
222         // some of the speculative frames.
223         in_device_map = true;
224       } else {
225         auto sp_info = maps_->Find(regs_->sp());
226         if (sp_info != nullptr && sp_info->flags() & MAPS_FLAGS_DEVICE_MAP) {
227           // Do not stop here, fall through in case we are
228           // in the speculative unwind path and need to remove
229           // some of the speculative frames.
230           in_device_map = true;
231         } else {
232           bool is_signal_frame = false;
233           if (elf->StepIfSignalHandler(rel_pc, regs_, process_memory_.get())) {
234             stepped = true;
235             is_signal_frame = true;
236           } else if (elf->Step(step_pc, regs_, process_memory_.get(), &finished,
237                                &is_signal_frame)) {
238             stepped = true;
239           }
240           if (is_signal_frame && frame != nullptr) {
241             // Need to adjust the relative pc because the signal handler
242             // pc should not be adjusted.
243             frame->rel_pc = rel_pc;
244             frame->pc += pc_adjustment;
245             step_pc = rel_pc;
246           }
247           elf->GetLastError(&last_error_);
248         }
249       }
250     }
251 
252     if (frame != nullptr) {
253       if (!resolve_names_ ||
254           !elf->GetFunctionName(step_pc, &frame->function_name, &frame->function_offset)) {
255         frame->function_name = "";
256         frame->function_offset = 0;
257       }
258     }
259 
260     if (finished) {
261       break;
262     }
263 
264     if (!stepped) {
265       if (return_address_attempt) {
266         // Only remove the speculative frame if there are more than two frames
267         // or the pc in the first frame is in a valid map.
268         // This allows for a case where the code jumps into the middle of
269         // nowhere, but there is no other unwind information after that.
270         if (frames_.size() > 2 || (frames_.size() > 0 && maps_->Find(frames_[0].pc) != nullptr)) {
271           // Remove the speculative frame.
272           frames_.pop_back();
273         }
274         break;
275       } else if (in_device_map) {
276         // Do not attempt any other unwinding, pc or sp is in a device
277         // map.
278         break;
279       } else {
280         // Steping didn't work, try this secondary method.
281         if (!regs_->SetPcFromReturnAddress(process_memory_.get())) {
282           break;
283         }
284         return_address_attempt = true;
285       }
286     } else {
287       return_address_attempt = false;
288       if (max_frames_ == frames_.size()) {
289         last_error_.code = ERROR_MAX_FRAMES_EXCEEDED;
290       }
291     }
292 
293     // If the pc and sp didn't change, then consider everything stopped.
294     if (cur_pc == regs_->pc() && cur_sp == regs_->sp()) {
295       last_error_.code = ERROR_REPEATED_FRAME;
296       break;
297     }
298   }
299 }
300 
FormatFrame(const FrameData & frame) const301 std::string Unwinder::FormatFrame(const FrameData& frame) const {
302   return FormatFrame(arch_, frame, display_build_id_);
303 }
304 
FormatFrame(ArchEnum arch,const FrameData & frame,bool display_build_id)305 std::string Unwinder::FormatFrame(ArchEnum arch, const FrameData& frame, bool display_build_id) {
306   std::string data;
307   if (ArchIs32Bit(arch)) {
308     data += android::base::StringPrintf("  #%02zu pc %08" PRIx64, frame.num, frame.rel_pc);
309   } else {
310     data += android::base::StringPrintf("  #%02zu pc %016" PRIx64, frame.num, frame.rel_pc);
311   }
312 
313   auto map_info = frame.map_info;
314   if (map_info == nullptr) {
315     // No valid map associated with this frame.
316     data += "  <unknown>";
317   } else if (!map_info->name().empty()) {
318     data += "  ";
319     data += map_info->GetFullName();
320   } else {
321     data += android::base::StringPrintf("  <anonymous:%" PRIx64 ">", map_info->start());
322   }
323 
324   if (map_info != nullptr && map_info->elf_start_offset() != 0) {
325     data += android::base::StringPrintf(" (offset 0x%" PRIx64 ")", map_info->elf_start_offset());
326   }
327 
328   if (!frame.function_name.empty()) {
329     char* demangled_name = __cxa_demangle(frame.function_name.c_str(), nullptr, nullptr, nullptr);
330     if (demangled_name == nullptr) {
331       data += " (";
332       data += frame.function_name;
333     } else {
334       data += " (";
335       data += demangled_name;
336       free(demangled_name);
337     }
338     if (frame.function_offset != 0) {
339       data += android::base::StringPrintf("+%" PRId64, frame.function_offset);
340     }
341     data += ')';
342   }
343 
344   if (map_info != nullptr && display_build_id) {
345     std::string build_id = map_info->GetPrintableBuildID();
346     if (!build_id.empty()) {
347       data += " (BuildId: " + build_id + ')';
348     }
349   }
350   return data;
351 }
352 
FormatFrame(size_t frame_num) const353 std::string Unwinder::FormatFrame(size_t frame_num) const {
354   if (frame_num >= frames_.size()) {
355     return "";
356   }
357   return FormatFrame(arch_, frames_[frame_num], display_build_id_);
358 }
359 
SetJitDebug(JitDebug * jit_debug)360 void Unwinder::SetJitDebug(JitDebug* jit_debug) {
361   jit_debug_ = jit_debug;
362 }
363 
SetDexFiles(DexFiles * dex_files)364 void Unwinder::SetDexFiles(DexFiles* dex_files) {
365   dex_files_ = dex_files;
366 }
367 
Init()368 bool UnwinderFromPid::Init() {
369   CHECK(arch_ != ARCH_UNKNOWN);
370   if (initted_) {
371     return true;
372   }
373   initted_ = true;
374 
375   if (maps_ == nullptr) {
376     if (pid_ == getpid()) {
377       maps_ptr_.reset(new LocalMaps());
378     } else {
379       maps_ptr_.reset(new RemoteMaps(pid_));
380     }
381     if (!maps_ptr_->Parse()) {
382       ClearErrors();
383       last_error_.code = ERROR_INVALID_MAP;
384       return false;
385     }
386     maps_ = maps_ptr_.get();
387   }
388 
389   if (process_memory_ == nullptr) {
390     if (pid_ == getpid()) {
391       // Local unwind, so use thread cache to allow multiple threads
392       // to cache data even when multiple threads access the same object.
393       process_memory_ = Memory::CreateProcessMemoryThreadCached(pid_);
394     } else {
395       // Remote unwind should be safe to cache since the unwind will
396       // be occurring on a stopped process.
397       process_memory_ = Memory::CreateProcessMemoryCached(pid_);
398     }
399   }
400 
401   jit_debug_ptr_ = CreateJitDebug(arch_, process_memory_);
402   jit_debug_ = jit_debug_ptr_.get();
403   SetJitDebug(jit_debug_);
404 #if defined(DEXFILE_SUPPORT)
405   dex_files_ptr_ = CreateDexFiles(arch_, process_memory_);
406   dex_files_ = dex_files_ptr_.get();
407   SetDexFiles(dex_files_);
408 #endif
409 
410   return true;
411 }
412 
Unwind(const std::vector<std::string> * initial_map_names_to_skip,const std::vector<std::string> * map_suffixes_to_ignore)413 void UnwinderFromPid::Unwind(const std::vector<std::string>* initial_map_names_to_skip,
414                              const std::vector<std::string>* map_suffixes_to_ignore) {
415   if (!Init()) {
416     return;
417   }
418   Unwinder::Unwind(initial_map_names_to_skip, map_suffixes_to_ignore);
419 }
420 
BuildFrameFromPcOnly(uint64_t pc,ArchEnum arch,Maps * maps,JitDebug * jit_debug,std::shared_ptr<Memory> process_memory,bool resolve_names)421 FrameData Unwinder::BuildFrameFromPcOnly(uint64_t pc, ArchEnum arch, Maps* maps,
422                                          JitDebug* jit_debug,
423                                          std::shared_ptr<Memory> process_memory,
424                                          bool resolve_names) {
425   FrameData frame;
426 
427   std::shared_ptr<MapInfo> map_info = maps->Find(pc);
428   if (map_info == nullptr || arch == ARCH_UNKNOWN) {
429     frame.pc = pc;
430     frame.rel_pc = pc;
431     return frame;
432   }
433 
434   Elf* elf = map_info->GetElf(process_memory, arch);
435 
436   uint64_t relative_pc = elf->GetRelPc(pc, map_info.get());
437 
438   uint64_t pc_adjustment = GetPcAdjustment(relative_pc, elf, arch);
439   relative_pc -= pc_adjustment;
440   // The debug PC may be different if the PC comes from the JIT.
441   uint64_t debug_pc = relative_pc;
442 
443   // If we don't have a valid ELF file, check the JIT.
444   if (!elf->valid() && jit_debug != nullptr) {
445     uint64_t jit_pc = pc - pc_adjustment;
446     Elf* jit_elf = jit_debug->Find(maps, jit_pc);
447     if (jit_elf != nullptr) {
448       debug_pc = jit_pc;
449       elf = jit_elf;
450     }
451   }
452 
453   // Copy all the things we need into the frame for symbolization.
454   frame.rel_pc = relative_pc;
455   frame.pc = pc - pc_adjustment;
456   frame.map_info = map_info;
457 
458   if (!resolve_names ||
459       !elf->GetFunctionName(debug_pc, &frame.function_name, &frame.function_offset)) {
460     frame.function_name = "";
461     frame.function_offset = 0;
462   }
463   return frame;
464 }
465 
BuildFrameFromPcOnly(uint64_t pc)466 FrameData Unwinder::BuildFrameFromPcOnly(uint64_t pc) {
467   return BuildFrameFromPcOnly(pc, arch_, maps_, jit_debug_, process_memory_, resolve_names_);
468 }
469 
470 }  // namespace unwindstack
471