xref: /aosp_15_r20/external/mesa3d/include/android_stub/backtrace/Backtrace.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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