1*61046927SAndroid Build Coastguard Worker /* 2*61046927SAndroid Build Coastguard Worker * Copyright (C) 2013 The Android Open Source Project 3*61046927SAndroid Build Coastguard Worker * 4*61046927SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*61046927SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*61046927SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*61046927SAndroid Build Coastguard Worker * 8*61046927SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*61046927SAndroid Build Coastguard Worker * 10*61046927SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*61046927SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*61046927SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*61046927SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*61046927SAndroid Build Coastguard Worker * limitations under the License. 15*61046927SAndroid Build Coastguard Worker */ 16*61046927SAndroid Build Coastguard Worker 17*61046927SAndroid Build Coastguard Worker #ifndef _BACKTRACE_BACKTRACE_H 18*61046927SAndroid Build Coastguard Worker #define _BACKTRACE_BACKTRACE_H 19*61046927SAndroid Build Coastguard Worker 20*61046927SAndroid Build Coastguard Worker #include <inttypes.h> 21*61046927SAndroid Build Coastguard Worker #include <stdint.h> 22*61046927SAndroid Build Coastguard Worker 23*61046927SAndroid Build Coastguard Worker #include <string> 24*61046927SAndroid Build Coastguard Worker #include <vector> 25*61046927SAndroid Build Coastguard Worker 26*61046927SAndroid Build Coastguard Worker #include <backtrace/backtrace_constants.h> 27*61046927SAndroid Build Coastguard Worker #include <backtrace/BacktraceMap.h> 28*61046927SAndroid Build Coastguard Worker 29*61046927SAndroid Build Coastguard Worker #if defined(__LP64__) 30*61046927SAndroid Build Coastguard Worker #define PRIPTR "016" PRIx64 31*61046927SAndroid Build Coastguard Worker typedef uint64_t word_t; 32*61046927SAndroid Build Coastguard Worker #else 33*61046927SAndroid Build Coastguard Worker #define PRIPTR "08" PRIx64 34*61046927SAndroid Build Coastguard Worker typedef uint32_t word_t; 35*61046927SAndroid Build Coastguard Worker #endif 36*61046927SAndroid Build Coastguard Worker 37*61046927SAndroid Build Coastguard Worker enum BacktraceUnwindErrorCode : uint32_t { 38*61046927SAndroid Build Coastguard Worker BACKTRACE_UNWIND_NO_ERROR, 39*61046927SAndroid Build Coastguard Worker // Something failed while trying to perform the setup to begin the unwind. 40*61046927SAndroid Build Coastguard Worker BACKTRACE_UNWIND_ERROR_SETUP_FAILED, 41*61046927SAndroid Build Coastguard Worker // There is no map information to use with the unwind. 42*61046927SAndroid Build Coastguard Worker BACKTRACE_UNWIND_ERROR_MAP_MISSING, 43*61046927SAndroid Build Coastguard Worker // An error occurred that indicates a programming error. 44*61046927SAndroid Build Coastguard Worker BACKTRACE_UNWIND_ERROR_INTERNAL, 45*61046927SAndroid Build Coastguard Worker // The thread to unwind has disappeared before the unwind can begin. 46*61046927SAndroid Build Coastguard Worker BACKTRACE_UNWIND_ERROR_THREAD_DOESNT_EXIST, 47*61046927SAndroid Build Coastguard Worker // The thread to unwind has not responded to a signal in a timely manner. 48*61046927SAndroid Build Coastguard Worker BACKTRACE_UNWIND_ERROR_THREAD_TIMEOUT, 49*61046927SAndroid Build Coastguard Worker // Attempt to do an unsupported operation. 50*61046927SAndroid Build Coastguard Worker BACKTRACE_UNWIND_ERROR_UNSUPPORTED_OPERATION, 51*61046927SAndroid Build Coastguard Worker // Attempt to do an offline unwind without a context. 52*61046927SAndroid Build Coastguard Worker BACKTRACE_UNWIND_ERROR_NO_CONTEXT, 53*61046927SAndroid Build Coastguard Worker // The count of frames exceed MAX_BACKTRACE_FRAMES. 54*61046927SAndroid Build Coastguard Worker BACKTRACE_UNWIND_ERROR_EXCEED_MAX_FRAMES_LIMIT, 55*61046927SAndroid Build Coastguard Worker // Failed to read memory. 56*61046927SAndroid Build Coastguard Worker BACKTRACE_UNWIND_ERROR_ACCESS_MEM_FAILED, 57*61046927SAndroid Build Coastguard Worker // Failed to read registers. 58*61046927SAndroid Build Coastguard Worker BACKTRACE_UNWIND_ERROR_ACCESS_REG_FAILED, 59*61046927SAndroid Build Coastguard Worker // Failed to find a function in debug sections. 60*61046927SAndroid Build Coastguard Worker BACKTRACE_UNWIND_ERROR_FIND_PROC_INFO_FAILED, 61*61046927SAndroid Build Coastguard Worker // Failed to execute dwarf instructions in debug sections. 62*61046927SAndroid Build Coastguard Worker BACKTRACE_UNWIND_ERROR_EXECUTE_DWARF_INSTRUCTION_FAILED, 63*61046927SAndroid Build Coastguard Worker // Unwind information is incorrect. 64*61046927SAndroid Build Coastguard Worker BACKTRACE_UNWIND_ERROR_UNWIND_INFO, 65*61046927SAndroid Build Coastguard Worker // Unwind information stopped due to sp/pc repeating. 66*61046927SAndroid Build Coastguard Worker BACKTRACE_UNWIND_ERROR_REPEATED_FRAME, 67*61046927SAndroid Build Coastguard Worker // Unwind information stopped due to invalid elf. 68*61046927SAndroid Build Coastguard Worker BACKTRACE_UNWIND_ERROR_INVALID_ELF, 69*61046927SAndroid Build Coastguard Worker }; 70*61046927SAndroid Build Coastguard Worker 71*61046927SAndroid Build Coastguard Worker struct BacktraceUnwindError { 72*61046927SAndroid Build Coastguard Worker enum BacktraceUnwindErrorCode error_code; 73*61046927SAndroid Build Coastguard Worker 74*61046927SAndroid Build Coastguard Worker union { 75*61046927SAndroid Build Coastguard Worker // for BACKTRACE_UNWIND_ERROR_ACCESS_MEM_FAILED 76*61046927SAndroid Build Coastguard Worker uint64_t addr; 77*61046927SAndroid Build Coastguard Worker // for BACKTRACE_UNWIND_ERROR_ACCESS_REG_FAILED 78*61046927SAndroid Build Coastguard Worker uint64_t regno; 79*61046927SAndroid Build Coastguard Worker } error_info; 80*61046927SAndroid Build Coastguard Worker BacktraceUnwindErrorBacktraceUnwindError81*61046927SAndroid Build Coastguard Worker BacktraceUnwindError() : error_code(BACKTRACE_UNWIND_NO_ERROR) {} 82*61046927SAndroid Build Coastguard Worker }; 83*61046927SAndroid Build Coastguard Worker 84*61046927SAndroid Build Coastguard Worker struct backtrace_frame_data_t { 85*61046927SAndroid Build Coastguard Worker size_t num; // The current fame number. 86*61046927SAndroid Build Coastguard Worker uint64_t pc; // The absolute pc. 87*61046927SAndroid Build Coastguard Worker uint64_t rel_pc; // The relative pc. 88*61046927SAndroid Build Coastguard Worker uint64_t sp; // The top of the stack. 89*61046927SAndroid Build Coastguard Worker size_t stack_size; // The size of the stack, zero indicate an unknown stack size. 90*61046927SAndroid Build Coastguard Worker backtrace_map_t map; // The map associated with the given pc. 91*61046927SAndroid Build Coastguard Worker std::string func_name; // The function name associated with this pc, NULL if not found. 92*61046927SAndroid Build Coastguard Worker uint64_t func_offset; // pc relative to the start of the function, only valid if func_name is not 93*61046927SAndroid Build Coastguard Worker // NULL. 94*61046927SAndroid Build Coastguard Worker }; 95*61046927SAndroid Build Coastguard Worker 96*61046927SAndroid Build Coastguard Worker struct backtrace_stackinfo_t { 97*61046927SAndroid Build Coastguard Worker uint64_t start; 98*61046927SAndroid Build Coastguard Worker uint64_t end; 99*61046927SAndroid Build Coastguard Worker const uint8_t* data; 100*61046927SAndroid Build Coastguard Worker }; 101*61046927SAndroid Build Coastguard Worker 102*61046927SAndroid Build Coastguard Worker namespace unwindstack { 103*61046927SAndroid Build Coastguard Worker class Regs; 104*61046927SAndroid Build Coastguard Worker } 105*61046927SAndroid Build Coastguard Worker 106*61046927SAndroid Build Coastguard Worker class Backtrace { 107*61046927SAndroid Build Coastguard Worker public: 108*61046927SAndroid Build Coastguard Worker enum ArchEnum : uint8_t { 109*61046927SAndroid Build Coastguard Worker ARCH_ARM, 110*61046927SAndroid Build Coastguard Worker ARCH_ARM64, 111*61046927SAndroid Build Coastguard Worker ARCH_X86, 112*61046927SAndroid Build Coastguard Worker ARCH_X86_64, 113*61046927SAndroid Build Coastguard Worker }; 114*61046927SAndroid Build Coastguard Worker 115*61046927SAndroid Build Coastguard Worker static void SetGlobalElfCache(bool enable); 116*61046927SAndroid Build Coastguard Worker 117*61046927SAndroid Build Coastguard Worker // Create the correct Backtrace object based on what is to be unwound. 118*61046927SAndroid Build Coastguard Worker // If pid < 0 or equals the current pid, then the Backtrace object 119*61046927SAndroid Build Coastguard Worker // corresponds to the current process. 120*61046927SAndroid Build Coastguard Worker // If pid < 0 or equals the current pid and tid >= 0, then the Backtrace 121*61046927SAndroid Build Coastguard Worker // object corresponds to a thread in the current process. 122*61046927SAndroid Build Coastguard Worker // If pid >= 0 and tid < 0, then the Backtrace object corresponds to a 123*61046927SAndroid Build Coastguard Worker // different process. 124*61046927SAndroid Build Coastguard Worker // Tracing a thread in a different process is not supported. 125*61046927SAndroid Build Coastguard Worker // If map is NULL, then create the map and manage it internally. 126*61046927SAndroid Build Coastguard Worker // If map is not NULL, the map is still owned by the caller. 127*61046927SAndroid Build Coastguard Worker static Backtrace* Create(pid_t pid, pid_t tid, BacktraceMap* map = nullptr); 128*61046927SAndroid Build Coastguard Worker 129*61046927SAndroid Build Coastguard Worker virtual ~Backtrace(); 130*61046927SAndroid Build Coastguard Worker 131*61046927SAndroid Build Coastguard Worker // Get the current stack trace and store in the backtrace_ structure. 132*61046927SAndroid Build Coastguard Worker virtual bool Unwind(size_t num_ignore_frames, void* context = nullptr) = 0; 133*61046927SAndroid Build Coastguard Worker 134*61046927SAndroid Build Coastguard Worker static bool Unwind(unwindstack::Regs* regs, BacktraceMap* back_map, 135*61046927SAndroid Build Coastguard Worker std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames, 136*61046927SAndroid Build Coastguard Worker std::vector<std::string>* skip_names, BacktraceUnwindError* error = nullptr); 137*61046927SAndroid Build Coastguard Worker 138*61046927SAndroid Build Coastguard Worker // Get the function name and offset into the function given the pc. 139*61046927SAndroid Build Coastguard Worker // If the string is empty, then no valid function name was found, 140*61046927SAndroid Build Coastguard Worker // or the pc is not in any valid map. 141*61046927SAndroid Build Coastguard Worker virtual std::string GetFunctionName(uint64_t pc, uint64_t* offset, 142*61046927SAndroid Build Coastguard Worker const backtrace_map_t* map = nullptr); 143*61046927SAndroid Build Coastguard Worker 144*61046927SAndroid Build Coastguard Worker // Fill in the map data associated with the given pc. 145*61046927SAndroid Build Coastguard Worker virtual void FillInMap(uint64_t pc, backtrace_map_t* map); 146*61046927SAndroid Build Coastguard Worker 147*61046927SAndroid Build Coastguard Worker // Read the data at a specific address. 148*61046927SAndroid Build Coastguard Worker virtual bool ReadWord(uint64_t ptr, word_t* out_value) = 0; 149*61046927SAndroid Build Coastguard Worker 150*61046927SAndroid Build Coastguard Worker // Read arbitrary data from a specific address. If a read request would 151*61046927SAndroid Build Coastguard Worker // span from one map to another, this call only reads up until the end 152*61046927SAndroid Build Coastguard Worker // of the current map. 153*61046927SAndroid Build Coastguard Worker // Returns the total number of bytes actually read. 154*61046927SAndroid Build Coastguard Worker virtual size_t Read(uint64_t addr, uint8_t* buffer, size_t bytes) = 0; 155*61046927SAndroid Build Coastguard Worker 156*61046927SAndroid Build Coastguard Worker // Create a string representing the formatted line of backtrace information 157*61046927SAndroid Build Coastguard Worker // for a single frame. 158*61046927SAndroid Build Coastguard Worker virtual std::string FormatFrameData(size_t frame_num); 159*61046927SAndroid Build Coastguard Worker static std::string FormatFrameData(const backtrace_frame_data_t* frame); 160*61046927SAndroid Build Coastguard Worker Pid()161*61046927SAndroid Build Coastguard Worker pid_t Pid() const { return pid_; } Tid()162*61046927SAndroid Build Coastguard Worker pid_t Tid() const { return tid_; } NumFrames()163*61046927SAndroid Build Coastguard Worker size_t NumFrames() const { return frames_.size(); } 164*61046927SAndroid Build Coastguard Worker GetFrame(size_t frame_num)165*61046927SAndroid Build Coastguard Worker const backtrace_frame_data_t* GetFrame(size_t frame_num) { 166*61046927SAndroid Build Coastguard Worker if (frame_num >= frames_.size()) { 167*61046927SAndroid Build Coastguard Worker return nullptr; 168*61046927SAndroid Build Coastguard Worker } 169*61046927SAndroid Build Coastguard Worker return &frames_[frame_num]; 170*61046927SAndroid Build Coastguard Worker } 171*61046927SAndroid Build Coastguard Worker 172*61046927SAndroid Build Coastguard Worker typedef std::vector<backtrace_frame_data_t>::iterator iterator; begin()173*61046927SAndroid Build Coastguard Worker iterator begin() { return frames_.begin(); } end()174*61046927SAndroid Build Coastguard Worker iterator end() { return frames_.end(); } 175*61046927SAndroid Build Coastguard Worker 176*61046927SAndroid Build Coastguard Worker typedef std::vector<backtrace_frame_data_t>::const_iterator const_iterator; begin()177*61046927SAndroid Build Coastguard Worker const_iterator begin() const { return frames_.begin(); } end()178*61046927SAndroid Build Coastguard Worker const_iterator end() const { return frames_.end(); } 179*61046927SAndroid Build Coastguard Worker GetMap()180*61046927SAndroid Build Coastguard Worker BacktraceMap* GetMap() { return map_; } 181*61046927SAndroid Build Coastguard Worker GetError()182*61046927SAndroid Build Coastguard Worker BacktraceUnwindError GetError() { return error_; } 183*61046927SAndroid Build Coastguard Worker 184*61046927SAndroid Build Coastguard Worker std::string GetErrorString(BacktraceUnwindError error); 185*61046927SAndroid Build Coastguard Worker 186*61046927SAndroid Build Coastguard Worker // Set whether to skip frames in libbacktrace/libunwindstack when doing a local unwind. SetSkipFrames(bool skip_frames)187*61046927SAndroid Build Coastguard Worker void SetSkipFrames(bool skip_frames) { skip_frames_ = skip_frames; } 188*61046927SAndroid Build Coastguard Worker 189*61046927SAndroid Build Coastguard Worker protected: 190*61046927SAndroid Build Coastguard Worker Backtrace(pid_t pid, pid_t tid, BacktraceMap* map); 191*61046927SAndroid Build Coastguard Worker 192*61046927SAndroid Build Coastguard Worker // The name returned is not demangled, GetFunctionName() takes care of 193*61046927SAndroid Build Coastguard Worker // demangling the name. 194*61046927SAndroid Build Coastguard Worker virtual std::string GetFunctionNameRaw(uint64_t pc, uint64_t* offset) = 0; 195*61046927SAndroid Build Coastguard Worker 196*61046927SAndroid Build Coastguard Worker virtual bool VerifyReadWordArgs(uint64_t ptr, word_t* out_value); 197*61046927SAndroid Build Coastguard Worker 198*61046927SAndroid Build Coastguard Worker bool BuildMap(); 199*61046927SAndroid Build Coastguard Worker 200*61046927SAndroid Build Coastguard Worker pid_t pid_; 201*61046927SAndroid Build Coastguard Worker pid_t tid_; 202*61046927SAndroid Build Coastguard Worker 203*61046927SAndroid Build Coastguard Worker BacktraceMap* map_; 204*61046927SAndroid Build Coastguard Worker bool map_shared_; 205*61046927SAndroid Build Coastguard Worker 206*61046927SAndroid Build Coastguard Worker std::vector<backtrace_frame_data_t> frames_; 207*61046927SAndroid Build Coastguard Worker 208*61046927SAndroid Build Coastguard Worker // Skip frames in libbacktrace/libunwindstack when doing a local unwind. 209*61046927SAndroid Build Coastguard Worker bool skip_frames_ = true; 210*61046927SAndroid Build Coastguard Worker 211*61046927SAndroid Build Coastguard Worker BacktraceUnwindError error_; 212*61046927SAndroid Build Coastguard Worker }; 213*61046927SAndroid Build Coastguard Worker 214*61046927SAndroid Build Coastguard Worker #endif // _BACKTRACE_BACKTRACE_H 215