brintos

brintos / llvm-project-archived public Read only

0
0
Text · 19.4 KiB · 4d3f239 Raw
528 lines · cpp
1//===-- UnwindLLDB.cpp ----------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Target/UnwindLLDB.h"10#include "lldb/Core/Module.h"11#include "lldb/Symbol/FuncUnwinders.h"12#include "lldb/Symbol/Function.h"13#include "lldb/Symbol/UnwindPlan.h"14#include "lldb/Target/ABI.h"15#include "lldb/Target/Process.h"16#include "lldb/Target/RegisterContext.h"17#include "lldb/Target/RegisterContextUnwind.h"18#include "lldb/Target/Target.h"19#include "lldb/Target/Thread.h"20#include "lldb/Utility/LLDBLog.h"21#include "lldb/Utility/Log.h"22 23using namespace lldb;24using namespace lldb_private;25 26UnwindLLDB::UnwindLLDB(Thread &thread)27    : Unwind(thread), m_frames(), m_unwind_complete(false),28      m_user_supplied_trap_handler_functions() {29  ProcessSP process_sp(thread.GetProcess());30  if (process_sp) {31    Args args;32    process_sp->GetTarget().GetUserSpecifiedTrapHandlerNames(args);33    size_t count = args.GetArgumentCount();34    for (size_t i = 0; i < count; i++) {35      const char *func_name = args.GetArgumentAtIndex(i);36      m_user_supplied_trap_handler_functions.push_back(ConstString(func_name));37    }38  }39}40 41uint32_t UnwindLLDB::DoGetFrameCount() {42  if (!m_unwind_complete) {43//#define DEBUG_FRAME_SPEED 144#if DEBUG_FRAME_SPEED45#define FRAME_COUNT 1000046    using namespace std::chrono;47    auto time_value = steady_clock::now();48#endif49    if (!AddFirstFrame())50      return 0;51 52    ProcessSP process_sp(m_thread.GetProcess());53    ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;54 55    while (AddOneMoreFrame(abi)) {56#if DEBUG_FRAME_SPEED57      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());63        time_value = now;64      }65#endif66    }67  }68  return m_frames.size();69}70 71bool UnwindLLDB::AddFirstFrame() {72  if (m_frames.size() > 0)73    return true;74 75  ProcessSP process_sp(m_thread.GetProcess());76  ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;77 78  // First, set up the 0th (initial) frame79  CursorSP first_cursor_sp(new Cursor());80  RegisterContextLLDBSP reg_ctx_sp(new RegisterContextUnwind(81      m_thread, RegisterContextLLDBSP(), first_cursor_sp->sctx, 0, *this));82  if (reg_ctx_sp.get() == nullptr)83    goto unwind_done;84 85  if (!reg_ctx_sp->IsValid())86    goto unwind_done;87 88  if (!reg_ctx_sp->GetCFA(first_cursor_sp->cfa))89    goto unwind_done;90 91  if (!reg_ctx_sp->ReadPC(first_cursor_sp->start_pc))92    goto unwind_done;93 94  // Everything checks out, so release the auto pointer value and let the95  // cursor own it in its shared pointer96  first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;97  m_frames.push_back(first_cursor_sp);98 99  // Update the Full Unwind Plan for this frame if not valid100  UpdateUnwindPlanForFirstFrameIfInvalid(abi);101 102  return true;103 104unwind_done:105  Log *log = GetLog(LLDBLog::Unwind);106  if (log) {107    LLDB_LOGF(log, "th%d Unwind of this thread is complete.",108              m_thread.GetIndexID());109  }110  m_unwind_complete = true;111  return false;112}113 114UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {115  assert(m_frames.size() != 0 &&116         "Get one more frame called with empty frame list");117 118  // If we've already gotten to the end of the stack, don't bother to try119  // again...120  if (m_unwind_complete)121    return nullptr;122 123  Log *log = GetLog(LLDBLog::Unwind);124 125  CursorSP prev_frame = m_frames.back();126  uint32_t cur_idx = m_frames.size();127 128  CursorSP cursor_sp(new Cursor());129  RegisterContextLLDBSP reg_ctx_sp(new RegisterContextUnwind(130      m_thread, prev_frame->reg_ctx_lldb_sp, cursor_sp->sctx, cur_idx, *this));131 132  uint64_t max_stack_depth = m_thread.GetMaxBacktraceDepth();133 134  // We want to detect an unwind that cycles erroneously and stop backtracing.135  // Don't want this maximum unwind limit to be too low -- if you have a136  // backtrace with an "infinitely recursing" bug, it will crash when the stack137  // blows out and the first 35,000 frames are uninteresting - it's the top138  // most 5 frames that you actually care about.  So you can't just cap the139  // unwind at 10,000 or something. Realistically anything over around 200,000140  // is going to blow out the stack space. If we're still unwinding at that141  // point, we're probably never going to finish.142  if (cur_idx >= max_stack_depth) {143    LLDB_LOGF(log,144              "%*sFrame %d unwound too many frames, assuming unwind has "145              "gone astray, stopping.",146              cur_idx < 100 ? cur_idx : 100, "", cur_idx);147    return nullptr;148  }149 150  if (reg_ctx_sp.get() == nullptr) {151    // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to152    // that and return true.  Subsequent calls to TryFallbackUnwindPlan() will153    // return false.154    if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {155      // TryFallbackUnwindPlan for prev_frame succeeded and updated156      // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame157      // still needs to be updated. Hence updating it.158      if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))159        return nullptr;160 161      return GetOneMoreFrame(abi);162    }163 164    LLDB_LOGF(log, "%*sFrame %d did not get a RegisterContext, stopping.",165              cur_idx < 100 ? cur_idx : 100, "", cur_idx);166    return nullptr;167  }168 169  if (!reg_ctx_sp->IsValid()) {170    // We failed to get a valid RegisterContext. See if the regctx below this171    // on the stack has a fallback unwind plan it can use. Subsequent calls to172    // TryFallbackUnwindPlan() will return false.173    if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {174      // TryFallbackUnwindPlan for prev_frame succeeded and updated175      // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame176      // still needs to be updated. Hence updating it.177      if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))178        return nullptr;179 180      return GetOneMoreFrame(abi);181    }182 183    LLDB_LOGF(log,184              "%*sFrame %d invalid RegisterContext for this frame, "185              "stopping stack walk",186              cur_idx < 100 ? cur_idx : 100, "", cur_idx);187    return nullptr;188  }189  if (!reg_ctx_sp->GetCFA(cursor_sp->cfa)) {190    // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to191    // that and return true.  Subsequent calls to TryFallbackUnwindPlan() will192    // return false.193    if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {194      // TryFallbackUnwindPlan for prev_frame succeeded and updated195      // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame196      // still needs to be updated. Hence updating it.197      if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))198        return nullptr;199 200      return GetOneMoreFrame(abi);201    }202 203    LLDB_LOGF(log,204              "%*sFrame %d did not get CFA for this frame, stopping stack walk",205              cur_idx < 100 ? cur_idx : 100, "", cur_idx);206    return nullptr;207  }208  if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) {209    // On Mac OS X, the _sigtramp asynchronous signal trampoline frame may not210    // have its (constructed) CFA aligned correctly -- don't do the abi211    // alignment check for these.212    if (!reg_ctx_sp->IsTrapHandlerFrame()) {213      // See if we can find a fallback unwind plan for THIS frame.  It may be214      // that the UnwindPlan we're using for THIS frame was bad and gave us a215      // bad CFA. If that's not it, then see if we can change the UnwindPlan216      // for the frame below us ("NEXT") -- see if using that other UnwindPlan217      // gets us a better unwind state.218      if (!reg_ctx_sp->TryFallbackUnwindPlan() ||219          !reg_ctx_sp->GetCFA(cursor_sp->cfa) ||220          !abi->CallFrameAddressIsValid(cursor_sp->cfa)) {221        if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {222          // TryFallbackUnwindPlan for prev_frame succeeded and updated223          // reg_ctx_lldb_sp field of prev_frame. However, cfa field of224          // prev_frame still needs to be updated. Hence updating it.225          if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))226            return nullptr;227 228          return GetOneMoreFrame(abi);229        }230 231        LLDB_LOGF(log,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);235        return nullptr;236      } else {237        LLDB_LOGF(log,238                  "%*sFrame %d had a bad CFA value but we switched the "239                  "UnwindPlan being used and got one that looks more "240                  "realistic.",241                  cur_idx < 100 ? cur_idx : 100, "", cur_idx);242      }243    }244  }245  if (!reg_ctx_sp->ReadPC(cursor_sp->start_pc)) {246    // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to247    // that and return true.  Subsequent calls to TryFallbackUnwindPlan() will248    // return false.249    if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {250      // TryFallbackUnwindPlan for prev_frame succeeded and updated251      // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame252      // still needs to be updated. Hence updating it.253      if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))254        return nullptr;255 256      return GetOneMoreFrame(abi);257    }258 259    LLDB_LOGF(log,260              "%*sFrame %d did not get PC for this frame, stopping stack walk",261              cur_idx < 100 ? cur_idx : 100, "", cur_idx);262    return nullptr;263  }264 265  // Invalid code addresses should not appear on the stack *unless* we're266  // directly below a trap handler frame (in this case, the invalid address is267  // likely the cause of the trap).268  if (abi && !abi->CodeAddressIsValid(cursor_sp->start_pc) &&269      !prev_frame->reg_ctx_lldb_sp->IsTrapHandlerFrame()) {270    // If the RegisterContextUnwind has a fallback UnwindPlan, it will switch to271    // that and return true.  Subsequent calls to TryFallbackUnwindPlan() will272    // return false.273    if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {274      // TryFallbackUnwindPlan for prev_frame succeeded and updated275      // reg_ctx_lldb_sp field of prev_frame. However, cfa field of prev_frame276      // still needs to be updated. Hence updating it.277      if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))278        return nullptr;279 280      return GetOneMoreFrame(abi);281    }282 283    LLDB_LOGF(log, "%*sFrame %d did not get a valid PC, stopping stack walk",284              cur_idx < 100 ? cur_idx : 100, "", cur_idx);285    return nullptr;286  }287  // Infinite loop where the current cursor is the same as the previous one...288  if (prev_frame->start_pc == cursor_sp->start_pc &&289      prev_frame->cfa == cursor_sp->cfa) {290    LLDB_LOGF(log,291              "th%d pc of this frame is the same as the previous frame and "292              "CFAs for both frames are identical -- stopping unwind",293              m_thread.GetIndexID());294    return nullptr;295  }296 297  cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;298  return cursor_sp;299}300 301void UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi) {302  // This function is called for First Frame only.303  assert(m_frames.size() == 1 && "No. of cursor frames are not 1");304 305  bool old_m_unwind_complete = m_unwind_complete;306  CursorSP old_m_candidate_frame = m_candidate_frame;307 308  // Try to unwind 2 more frames using the Unwinder. It uses Full UnwindPlan309  // and if Full UnwindPlan fails, then uses FallBack UnwindPlan. Also update310  // the cfa of Frame 0 (if required).311  AddOneMoreFrame(abi);312 313  // Remove all the frames added by above function as the purpose of using314  // above function was just to check whether Unwinder of Frame 0 works or not.315  for (uint32_t i = 1; i < m_frames.size(); i++)316    m_frames.pop_back();317 318  // Restore status after calling AddOneMoreFrame319  m_unwind_complete = old_m_unwind_complete;320  m_candidate_frame = old_m_candidate_frame;321}322 323bool UnwindLLDB::AddOneMoreFrame(ABI *abi) {324  Log *log = GetLog(LLDBLog::Unwind);325 326  // Frame zero is a little different327  if (m_frames.empty())328    return false;329 330  // If we've already gotten to the end of the stack, don't bother to try331  // again...332  if (m_unwind_complete)333    return false;334 335  CursorSP new_frame = m_candidate_frame;336  if (new_frame == nullptr)337    new_frame = GetOneMoreFrame(abi);338 339  if (new_frame == nullptr) {340    LLDB_LOGF(log, "th%d Unwind of this thread is complete.",341              m_thread.GetIndexID());342    m_unwind_complete = true;343    return false;344  }345 346  m_frames.push_back(new_frame);347 348  // If we can get one more frame further then accept that we get back a349  // correct frame.350  m_candidate_frame = GetOneMoreFrame(abi);351  if (m_candidate_frame)352    return true;353 354  // We can't go further from the frame returned by GetOneMore frame. Lets try355  // to get a different frame with using the fallback unwind plan.356  if (!m_frames[m_frames.size() - 2]357           ->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {358    // We don't have a valid fallback unwind plan. Accept the frame as it is.359    // This is a valid situation when we are at the bottom of the stack.360    return true;361  }362 363  // Remove the possibly incorrect frame from the frame list and try to add a364  // different one with the newly selected fallback unwind plan.365  m_frames.pop_back();366  CursorSP new_frame_v2 = GetOneMoreFrame(abi);367  if (new_frame_v2 == nullptr) {368    // We haven't got a new frame from the fallback unwind plan. Accept the369    // frame from the original unwind plan. This is a valid situation when we370    // are at the bottom of the stack.371    m_frames.push_back(new_frame);372    return true;373  }374 375  // Push the new frame to the list and try to continue from this frame. If we376  // can get a new frame then accept it as the correct one.377  m_frames.push_back(new_frame_v2);378  m_candidate_frame = GetOneMoreFrame(abi);379  if (m_candidate_frame) {380    // If control reached here then TryFallbackUnwindPlan had succeeded for381    // Cursor::m_frames[m_frames.size() - 2]. It also succeeded to Unwind next382    // 2 frames i.e. m_frames[m_frames.size() - 1] and a frame after that. For383    // Cursor::m_frames[m_frames.size() - 2], reg_ctx_lldb_sp field was already384    // updated during TryFallbackUnwindPlan call above. However, cfa field385    // still needs to be updated. Hence updating it here and then returning.386    return m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA(387        m_frames[m_frames.size() - 2]->cfa);388  }389 390  // The new frame hasn't helped in unwinding. Fall back to the original one as391  // the default unwind plan is usually more reliable then the fallback one.392  m_frames.pop_back();393  m_frames.push_back(new_frame);394  return true;395}396 397bool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc,398                                       bool &behaves_like_zeroth_frame) {399  if (m_frames.size() == 0) {400    if (!AddFirstFrame())401      return false;402  }403 404  ProcessSP process_sp(m_thread.GetProcess());405  ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;406 407  while (idx >= m_frames.size() && AddOneMoreFrame(abi))408    ;409 410  if (idx < m_frames.size()) {411    cfa = m_frames[idx]->cfa;412    pc = m_frames[idx]->start_pc;413    if (idx == 0) {414      // Frame zero always behaves like it.415      behaves_like_zeroth_frame = true;416    } else if (m_frames[idx - 1]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) {417      // This could be an asynchronous signal, thus the418      // pc might point to the interrupted instruction rather419      // than a post-call instruction420      behaves_like_zeroth_frame = true;421    } else if (m_frames[idx]->reg_ctx_lldb_sp->IsTrapHandlerFrame()) {422      // This frame may result from signal processing installing423      // a pointer to the first byte of a signal-return trampoline424      // in the return address slot of the frame below, so this425      // too behaves like the zeroth frame (i.e. the pc might not426      // be pointing just past a call in it)427      behaves_like_zeroth_frame = true;428    } else if (m_frames[idx]->reg_ctx_lldb_sp->BehavesLikeZerothFrame()) {429      behaves_like_zeroth_frame = true;430    } else {431      behaves_like_zeroth_frame = false;432    }433    return true;434  }435  return false;436}437 438lldb::RegisterContextSP439UnwindLLDB::DoCreateRegisterContextForFrame(StackFrame *frame) {440  lldb::RegisterContextSP reg_ctx_sp;441  uint32_t idx = frame->GetConcreteFrameIndex();442 443  if (idx == 0) {444    return m_thread.GetRegisterContext();445  }446 447  if (m_frames.size() == 0) {448    if (!AddFirstFrame())449      return reg_ctx_sp;450  }451 452  ProcessSP process_sp(m_thread.GetProcess());453  ABI *abi = process_sp ? process_sp->GetABI().get() : nullptr;454 455  while (idx >= m_frames.size()) {456    if (!AddOneMoreFrame(abi))457      break;458  }459 460  const uint32_t num_frames = m_frames.size();461  if (idx < num_frames) {462    Cursor *frame_cursor = m_frames[idx].get();463    reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp;464  }465  return reg_ctx_sp;466}467 468UnwindLLDB::RegisterContextLLDBSP469UnwindLLDB::GetRegisterContextForFrameNum(uint32_t frame_num) {470  RegisterContextLLDBSP reg_ctx_sp;471  if (frame_num < m_frames.size())472    reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp;473  return reg_ctx_sp;474}475 476bool UnwindLLDB::SearchForSavedLocationForRegister(477    uint32_t lldb_regnum,478    lldb_private::UnwindLLDB::ConcreteRegisterLocation &regloc,479    uint32_t starting_frame_num, bool pc_reg) {480  int64_t frame_num = starting_frame_num;481  if (static_cast<size_t>(frame_num) >= m_frames.size())482    return false;483 484  // Never interrogate more than one level while looking for the saved pc485  // value. If the value isn't saved by frame_num, none of the frames lower on486  // the stack will have a useful value.487  if (pc_reg) {488    UnwindLLDB::RegisterSearchResult result;489    result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister(490        lldb_regnum, regloc);491    return result == UnwindLLDB::RegisterSearchResult::eRegisterFound;492  }493  while (frame_num >= 0) {494    UnwindLLDB::RegisterSearchResult result;495    result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister(496        lldb_regnum, regloc);497 498    // We descended down to the live register context aka stack frame 0 and are499    // reading the value out of a live register.500    if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound &&501        regloc.type == UnwindLLDB::ConcreteRegisterLocation::502                           eRegisterInLiveRegisterContext) {503      return true;504    }505 506    // If we have unwind instructions saying that register N is saved in507    // register M in the middle of the stack (and N can equal M here, meaning508    // the register was not used in this function), then change the register509    // number we're looking for to M and keep looking for a concrete  location510    // down the stack, or an actual value from a live RegisterContext at frame511    // 0.512    if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound &&513        regloc.type ==514            UnwindLLDB::ConcreteRegisterLocation::eRegisterInRegister &&515        frame_num > 0) {516      result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound;517      lldb_regnum = regloc.location.register_number;518    }519 520    if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)521      return true;522    if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile)523      return false;524    frame_num--;525  }526  return false;527}528