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