diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-09-06 14:32:30 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-09-06 14:32:30 +0000 | 
| commit | 027f1c9655391dcb2b0117f931f720211ac933db (patch) | |
| tree | 94980f450aa3daec3e1fec217374704ad62cfe45 /source/Plugins/Process/Utility | |
| parent | 5e95aa85bb660d45e9905ef1d7180b2678280660 (diff) | |
Notes
Diffstat (limited to 'source/Plugins/Process/Utility')
| -rw-r--r-- | source/Plugins/Process/Utility/FreeBSDSignals.cpp | 2 | ||||
| -rw-r--r-- | source/Plugins/Process/Utility/FreeBSDSignals.h | 9 | ||||
| -rw-r--r-- | source/Plugins/Process/Utility/GDBRemoteSignals.cpp | 32 | ||||
| -rw-r--r-- | source/Plugins/Process/Utility/GDBRemoteSignals.h | 36 | ||||
| -rw-r--r-- | source/Plugins/Process/Utility/LinuxSignals.cpp | 2 | ||||
| -rw-r--r-- | source/Plugins/Process/Utility/LinuxSignals.h | 23 | ||||
| -rw-r--r-- | source/Plugins/Process/Utility/MipsLinuxSignals.cpp | 2 | ||||
| -rw-r--r-- | source/Plugins/Process/Utility/MipsLinuxSignals.h | 23 | ||||
| -rw-r--r-- | source/Plugins/Process/Utility/UnwindLLDB.cpp | 176 | ||||
| -rw-r--r-- | source/Plugins/Process/Utility/UnwindLLDB.h | 12 | 
10 files changed, 214 insertions, 103 deletions
diff --git a/source/Plugins/Process/Utility/FreeBSDSignals.cpp b/source/Plugins/Process/Utility/FreeBSDSignals.cpp index f082e143059c9..c143d36e87c75 100644 --- a/source/Plugins/Process/Utility/FreeBSDSignals.cpp +++ b/source/Plugins/Process/Utility/FreeBSDSignals.cpp @@ -13,6 +13,8 @@  // Project includes  #include "FreeBSDSignals.h" +using namespace lldb_private; +  FreeBSDSignals::FreeBSDSignals()      : UnixSignals()  { diff --git a/source/Plugins/Process/Utility/FreeBSDSignals.h b/source/Plugins/Process/Utility/FreeBSDSignals.h index 1e14ccb9fc4d2..b715c62c81e9e 100644 --- a/source/Plugins/Process/Utility/FreeBSDSignals.h +++ b/source/Plugins/Process/Utility/FreeBSDSignals.h @@ -13,16 +13,19 @@  // Project includes  #include "lldb/Target/UnixSignals.h" +namespace lldb_private { +  /// FreeBSD specific set of Unix signals. -class FreeBSDSignals -    : public lldb_private::UnixSignals +class FreeBSDSignals : public UnixSignals  {  public:      FreeBSDSignals();  private:      void -    Reset(); +    Reset() override;  }; +} // namespace lldb_private +  #endif // liblldb_FreeBSDSignals_H_ diff --git a/source/Plugins/Process/Utility/GDBRemoteSignals.cpp b/source/Plugins/Process/Utility/GDBRemoteSignals.cpp new file mode 100644 index 0000000000000..4e355c63b3aa2 --- /dev/null +++ b/source/Plugins/Process/Utility/GDBRemoteSignals.cpp @@ -0,0 +1,32 @@ +//===-- GDBRemoteSignals.cpp ------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "GDBRemoteSignals.h" + +using namespace lldb_private; + +GDBRemoteSignals::GDBRemoteSignals() +    : UnixSignals() +{ +    Reset(); +} + +GDBRemoteSignals::GDBRemoteSignals(const lldb::UnixSignalsSP &rhs) +    : UnixSignals(*rhs) +{ +} + +void +GDBRemoteSignals::Reset() +{ +    m_signals.clear(); +} diff --git a/source/Plugins/Process/Utility/GDBRemoteSignals.h b/source/Plugins/Process/Utility/GDBRemoteSignals.h new file mode 100644 index 0000000000000..bbb631a14090e --- /dev/null +++ b/source/Plugins/Process/Utility/GDBRemoteSignals.h @@ -0,0 +1,36 @@ +//===-- GDBRemoteSignals.h --------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_GDBRemoteSignals_H_ +#define liblldb_GDBRemoteSignals_H_ + +// C Includes +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Target/UnixSignals.h" + +namespace lldb_private { + +/// Empty set of Unix signals to be filled by PlatformRemoteGDBServer +class GDBRemoteSignals : public UnixSignals +{ +public: +    GDBRemoteSignals(); + +    GDBRemoteSignals(const lldb::UnixSignalsSP &rhs); + +private: +    void +    Reset() override; +}; + +} // namespace lldb_private + +#endif // liblldb_GDBRemoteSignals_H_ diff --git a/source/Plugins/Process/Utility/LinuxSignals.cpp b/source/Plugins/Process/Utility/LinuxSignals.cpp index 0680d268233c1..cd1fc8165eb9c 100644 --- a/source/Plugins/Process/Utility/LinuxSignals.cpp +++ b/source/Plugins/Process/Utility/LinuxSignals.cpp @@ -12,7 +12,7 @@  // Project includes  #include "LinuxSignals.h" -using namespace lldb_private::process_linux; +using namespace lldb_private;  LinuxSignals::LinuxSignals()      : UnixSignals() diff --git a/source/Plugins/Process/Utility/LinuxSignals.h b/source/Plugins/Process/Utility/LinuxSignals.h index 5102bcb95e74b..dd9062f040a22 100644 --- a/source/Plugins/Process/Utility/LinuxSignals.h +++ b/source/Plugins/Process/Utility/LinuxSignals.h @@ -17,21 +17,18 @@  #include "lldb/Target/UnixSignals.h"  namespace lldb_private { -namespace process_linux { -    /// Linux specific set of Unix signals. -    class LinuxSignals -        : public lldb_private::UnixSignals -    { -    public: -        LinuxSignals(); +/// Linux specific set of Unix signals. +class LinuxSignals : public UnixSignals +{ +public: +    LinuxSignals(); -    private: -        void -        Reset(); -    }; +private: +    void +    Reset() override; +};  } // namespace lldb_private -} // namespace process_linux -#endif +#endif // liblldb_LinuxSignals_H_ diff --git a/source/Plugins/Process/Utility/MipsLinuxSignals.cpp b/source/Plugins/Process/Utility/MipsLinuxSignals.cpp index e4e654626eaac..1dc0be81c0aee 100644 --- a/source/Plugins/Process/Utility/MipsLinuxSignals.cpp +++ b/source/Plugins/Process/Utility/MipsLinuxSignals.cpp @@ -12,7 +12,7 @@  // Project includes  #include "MipsLinuxSignals.h" -using namespace lldb_private::process_linux; +using namespace lldb_private;  MipsLinuxSignals::MipsLinuxSignals()      : UnixSignals() diff --git a/source/Plugins/Process/Utility/MipsLinuxSignals.h b/source/Plugins/Process/Utility/MipsLinuxSignals.h index 2e603fbbdf3c7..a5041b50eea39 100644 --- a/source/Plugins/Process/Utility/MipsLinuxSignals.h +++ b/source/Plugins/Process/Utility/MipsLinuxSignals.h @@ -17,21 +17,18 @@  #include "lldb/Target/UnixSignals.h"  namespace lldb_private { -namespace process_linux { -    /// Linux specific set of Unix signals. -    class MipsLinuxSignals -        : public lldb_private::UnixSignals -    { -    public: -        MipsLinuxSignals(); +/// Linux specific set of Unix signals. +class MipsLinuxSignals : public UnixSignals +{ +public: +    MipsLinuxSignals(); -    private: -        void -        Reset(); -    }; +private: +    void +    Reset() override; +};  } // namespace lldb_private -} // namespace process_linux -#endif +#endif // liblldb_MipsLinuxSignals_H_ diff --git a/source/Plugins/Process/Utility/UnwindLLDB.cpp b/source/Plugins/Process/Utility/UnwindLLDB.cpp index 02d3ecd7b3c51..1cdae9011673b 100644 --- a/source/Plugins/Process/Utility/UnwindLLDB.cpp +++ b/source/Plugins/Process/Utility/UnwindLLDB.cpp @@ -120,29 +120,28 @@ unwind_done:      return false;  } -// For adding a non-zero stack frame to m_frames. -bool -UnwindLLDB::AddOneMoreFrame (ABI *abi) +UnwindLLDB::CursorSP +UnwindLLDB::GetOneMoreFrame (ABI* abi)  { +    assert (m_frames.size() != 0 && "Get one more frame called with empty frame list"); +      // If we've already gotten to the end of the stack, don't bother to try again...      if (m_unwind_complete) -        return false; +        return nullptr;      Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); -    CursorSP cursor_sp(new Cursor ()); -    // Frame zero is a little different -    if (m_frames.size() == 0) -        return false; +    CursorSP prev_frame = m_frames.back(); +    uint32_t cur_idx = m_frames.size(); -    uint32_t cur_idx = m_frames.size (); +    CursorSP cursor_sp(new Cursor ());      RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB (m_thread,  -                                                              m_frames[cur_idx - 1]->reg_ctx_lldb_sp,  +                                                              prev_frame->reg_ctx_lldb_sp,                                                                 cursor_sp->sctx,                                                                 cur_idx,                                                                 *this)); -    // We want to detect an unwind that cycles erronously and stop backtracing. +    // We want to detect an unwind that cycles erroneously and stop backtracing.      // Don't want this maximum unwind limit to be too low -- if you have a backtrace      // with an "infinitely recursing" bug, it will crash when the stack blows out      // and the first 35,000 frames are uninteresting - it's the top most 5 frames that @@ -154,21 +153,20 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi)          if (log)              log->Printf ("%*sFrame %d unwound too many frames, assuming unwind has gone astray, stopping.",                            cur_idx < 100 ? cur_idx : 100, "", cur_idx); -        goto unwind_done; +        return nullptr;      }      if (reg_ctx_sp.get() == NULL)      {          // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return          // true.  Subsequent calls to TryFallbackUnwindPlan() will return false. -        if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) -        { -            return AddOneMoreFrame (abi); -        } +        if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) +            return GetOneMoreFrame (abi); +          if (log)              log->Printf ("%*sFrame %d did not get a RegisterContext, stopping.",                           cur_idx < 100 ? cur_idx : 100, "", cur_idx); -        goto unwind_done; +        return nullptr;      }      if (!reg_ctx_sp->IsValid()) @@ -176,31 +174,25 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi)          // We failed to get a valid RegisterContext.          // See if the regctx below this on the stack has a fallback unwind plan it can use.          // Subsequent calls to TryFallbackUnwindPlan() will return false. -        if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) -        { -            return AddOneMoreFrame (abi); -        } +        if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) +            return GetOneMoreFrame (abi); +          if (log) -        {              log->Printf("%*sFrame %d invalid RegisterContext for this frame, stopping stack walk",                           cur_idx < 100 ? cur_idx : 100, "", cur_idx); -        } -        goto unwind_done; +        return nullptr;      }      if (!reg_ctx_sp->GetCFA (cursor_sp->cfa))      {          // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return          // true.  Subsequent calls to TryFallbackUnwindPlan() will return false. -        if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) -        { -            return AddOneMoreFrame (abi); -        } +        if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) +            return GetOneMoreFrame (abi); +          if (log) -        {              log->Printf("%*sFrame %d did not get CFA for this frame, stopping stack walk",                          cur_idx < 100 ? cur_idx : 100, "", cur_idx); -        } -        goto unwind_done; +        return nullptr;      }      if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa))      { @@ -219,24 +211,19 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi)                  || reg_ctx_sp->GetCFA (cursor_sp->cfa) == false                  || abi->CallFrameAddressIsValid(cursor_sp->cfa) == false)              { -                if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) -                { -                    return AddOneMoreFrame (abi); -                } +                if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) +                    return GetOneMoreFrame (abi); +                  if (log) -                {                      log->Printf("%*sFrame %d did not get a valid CFA for this frame, stopping stack walk",                                  cur_idx < 100 ? cur_idx : 100, "", cur_idx); -                } -                goto unwind_done; +                return nullptr;              }              else              {                  if (log) -                {                      log->Printf("%*sFrame %d had a bad CFA value but we switched the UnwindPlan being used and got one that looks more realistic.",                                  cur_idx < 100 ? cur_idx : 100, "", cur_idx); -                }              }          }      } @@ -244,54 +231,103 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi)      {          // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return          // true.  Subsequent calls to TryFallbackUnwindPlan() will return false. -        if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) -        { -            return AddOneMoreFrame (abi); -        } +        if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) +            return GetOneMoreFrame (abi); +          if (log) -        {              log->Printf("%*sFrame %d did not get PC for this frame, stopping stack walk",                          cur_idx < 100 ? cur_idx : 100, "", cur_idx); -        } -        goto unwind_done; +        return nullptr;      }      if (abi && !abi->CodeAddressIsValid (cursor_sp->start_pc))      {          // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to that and return          // true.  Subsequent calls to TryFallbackUnwindPlan() will return false. -        if (m_frames[cur_idx - 1]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) -        { -            return AddOneMoreFrame (abi); -        } +        if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) +            return GetOneMoreFrame (abi); +          if (log) -        {              log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk",                          cur_idx < 100 ? cur_idx : 100, "", cur_idx); -        } -        goto unwind_done; +        return nullptr;      } -    if (!m_frames.empty()) +    // Infinite loop where the current cursor is the same as the previous one... +    if (prev_frame->start_pc == cursor_sp->start_pc && prev_frame->cfa == cursor_sp->cfa)      { -        // Infinite loop where the current cursor is the same as the previous one... -        if (m_frames.back()->start_pc == cursor_sp->start_pc && m_frames.back()->cfa == cursor_sp->cfa) -        { -            if (log) -                log->Printf ("th%d pc of this frame is the same as the previous frame and CFAs for both frames are identical -- stopping unwind", m_thread.GetIndexID()); -            goto unwind_done;  -        } +        if (log) +            log->Printf ("th%d pc of this frame is the same as the previous frame and CFAs for both frames are identical -- stopping unwind", m_thread.GetIndexID()); +        return nullptr;      }      cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp; -    m_frames.push_back (cursor_sp); -    return true; -     -unwind_done: -    if (log) +    return cursor_sp; +} + +bool +UnwindLLDB::AddOneMoreFrame (ABI *abi) +{ +    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); + +    // Frame zero is a little different +    if (m_frames.empty()) +        return false; + +    // If we've already gotten to the end of the stack, don't bother to try again... +    if (m_unwind_complete) +        return false; + +    CursorSP new_frame = m_candidate_frame; +    if (new_frame == nullptr) +        new_frame = GetOneMoreFrame(abi); + +    if (new_frame == nullptr)      { -        log->Printf ("th%d Unwind of this thread is complete.", m_thread.GetIndexID()); +        if (log) +            log->Printf ("th%d Unwind of this thread is complete.", m_thread.GetIndexID()); +        m_unwind_complete = true; +        return false;      } -    m_unwind_complete = true; -    return false; + +    m_frames.push_back(new_frame); + +    // If we can get one more frame further then accept that we get back a correct frame. +    m_candidate_frame = GetOneMoreFrame(abi); +    if (m_candidate_frame) +        return true; + +    // We can't go further from the frame returned by GetOneMore frame. Lets try to get a +    // different frame with using the fallback unwind plan. +    if (!m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) +    { +        // We don't have a valid fallback unwind plan. Accept the frame as it is. This is a +        // valid situation when we are at the bottom of the stack. +        return true; +    } + +    // Remove the possibly incorrect frame from the frame list and try to add a different one with +    // the newly selected fallback unwind plan. +    m_frames.pop_back(); +    CursorSP new_frame_v2 = GetOneMoreFrame(abi); +    if (new_frame_v2 == nullptr) +    { +        // We haven't got a new frame from the fallback unwind plan. Accept the frame from the +        // original unwind plan. This is a valid situation when we are at the bottom of the stack. +        m_frames.push_back(new_frame); +        return true; +    } + +    // Push the new frame to the list and try to continue from this frame. If we can get a new frame +    // then accept it as the correct one. +    m_frames.push_back(new_frame_v2); +    m_candidate_frame = GetOneMoreFrame(abi); +    if (m_candidate_frame) +        return true; + +    // The new frame isn't helped in unwinding. Fall back to the original one as the default unwind +    // plan is usually more reliable then the fallback one. +    m_frames.pop_back(); +    m_frames.push_back(new_frame); +    return true;  }  bool diff --git a/source/Plugins/Process/Utility/UnwindLLDB.h b/source/Plugins/Process/Utility/UnwindLLDB.h index 35d85e2e3d26e..ce897cd82423c 100644 --- a/source/Plugins/Process/Utility/UnwindLLDB.h +++ b/source/Plugins/Process/Utility/UnwindLLDB.h @@ -65,6 +65,7 @@ protected:      DoClear()      {          m_frames.clear(); +        m_candidate_frame.reset();          m_unwind_complete = false;      } @@ -126,14 +127,21 @@ private:      typedef std::shared_ptr<Cursor> CursorSP;      std::vector<CursorSP> m_frames; +    CursorSP m_candidate_frame;      bool m_unwind_complete; // If this is true, we've enumerated all the frames in the stack, and m_frames.size() is the                               // number of frames, etc.  Otherwise we've only gone as far as directly asked, and m_frames.size()                              // is how far we've currently gone.      std::vector<ConstString> m_user_supplied_trap_handler_functions; -    bool AddOneMoreFrame (ABI *abi); -    bool AddFirstFrame (); +    CursorSP +    GetOneMoreFrame (ABI* abi); + +    bool +    AddOneMoreFrame (ABI *abi); + +    bool +    AddFirstFrame ();      //------------------------------------------------------------------      // For UnwindLLDB only  | 
