diff options
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp')
| -rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index 091feb9e649..b8108bfd383 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -37,7 +37,8 @@ ThreadGDBRemote::ThreadGDBRemote (ProcessGDBRemote &process, lldb::tid_t tid) : Thread(process, tid), m_thread_name (), m_dispatch_queue_name (), - m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS) + m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS), + m_thread_stop_reason_stop_id (0) { // ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD | GDBR_LOG_VERBOSE, "ThreadGDBRemote::ThreadGDBRemote ( pid = %i, tid = 0x%4.4x, )", m_process.GetID(), GetID()); ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID()); @@ -116,14 +117,18 @@ ThreadGDBRemote::WillResume (StateType resume_state) void ThreadGDBRemote::RefreshStateAfterStop() { - // Invalidate all registers in our register context - GetRegisterContext()->Invalidate(); + // Invalidate all registers in our register context. We don't set "force" to + // true because the stop reply packet might have had some register values + // that were expedited and these will already be copied into the register + // context by the time this function gets called. The GDBRemoteRegisterContext + // class has been made smart enough to detect when it needs to invalidate + // which registers are valid by putting hooks in the register read and + // register supply functions where they check the process stop ID and do + // the right thing. + const bool force = false; + GetRegisterContext()->InvalidateIfNeeded (force); } -// Whether to use the new native unwinder (UnwindLLDB) or the libunwind-remote based unwinder for -// stack walks on i386/x86_64 -#define USE_NATIVE_UNWINDER - Unwind * ThreadGDBRemote::GetUnwinder () { @@ -132,11 +137,7 @@ ThreadGDBRemote::GetUnwinder () const ArchSpec target_arch (GetProcess().GetTarget().GetArchitecture ()); if (target_arch == ArchSpec("x86_64") || target_arch == ArchSpec("i386")) { -#if defined (USE_NATIVE_UNWINDER) m_unwinder_ap.reset (new UnwindLLDB (*this)); -#else - m_unwinder_ap.reset (new UnwindLibUnwind (*this, GetGDBProcess().GetLibUnwindAddressSpace())); -#endif } else { @@ -198,6 +199,14 @@ ThreadGDBRemote::CreateRegisterContextForFrame (StackFrame *frame) return reg_ctx_sp; } +void +ThreadGDBRemote::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response) +{ + GDBRemoteRegisterContext *gdb_reg_ctx = static_cast<GDBRemoteRegisterContext *>(GetRegisterContext ().get()); + assert (gdb_reg_ctx); + gdb_reg_ctx->PrivateSetRegisterValue (reg, response); +} + bool ThreadGDBRemote::SaveFrameZeroState (RegisterCheckpoint &checkpoint) { @@ -217,7 +226,7 @@ ThreadGDBRemote::RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint) if (frame_sp) { bool ret = frame_sp->GetRegisterContext()->WriteAllRegisterValues (checkpoint.GetData()); - frame_sp->GetRegisterContext()->Invalidate(); + frame_sp->GetRegisterContext()->InvalidateIfNeeded(true); ClearStackFrames(); return ret; } @@ -227,8 +236,19 @@ ThreadGDBRemote::RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint) lldb::StopInfoSP ThreadGDBRemote::GetPrivateStopReason () { - if (m_actual_stop_info_sp.get() == NULL || m_actual_stop_info_sp->IsValid() == false) + const uint32_t process_stop_id = GetProcess().GetStopID(); + if (m_thread_stop_reason_stop_id != process_stop_id || + (m_actual_stop_info_sp && !m_actual_stop_info_sp->IsValid())) { + // If GetGDBProcess().SetThreadStopInfo() doesn't find a stop reason + // for this thread, then m_actual_stop_info_sp will not ever contain + // a valid stop reason and the "m_actual_stop_info_sp->IsValid() == false" + // check will never be able to tell us if we have the correct stop info + // for this thread and we will continually send qThreadStopInfo packets + // down to the remote GDB server, so we need to keep our own notion + // of the stop ID that m_actual_stop_info_sp is valid for (even if it + // contains nothing). We use m_thread_stop_reason_stop_id for this below. + m_thread_stop_reason_stop_id = process_stop_id; m_actual_stop_info_sp.reset(); char packet[256]; @@ -236,7 +256,6 @@ ThreadGDBRemote::GetPrivateStopReason () StringExtractorGDBRemote stop_packet; if (GetGDBProcess().GetGDBRemote().SendPacketAndWaitForResponse(packet, stop_packet, 1, false)) { - std::string copy(stop_packet.GetStringRef()); GetGDBProcess().SetThreadStopInfo (stop_packet); } } |

