[Lldb-commits] [lldb] r237239 - Remote Non-Stop Support
Ewan Crawford
ewan at codeplay.com
Wed May 13 02:18:19 PDT 2015
Author: ewancrawford
Date: Wed May 13 04:18:18 2015
New Revision: 237239
URL: http://llvm.org/viewvc/llvm-project?rev=237239&view=rev
Log:
Remote Non-Stop Support
Summary:
This patch is the beginnings of support for Non-stop mode in the remote protocol. Letting a user examine stopped threads, while other threads execute freely.
Non-stop mode is enabled using the setting target.non-stop-mode, which sends a QNonStop packet when establishing the remote connection.
Changes are also made to treat the '?' stop reply packet differently in non-stop mode, according to spec https://sourceware.org/gdb/current/onlinedocs/gdb/Remote-Non_002dStop.html#Remote-Non_002dStop.
A setting for querying the remote for default thread on setup is also included.
Handling of '%' async notification packets will be added next.
Reviewers: clayborg
Subscribers: lldb-commits, ADodds, ted, deepak2427
Differential Revision: http://reviews.llvm.org/D9656
Modified:
lldb/trunk/include/lldb/Target/Target.h
lldb/trunk/source/Commands/CommandObjectThread.cpp
lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
lldb/trunk/source/Target/Target.cpp
lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp
lldb/trunk/source/Utility/StringExtractorGDBRemote.h
Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=237239&r1=237238&r2=237239&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Wed May 13 04:18:18 2015
@@ -189,6 +189,9 @@ public:
void
SetUserSpecifiedTrapHandlerNames (const Args &args);
+
+ bool
+ GetNonStopModeEnabled () const;
bool
GetDisplayRuntimeSupportValues () const;
Modified: lldb/trunk/source/Commands/CommandObjectThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectThread.cpp?rev=237239&r1=237238&r2=237239&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectThread.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectThread.cpp Wed May 13 04:18:18 2015
@@ -433,6 +433,12 @@ public:
m_step_in_avoid_no_debug = eLazyBoolCalculate;
m_step_out_avoid_no_debug = eLazyBoolCalculate;
m_run_mode = eOnlyDuringStepping;
+
+ // Check if we are in Non-Stop mode
+ lldb::TargetSP target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
+ if (target_sp.get() != nullptr && target_sp->GetNonStopModeEnabled())
+ m_run_mode = eOnlyThisThread;
+
m_avoid_regexp.clear();
m_step_in_target.clear();
m_class_name.clear();
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp?rev=237239&r1=237238&r2=237239&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Wed May 13 04:18:18 2015
@@ -424,6 +424,7 @@ GDBRemoteCommunication::CheckForPacket (
content_length = total_length = 1; // The command is one byte long...
break;
+ case '%': // Async notify packet
case '$':
// Look for a standard gdb packet?
{
@@ -466,6 +467,7 @@ GDBRemoteCommunication::CheckForPacket (
case '+':
case '-':
case '\x03':
+ case '%':
case '$':
done = true;
break;
@@ -586,7 +588,7 @@ GDBRemoteCommunication::CheckForPacket (
}
}
- if (m_bytes[0] == '$')
+ if (m_bytes[0] == '$' || m_bytes[0] == '%')
{
assert (checksum_idx < m_bytes.size());
if (::isxdigit (m_bytes[checksum_idx+0]) ||
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=237239&r1=237238&r2=237239&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Wed May 13 04:18:18 2015
@@ -1621,6 +1621,22 @@ GDBRemoteCommunicationClient::GetGDBServ
}
bool
+GDBRemoteCommunicationClient::GetDefaultThreadId (lldb::tid_t &tid)
+{
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qC",response,false) != PacketResult::Success)
+ return false;
+
+ if (!response.IsNormalResponse())
+ return false;
+
+ if (response.GetChar() == 'Q' && response.GetChar() == 'C')
+ tid = response.GetHexMaxU32(true, -1);
+
+ return true;
+}
+
+bool
GDBRemoteCommunicationClient::GetHostInfo (bool force)
{
Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS));
@@ -2759,6 +2775,25 @@ GDBRemoteCommunicationClient::GetGroupNa
return false;
}
+bool
+GDBRemoteCommunicationClient::SetNonStopMode (const bool enable)
+{
+ // Form non-stop packet request
+ char packet[32];
+ const int packet_len = ::snprintf(packet, sizeof(packet), "QNonStop:%1d", (int)enable);
+ assert(packet_len < (int)sizeof(packet));
+
+ StringExtractorGDBRemote response;
+ // Send to target
+ if (SendPacketAndWaitForResponse(packet, packet_len, response, false) == PacketResult::Success)
+ if (response.IsOKResponse())
+ return true;
+
+ // Failed or not supported
+ return false;
+
+}
+
void
GDBRemoteCommunicationClient::TestPacketSpeed (const uint32_t num_packets)
{
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h?rev=237239&r1=237238&r2=237239&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Wed May 13 04:18:18 2015
@@ -318,6 +318,9 @@ public:
bool
GetHostInfo (bool force = false);
+
+ bool
+ GetDefaultThreadId (lldb::tid_t &tid);
bool
GetOSVersion (uint32_t &major,
@@ -393,6 +396,9 @@ public:
lldb::addr_t addr, // Address of breakpoint or watchpoint
uint32_t length); // Byte Size of breakpoint or watchpoint
+ bool
+ SetNonStopMode (const bool enable);
+
void
TestPacketSpeed (const uint32_t num_packets);
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=237239&r1=237238&r2=237239&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Wed May 13 04:18:18 2015
@@ -391,7 +391,8 @@ ProcessGDBRemote::ProcessGDBRemote(Targe
m_waiting_for_attach (false),
m_destroy_tried_resuming (false),
m_command_sp (),
- m_breakpoint_pc_offset (0)
+ m_breakpoint_pc_offset (0),
+ m_initial_tid (LLDB_INVALID_THREAD_ID)
{
m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue");
@@ -769,8 +770,13 @@ ProcessGDBRemote::DoConnectRemote (Strea
// We have a valid process
SetID (pid);
GetThreadList();
- if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, m_last_stop_packet, false) == GDBRemoteCommunication::PacketResult::Success)
+ if (m_gdb_comm.GetStopReply(m_last_stop_packet))
{
+
+ // '?' Packets must be handled differently in non-stop mode
+ if (GetTarget().GetNonStopModeEnabled())
+ HandleStopReplySequence();
+
if (!m_target.GetArchitecture().IsValid())
{
if (m_gdb_comm.GetProcessArchitecture().IsValid())
@@ -1052,8 +1058,13 @@ ProcessGDBRemote::DoLaunch (Module *exe_
return error;
}
- if (m_gdb_comm.SendPacketAndWaitForResponse("?", 1, m_last_stop_packet, false) == GDBRemoteCommunication::PacketResult::Success)
+ if (m_gdb_comm.GetStopReply(m_last_stop_packet))
{
+
+ // '?' Packets must be handled differently in non-stop mode
+ if (GetTarget().GetNonStopModeEnabled())
+ HandleStopReplySequence();
+
const ArchSpec &process_arch = m_gdb_comm.GetProcessArchitecture();
if (process_arch.IsValid())
@@ -1153,12 +1164,22 @@ ProcessGDBRemote::ConnectToDebugserver (
error.SetErrorString("not connected to remote gdb server");
return error;
}
+
+ // Send $QNonStop:1 packet on startup if required
+ if (GetTarget().GetNonStopModeEnabled())
+ m_gdb_comm.SetNonStopMode(true);
+
m_gdb_comm.GetThreadSuffixSupported ();
m_gdb_comm.GetListThreadsInStopReplySupported ();
m_gdb_comm.GetHostInfo ();
m_gdb_comm.GetVContSupported ('c');
m_gdb_comm.GetVAttachOrWaitSupported();
-
+
+ // Ask the remote server for the default thread id
+ if (GetTarget().GetNonStopModeEnabled())
+ m_gdb_comm.GetDefaultThreadId(m_initial_tid);
+
+
size_t num_cmds = GetExtraStartupCommands().GetArgumentCount();
for (size_t idx = 0; idx < num_cmds; idx++)
{
@@ -1430,11 +1451,12 @@ ProcessGDBRemote::DoResume ()
bool continue_packet_error = false;
if (m_gdb_comm.HasAnyVContSupport ())
{
- if (m_continue_c_tids.size() == num_threads ||
+ if (!GetTarget().GetNonStopModeEnabled() &&
+ (m_continue_c_tids.size() == num_threads ||
(m_continue_c_tids.empty() &&
m_continue_C_tids.empty() &&
m_continue_s_tids.empty() &&
- m_continue_S_tids.empty()))
+ m_continue_S_tids.empty())))
{
// All threads are continuing, just send a "c" packet
continue_packet.PutCString ("c");
@@ -1662,6 +1684,27 @@ ProcessGDBRemote::DoResume ()
}
void
+ProcessGDBRemote::HandleStopReplySequence ()
+{
+ while(true)
+ {
+ // Send vStopped
+ StringExtractorGDBRemote response;
+ m_gdb_comm.SendPacketAndWaitForResponse("vStopped", response, false);
+
+ // OK represents end of signal list
+ if (response.IsOKResponse())
+ break;
+
+ // If not OK or a normal packet we have a problem
+ if (!response.IsNormalResponse())
+ break;
+
+ SetLastStopPacket(response);
+ }
+}
+
+void
ProcessGDBRemote::ClearThreadIDList ()
{
Mutex::Locker locker(m_thread_list_real.GetMutex());
@@ -2095,6 +2138,13 @@ ProcessGDBRemote::RefreshStateAfterStop
UpdateThreadIDList();
}
+ // If we have queried for a default thread id
+ if (m_initial_tid != LLDB_INVALID_THREAD_ID)
+ {
+ m_thread_list.SetSelectedThreadByID(m_initial_tid);
+ m_initial_tid = LLDB_INVALID_THREAD_ID;
+ }
+
// Let all threads recover from stopping and do any clean up based
// on the previous thread state (if any).
m_thread_list_real.RefreshStateAfterStop();
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=237239&r1=237238&r2=237239&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Wed May 13 04:18:18 2015
@@ -358,6 +358,7 @@ protected:
bool m_destroy_tried_resuming;
lldb::CommandObjectSP m_command_sp;
int64_t m_breakpoint_pc_offset;
+ lldb::tid_t m_initial_tid; // The inital thread ID, given by stub on attach
bool
StartAsyncThread ();
@@ -379,6 +380,9 @@ protected:
SetThreadStopInfo (StringExtractor& stop_packet);
void
+ HandleStopReplySequence ();
+
+ void
ClearThreadIDList ();
bool
Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=237239&r1=237238&r2=237239&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Wed May 13 04:18:18 2015
@@ -2978,6 +2978,7 @@ g_properties[] =
{ "display-expression-in-crashlogs" , OptionValue::eTypeBoolean , false, false, NULL, NULL, "Expressions that crash will show up in crash logs if the host system supports executable specific crash log strings and this setting is set to true." },
{ "trap-handler-names" , OptionValue::eTypeArray , true, OptionValue::eTypeString, NULL, NULL, "A list of trap handler function names, e.g. a common Unix user process one is _sigtramp." },
{ "display-runtime-support-values" , OptionValue::eTypeBoolean , false, false, NULL, NULL, "If true, LLDB will show variables that are meant to support the operation of a language's runtime support." },
+ { "non-stop-mode" , OptionValue::eTypeBoolean , false, 0, NULL, NULL, "Disable lock-step debugging, instead control threads independently." },
{ NULL , OptionValue::eTypeInvalid , false, 0 , NULL, NULL, NULL }
};
@@ -3016,7 +3017,8 @@ enum
ePropertyMemoryModuleLoadLevel,
ePropertyDisplayExpressionsInCrashlogs,
ePropertyTrapHandlerNames,
- ePropertyDisplayRuntimeSupportValues
+ ePropertyDisplayRuntimeSupportValues,
+ ePropertyNonStopModeEnabled
};
@@ -3515,6 +3517,13 @@ TargetProperties::SetDisplayRuntimeSuppo
m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b);
}
+bool
+TargetProperties::GetNonStopModeEnabled () const
+{
+ const uint32_t idx = ePropertyNonStopModeEnabled;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, false);
+}
+
const ProcessLaunchInfo &
TargetProperties::GetProcessLaunchInfo ()
{
Modified: lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp?rev=237239&r1=237238&r2=237239&view=diff
==============================================================================
--- lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp (original)
+++ lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp Wed May 13 04:18:18 2015
@@ -64,6 +64,10 @@ StringExtractorGDBRemote::GetServerPacke
const char *packet_cstr = m_packet.c_str();
switch (m_packet[0])
{
+
+ case '%':
+ return eServerPacketType_notify;
+
case '\x03':
if (packet_size == 1) return eServerPacketType_interrupt;
break;
Modified: lldb/trunk/source/Utility/StringExtractorGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/StringExtractorGDBRemote.h?rev=237239&r1=237238&r2=237239&view=diff
==============================================================================
--- lldb/trunk/source/Utility/StringExtractorGDBRemote.h (original)
+++ lldb/trunk/source/Utility/StringExtractorGDBRemote.h Wed May 13 04:18:18 2015
@@ -145,6 +145,7 @@ public:
eServerPacketType__M,
eServerPacketType__m,
+ eServerPacketType_notify, // '%' notification
};
ServerPacketType
More information about the lldb-commits
mailing list