27 :
Unwind(thread), m_frames(), m_unwind_complete(false),
28 m_user_supplied_trap_handler_functions() {
32 process_sp->GetTarget().GetUserSpecifiedTrapHandlerNames(args);
34 for (
size_t i = 0; i < count; i++) {
45#define FRAME_COUNT 10000
46 using namespace std::chrono;
47 auto time_value = steady_clock::now();
53 ABI *abi = process_sp ? process_sp->GetABI().get() :
nullptr;
57 if ((
m_frames.size() % FRAME_COUNT) == 0) {
58 const auto now = steady_clock::now();
59 const auto delta_t = now - time_value;
60 printf(
"%u frames in %.9f ms (%g frames/sec)\n", FRAME_COUNT,
61 duration<double, std::milli>(delta_t).count(),
62 (
float)FRAME_COUNT / duration<double>(delta_t).count());
76 ABI *abi = process_sp ? process_sp->GetABI().get() :
nullptr;
82 if (reg_ctx_sp.get() ==
nullptr)
85 if (!reg_ctx_sp->IsValid())
88 if (!reg_ctx_sp->GetCFA(first_cursor_sp->cfa))
91 if (!reg_ctx_sp->ReadPC(first_cursor_sp->start_pc))
96 first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
107 LLDB_LOGF(log,
"th%d Unwind of this thread is complete.",
116 "Get one more frame called with empty frame list");
130 m_thread, prev_frame->reg_ctx_lldb_sp, cursor_sp->sctx, cur_idx, *
this));
142 if (cur_idx >= max_stack_depth) {
144 "%*sFrame %d unwound too many frames, assuming unwind has "
145 "gone astray, stopping.",
146 cur_idx < 100 ? cur_idx : 100,
"", cur_idx);
150 if (reg_ctx_sp.get() ==
nullptr) {
154 if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
158 if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
164 LLDB_LOGF(log,
"%*sFrame %d did not get a RegisterContext, stopping.",
165 cur_idx < 100 ? cur_idx : 100,
"", cur_idx);
169 if (!reg_ctx_sp->IsValid()) {
173 if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
177 if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
184 "%*sFrame %d invalid RegisterContext for this frame, "
185 "stopping stack walk",
186 cur_idx < 100 ? cur_idx : 100,
"", cur_idx);
189 if (!reg_ctx_sp->GetCFA(cursor_sp->cfa)) {
193 if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
197 if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
204 "%*sFrame %d did not get CFA for this frame, stopping stack walk",
205 cur_idx < 100 ? cur_idx : 100,
"", cur_idx);
212 if (!reg_ctx_sp->IsTrapHandlerFrame()) {
218 if (!reg_ctx_sp->TryFallbackUnwindPlan() ||
219 !reg_ctx_sp->GetCFA(cursor_sp->cfa) ||
221 if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
225 if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
232 "%*sFrame %d did not get a valid CFA for this frame, "
233 "stopping stack walk",
234 cur_idx < 100 ? cur_idx : 100,
"", cur_idx);
238 "%*sFrame %d had a bad CFA value but we switched the "
239 "UnwindPlan being used and got one that looks more "
241 cur_idx < 100 ? cur_idx : 100,
"", cur_idx);
245 if (!reg_ctx_sp->ReadPC(cursor_sp->start_pc)) {
249 if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
253 if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
260 "%*sFrame %d did not get PC for this frame, stopping stack walk",
261 cur_idx < 100 ? cur_idx : 100,
"", cur_idx);
269 !prev_frame->reg_ctx_lldb_sp->IsTrapHandlerFrame()) {
273 if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
277 if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
283 LLDB_LOGF(log,
"%*sFrame %d did not get a valid PC, stopping stack walk",
284 cur_idx < 100 ? cur_idx : 100,
"", cur_idx);
288 if (prev_frame->start_pc == cursor_sp->start_pc &&
289 prev_frame->cfa == cursor_sp->cfa) {
291 "th%d pc of this frame is the same as the previous frame and "
292 "CFAs for both frames are identical -- stopping unwind",
297 cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
303 assert(
m_frames.size() == 1 &&
"No. of cursor frames are not 1");
315 for (uint32_t i = 1; i <
m_frames.size(); i++)
336 if (new_frame ==
nullptr)
339 if (new_frame ==
nullptr) {
340 LLDB_LOGF(log,
"th%d Unwind of this thread is complete.",
357 ->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
367 if (new_frame_v2 ==
nullptr) {
398 bool &behaves_like_zeroth_frame) {
405 ABI *abi = process_sp ? process_sp->GetABI().get() :
nullptr;
415 behaves_like_zeroth_frame =
true;
416 }
else if (
m_frames[idx - 1]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) {
420 behaves_like_zeroth_frame =
true;
421 }
else if (
m_frames[idx]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) {
427 behaves_like_zeroth_frame =
true;
428 }
else if (
m_frames[idx]->reg_ctx_lldb_sp->BehavesLikeZerothFrame()) {
429 behaves_like_zeroth_frame =
true;
431 behaves_like_zeroth_frame =
false;
453 ABI *abi = process_sp ? process_sp->GetABI().get() :
nullptr;
460 const uint32_t num_frames =
m_frames.size();
461 if (idx < num_frames) {
472 reg_ctx_sp =
m_frames[frame_num]->reg_ctx_lldb_sp;
478 uint32_t starting_frame_num,
bool pc_reg) {
479 int64_t frame_num = starting_frame_num;
480 if (
static_cast<size_t>(frame_num) >=
m_frames.size())
488 result =
m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister(
489 lldb_regnum, regloc);
492 while (frame_num >= 0) {
494 result =
m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister(
495 lldb_regnum, regloc);
#define LLDB_LOGF(log,...)
virtual bool CodeAddressIsValid(lldb::addr_t pc)=0
virtual bool CallFrameAddressIsValid(lldb::addr_t cfa)=0
A command line argument class.
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
A uniqued constant string class.
This base class provides an interface to stack frames.
uint32_t GetConcreteFrameIndex() const
Query this frame to find what frame it is in this Thread's StackFrameList, not counting inlined frame...
uint64_t GetMaxBacktraceDepth() const
virtual lldb::RegisterContextSP GetRegisterContext()=0
uint32_t GetIndexID() const
lldb::ProcessSP GetProcess() const
void UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi)
std::vector< ConstString > m_user_supplied_trap_handler_functions
std::vector< CursorSP > m_frames
RegisterContextLLDBSP GetRegisterContextForFrameNum(uint32_t frame_num)
lldb::RegisterContextSP DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) override
UnwindLLDB(lldb_private::Thread &thread)
friend class lldb_private::RegisterContextUnwind
CursorSP m_candidate_frame
std::shared_ptr< Cursor > CursorSP
bool AddOneMoreFrame(ABI *abi)
CursorSP GetOneMoreFrame(ABI *abi)
std::shared_ptr< RegisterContextUnwind > RegisterContextLLDBSP
bool DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, lldb::addr_t &start_pc, bool &behaves_like_zeroth_frame) override
bool SearchForSavedLocationForRegister(uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation ®loc, uint32_t starting_frame_num, bool pc_register)
uint32_t DoGetFrameCount() override
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::RegisterContext > RegisterContextSP
RegisterContextLLDBSP reg_ctx_lldb_sp
@ eRegisterInLiveRegisterContext
union lldb_private::UnwindLLDB::RegisterLocation::@37 location