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