summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp47
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);
}
}
OpenPOWER on IntegriCloud