~mmach/netext73/mesa-haswell

« back to all changes in this revision

Viewing changes to include/android_stub/backtrace/Backtrace.h

  • Committer: mmach
  • Date: 2022-09-22 19:56:13 UTC
  • Revision ID: netbit73@gmail.com-20220922195613-wtik9mmy20tmor0i
2022-09-22 21:17:09

Show diffs side-by-side

added added

removed removed

Lines of Context:
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