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 #pragma once 18 19 #include <stdint.h> 20 #include <sys/types.h> 21 22 #include <memory> 23 #include <string> 24 #include <vector> 25 26 #include <unwindstack/Arch.h> 27 #include <unwindstack/DexFiles.h> 28 #include <unwindstack/Error.h> 29 #include <unwindstack/JitDebug.h> 30 #include <unwindstack/Maps.h> 31 #include <unwindstack/Memory.h> 32 #include <unwindstack/Regs.h> 33 #include <unwindstack/SharedString.h> 34 35 namespace unwindstack { 36 37 // Forward declarations. 38 class Elf; 39 class ThreadEntry; 40 41 struct FrameData { 42 size_t num; 43 44 uint64_t rel_pc; 45 uint64_t pc; 46 uint64_t sp; 47 48 SharedString function_name; 49 uint64_t function_offset = 0; 50 51 std::shared_ptr<MapInfo> map_info; 52 }; 53 54 class Unwinder { 55 public: Unwinder(size_t max_frames,Maps * maps,Regs * regs,std::shared_ptr<Memory> process_memory)56 Unwinder(size_t max_frames, Maps* maps, Regs* regs, std::shared_ptr<Memory> process_memory) 57 : max_frames_(max_frames), 58 maps_(maps), 59 regs_(regs), 60 process_memory_(process_memory), 61 arch_(regs->Arch()) {} Unwinder(size_t max_frames,Maps * maps,std::shared_ptr<Memory> process_memory)62 Unwinder(size_t max_frames, Maps* maps, std::shared_ptr<Memory> process_memory) 63 : max_frames_(max_frames), maps_(maps), process_memory_(process_memory) {} 64 65 virtual ~Unwinder() = default; 66 67 virtual void Unwind(const std::vector<std::string>* initial_map_names_to_skip = nullptr, 68 const std::vector<std::string>* map_suffixes_to_ignore = nullptr); 69 NumFrames()70 size_t NumFrames() const { return frames_.size(); } 71 72 // Returns frames after unwinding. 73 // Intentionally mutable (which can be used to swap in reserved memory before unwinding). frames()74 std::vector<FrameData>& frames() { return frames_; } 75 ConsumeFrames()76 std::vector<FrameData> ConsumeFrames() { 77 std::vector<FrameData> frames = std::move(frames_); 78 frames_.clear(); 79 return frames; 80 } 81 82 std::string FormatFrame(size_t frame_num) const; 83 std::string FormatFrame(const FrameData& frame) const; 84 85 static std::string FormatFrame(ArchEnum arch, const FrameData& frame, 86 bool display_build_id = true); 87 SetArch(ArchEnum arch)88 void SetArch(ArchEnum arch) { arch_ = arch; }; 89 90 void SetJitDebug(JitDebug* jit_debug); 91 SetRegs(Regs * regs)92 void SetRegs(Regs* regs) { 93 regs_ = regs; 94 arch_ = regs_ != nullptr ? regs->Arch() : ARCH_UNKNOWN; 95 } GetMaps()96 Maps* GetMaps() { return maps_; } GetProcessMemory()97 std::shared_ptr<Memory>& GetProcessMemory() { return process_memory_; } 98 99 // Disabling the resolving of names results in the function name being 100 // set to an empty string and the function offset being set to zero. SetResolveNames(bool resolve)101 void SetResolveNames(bool resolve) { resolve_names_ = resolve; } 102 SetDisplayBuildID(bool display_build_id)103 void SetDisplayBuildID(bool display_build_id) { display_build_id_ = display_build_id; } 104 105 void SetDexFiles(DexFiles* dex_files); 106 LastError()107 const ErrorData& LastError() { return last_error_; } LastErrorCode()108 ErrorCode LastErrorCode() { return last_error_.code; } LastErrorCodeString()109 const char* LastErrorCodeString() { return GetErrorCodeString(last_error_.code); } LastErrorAddress()110 uint64_t LastErrorAddress() { return last_error_.address; } warnings()111 uint64_t warnings() { return warnings_; } 112 113 // Builds a frame for symbolization using the maps from this unwinder. The 114 // constructed frame contains just enough information to be used to symbolize 115 // frames collected by frame-pointer unwinding that's done outside of 116 // libunwindstack. This is used by tombstoned to symbolize frame pointer-based 117 // stack traces that are collected by tools such as GWP-ASan and MTE. 118 static FrameData BuildFrameFromPcOnly(uint64_t pc, ArchEnum arch, Maps* maps, JitDebug* jit_debug, 119 std::shared_ptr<Memory> process_memory, bool resolve_names); 120 FrameData BuildFrameFromPcOnly(uint64_t pc); 121 122 protected: max_frames_(max_frames)123 Unwinder(size_t max_frames, Maps* maps = nullptr) : max_frames_(max_frames), maps_(maps) {} 124 Unwinder(size_t max_frames, ArchEnum arch, Maps* maps = nullptr) max_frames_(max_frames)125 : max_frames_(max_frames), maps_(maps), arch_(arch) {} Unwinder(size_t max_frames,ArchEnum arch,Maps * maps,std::shared_ptr<Memory> & process_memory)126 Unwinder(size_t max_frames, ArchEnum arch, Maps* maps, std::shared_ptr<Memory>& process_memory) 127 : max_frames_(max_frames), maps_(maps), process_memory_(process_memory), arch_(arch) {} 128 ClearErrors()129 void ClearErrors() { 130 warnings_ = WARNING_NONE; 131 last_error_.code = ERROR_NONE; 132 last_error_.address = 0; 133 } 134 135 void FillInDexFrame(); 136 FrameData* FillInFrame(std::shared_ptr<MapInfo>& map_info, Elf* elf, uint64_t rel_pc, 137 uint64_t pc_adjustment); 138 139 size_t max_frames_; 140 Maps* maps_ = nullptr; 141 Regs* regs_; 142 std::vector<FrameData> frames_; 143 std::shared_ptr<Memory> process_memory_; 144 JitDebug* jit_debug_ = nullptr; 145 DexFiles* dex_files_ = nullptr; 146 bool resolve_names_ = true; 147 bool display_build_id_ = false; 148 ErrorData last_error_; 149 uint64_t warnings_; 150 ArchEnum arch_ = ARCH_UNKNOWN; 151 }; 152 153 class UnwinderFromPid : public Unwinder { 154 public: 155 UnwinderFromPid(size_t max_frames, pid_t pid, Maps* maps = nullptr) Unwinder(max_frames,maps)156 : Unwinder(max_frames, maps), pid_(pid) {} UnwinderFromPid(size_t max_frames,pid_t pid,std::shared_ptr<Memory> & process_memory)157 UnwinderFromPid(size_t max_frames, pid_t pid, std::shared_ptr<Memory>& process_memory) 158 : Unwinder(max_frames, nullptr, process_memory), pid_(pid) {} 159 UnwinderFromPid(size_t max_frames, pid_t pid, ArchEnum arch, Maps* maps = nullptr) Unwinder(max_frames,arch,maps)160 : Unwinder(max_frames, arch, maps), pid_(pid) {} UnwinderFromPid(size_t max_frames,pid_t pid,ArchEnum arch,Maps * maps,std::shared_ptr<Memory> & process_memory)161 UnwinderFromPid(size_t max_frames, pid_t pid, ArchEnum arch, Maps* maps, 162 std::shared_ptr<Memory>& process_memory) 163 : Unwinder(max_frames, arch, maps, process_memory), pid_(pid) {} 164 virtual ~UnwinderFromPid() = default; 165 166 bool Init(); 167 168 void Unwind(const std::vector<std::string>* initial_map_names_to_skip = nullptr, 169 const std::vector<std::string>* map_suffixes_to_ignore = nullptr) override; 170 171 protected: 172 pid_t pid_; 173 std::unique_ptr<Maps> maps_ptr_; 174 std::unique_ptr<JitDebug> jit_debug_ptr_; 175 std::unique_ptr<DexFiles> dex_files_ptr_; 176 bool initted_ = false; 177 }; 178 179 class ThreadUnwinder : public UnwinderFromPid { 180 public: 181 ThreadUnwinder(size_t max_frames, Maps* maps = nullptr); 182 ThreadUnwinder(size_t max_frames, Maps* maps, std::shared_ptr<Memory>& process_memory); 183 ThreadUnwinder(size_t max_frames, const ThreadUnwinder* unwinder); 184 virtual ~ThreadUnwinder() = default; 185 186 void SetObjects(ThreadUnwinder* unwinder); 187 Unwind(const std::vector<std::string> *,const std::vector<std::string> *)188 void Unwind(const std::vector<std::string>*, const std::vector<std::string>*) override {} 189 190 void UnwindWithSignal(int signal, pid_t tid, std::unique_ptr<Regs>* initial_regs = nullptr, 191 const std::vector<std::string>* initial_map_names_to_skip = nullptr, 192 const std::vector<std::string>* map_suffixes_to_ignore = nullptr); 193 194 protected: 195 ThreadEntry* SendSignalToThread(int signal, pid_t tid); 196 }; 197 198 } // namespace unwindstack 199