[Lldb-commits] [lldb] r128070 - in /lldb/trunk: lldb.xcodeproj/ source/Plugins/Process/gdb-remote/ source/Utility/ tools/lldb-platform/
Greg Clayton
gclayton at apple.com
Mon Mar 21 21:00:09 PDT 2011
Author: gclayton
Date: Mon Mar 21 23:00:09 2011
New Revision: 128070
URL: http://llvm.org/viewvc/llvm-project?rev=128070&view=rev
Log:
Split the GDBRemoteCommunication class into three classes:
GDBRemoteCommunication - The base GDB remote communication class
GDBRemoteCommunicationClient - designed to be used for clients the connect to
a remote GDB server
GDBRemoteCommunicationServer - designed to be used on the server side of a
GDB server implementation.
Added:
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/GDBRemoteCommunicationServer.cpp
lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
Modified:
lldb/trunk/lldb.xcodeproj/project.pbxproj
lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp
lldb/trunk/source/Utility/StringExtractorGDBRemote.h
lldb/trunk/tools/lldb-platform/lldb-platform.cpp
Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=128070&r1=128069&r2=128070&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Mon Mar 21 23:00:09 2011
@@ -56,6 +56,10 @@
26680336116005EF008E1FE4 /* SBBreakpointLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AF16CC7114086A1007A7B3F /* SBBreakpointLocation.cpp */; };
26680337116005F1008E1FE4 /* SBBreakpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9AF16A9C11402D5B007A7B3F /* SBBreakpoint.cpp */; };
2668035C11601108008E1FE4 /* LLDB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 26680207115FD0ED008E1FE4 /* LLDB.framework */; };
+ 26744EF11338317700EF765A /* GDBRemoteCommunicationClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26744EED1338317700EF765A /* GDBRemoteCommunicationClient.cpp */; };
+ 26744EF21338317700EF765A /* GDBRemoteCommunicationClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 26744EEE1338317700EF765A /* GDBRemoteCommunicationClient.h */; };
+ 26744EF31338317700EF765A /* GDBRemoteCommunicationServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26744EEF1338317700EF765A /* GDBRemoteCommunicationServer.cpp */; };
+ 26744EF41338317700EF765A /* GDBRemoteCommunicationServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 26744EF01338317700EF765A /* GDBRemoteCommunicationServer.h */; };
2689000013353DB600698AC0 /* BreakpointResolverAddress.h in Headers */ = {isa = PBXBuildFile; fileRef = 26D0DD5010FE554D00271C65 /* BreakpointResolverAddress.h */; };
2689000113353DB600698AC0 /* BreakpointResolverAddress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D0DD5310FE555900271C65 /* BreakpointResolverAddress.cpp */; };
2689000213353DB600698AC0 /* BreakpointResolverFileLine.h in Headers */ = {isa = PBXBuildFile; fileRef = 26D0DD5110FE554D00271C65 /* BreakpointResolverFileLine.h */; };
@@ -635,6 +639,10 @@
266F5CBB12FC846200DFCE33 /* Config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Config.h; path = include/lldb/Host/Config.h; sourceTree = "<group>"; };
2672D8461189055500FF4019 /* CommandObjectFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectFrame.cpp; path = source/Commands/CommandObjectFrame.cpp; sourceTree = "<group>"; };
2672D8471189055500FF4019 /* CommandObjectFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectFrame.h; path = source/Commands/CommandObjectFrame.h; sourceTree = "<group>"; };
+ 26744EED1338317700EF765A /* GDBRemoteCommunicationClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GDBRemoteCommunicationClient.cpp; sourceTree = "<group>"; };
+ 26744EEE1338317700EF765A /* GDBRemoteCommunicationClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDBRemoteCommunicationClient.h; sourceTree = "<group>"; };
+ 26744EEF1338317700EF765A /* GDBRemoteCommunicationServer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GDBRemoteCommunicationServer.cpp; sourceTree = "<group>"; };
+ 26744EF01338317700EF765A /* GDBRemoteCommunicationServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GDBRemoteCommunicationServer.h; sourceTree = "<group>"; };
2675F6FE1332BE690067997B /* PlatformRemoteiOS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformRemoteiOS.cpp; sourceTree = "<group>"; };
2675F6FF1332BE690067997B /* PlatformRemoteiOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformRemoteiOS.h; sourceTree = "<group>"; };
2676A093119C93C8008A98EF /* StringExtractorGDBRemote.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringExtractorGDBRemote.cpp; path = source/Utility/StringExtractorGDBRemote.cpp; sourceTree = "<group>"; };
@@ -2380,6 +2388,10 @@
children = (
2618EE5B1315B29C001D6D71 /* GDBRemoteCommunication.cpp */,
2618EE5C1315B29C001D6D71 /* GDBRemoteCommunication.h */,
+ 26744EED1338317700EF765A /* GDBRemoteCommunicationClient.cpp */,
+ 26744EEE1338317700EF765A /* GDBRemoteCommunicationClient.h */,
+ 26744EEF1338317700EF765A /* GDBRemoteCommunicationServer.cpp */,
+ 26744EF01338317700EF765A /* GDBRemoteCommunicationServer.h */,
2618EE5D1315B29C001D6D71 /* GDBRemoteRegisterContext.cpp */,
2618EE5E1315B29C001D6D71 /* GDBRemoteRegisterContext.h */,
2618EE5F1315B29C001D6D71 /* ProcessGDBRemote.cpp */,
@@ -2483,6 +2495,8 @@
2689000C13353DB600698AC0 /* StoppointCallbackContext.h in Headers */,
2689000E13353DB600698AC0 /* StoppointLocation.h in Headers */,
2689001013353DB600698AC0 /* WatchpointLocation.h in Headers */,
+ 26744EF21338317700EF765A /* GDBRemoteCommunicationClient.h in Headers */,
+ 26744EF41338317700EF765A /* GDBRemoteCommunicationServer.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3038,6 +3052,8 @@
2689011213353E8200698AC0 /* StringExtractorGDBRemote.cpp in Sources */,
2689011313353E8200698AC0 /* PseudoTerminal.cpp in Sources */,
26B1FCC21338115F002886E2 /* Host.mm in Sources */,
+ 26744EF11338317700EF765A /* GDBRemoteCommunicationClient.cpp in Sources */,
+ 26744EF31338317700EF765A /* GDBRemoteCommunicationServer.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
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=128070&r1=128069&r2=128070&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Mon Mar 21 23:00:09 2011
@@ -13,18 +13,11 @@
// C Includes
// C++ Includes
// Other libraries and framework includes
-#include "llvm/ADT/Triple.h"
-#include "lldb/Interpreter/Args.h"
-#include "lldb/Core/ConnectionFileDescriptor.h"
#include "lldb/Core/Log.h"
-#include "lldb/Core/State.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Host/Host.h"
#include "lldb/Host/TimeValue.h"
// Project includes
-#include "Utility/StringExtractorGDBRemote.h"
-#include "ProcessGDBRemote.h"
#include "ProcessGDBRemoteLog.h"
using namespace lldb;
@@ -33,32 +26,13 @@
//----------------------------------------------------------------------
// GDBRemoteCommunication constructor
//----------------------------------------------------------------------
-GDBRemoteCommunication::GDBRemoteCommunication() :
- Communication("gdb-remote.packets"),
+GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, const char *listener_name) :
+ Communication(comm_name),
m_packet_timeout (1),
- m_supports_not_sending_acks (eLazyBoolCalculate),
- m_supports_thread_suffix (eLazyBoolCalculate),
- m_supports_qHostInfo (eLazyBoolCalculate),
- m_supports_vCont_all (eLazyBoolCalculate),
- m_supports_vCont_any (eLazyBoolCalculate),
- m_supports_vCont_c (eLazyBoolCalculate),
- m_supports_vCont_C (eLazyBoolCalculate),
- m_supports_vCont_s (eLazyBoolCalculate),
- m_supports_vCont_S (eLazyBoolCalculate),
- m_rx_packet_listener ("gdbremote.rx_packet"),
+ m_rx_packet_listener (listener_name),
m_sequence_mutex (Mutex::eMutexTypeRecursive),
m_public_is_running (false),
- m_private_is_running (false),
- m_async_mutex (Mutex::eMutexTypeRecursive),
- m_async_packet_predicate (false),
- m_async_packet (),
- m_async_response (),
- m_async_signal (-1),
- m_arch(),
- m_os(),
- m_vendor(),
- m_byte_order(lldb::endian::InlHostByteOrder()),
- m_pointer_byte_size(0)
+ m_private_is_running (false)
{
m_rx_packet_listener.StartListeningForEvents(this,
Communication::eBroadcastBitPacketAvailable |
@@ -117,419 +91,6 @@
return Write (&nack_char, 1, status, NULL) == 1;
}
-bool
-GDBRemoteCommunication::GetSendAcks ()
-{
- if (m_supports_not_sending_acks == eLazyBoolCalculate)
- {
- StringExtractorGDBRemote response;
- m_supports_not_sending_acks = eLazyBoolNo;
- if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false))
- {
- if (response.IsOKPacket())
- m_supports_not_sending_acks = eLazyBoolYes;
- }
- }
- return m_supports_not_sending_acks != eLazyBoolYes;
-}
-
-void
-GDBRemoteCommunication::ResetDiscoverableSettings()
-{
- m_supports_not_sending_acks = eLazyBoolCalculate;
- m_supports_thread_suffix = eLazyBoolCalculate;
- m_supports_qHostInfo = eLazyBoolCalculate;
- m_supports_vCont_c = eLazyBoolCalculate;
- m_supports_vCont_C = eLazyBoolCalculate;
- m_supports_vCont_s = eLazyBoolCalculate;
- m_supports_vCont_S = eLazyBoolCalculate;
- m_arch.Clear();
- m_os.Clear();
- m_vendor.Clear();
- m_byte_order = lldb::endian::InlHostByteOrder();
- m_pointer_byte_size = 0;
-}
-
-
-bool
-GDBRemoteCommunication::GetThreadSuffixSupported ()
-{
- if (m_supports_thread_suffix == eLazyBoolCalculate)
- {
- StringExtractorGDBRemote response;
- m_supports_thread_suffix = eLazyBoolNo;
- if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false))
- {
- if (response.IsOKPacket())
- m_supports_thread_suffix = eLazyBoolYes;
- }
- }
- return m_supports_thread_suffix;
-}
-bool
-GDBRemoteCommunication::GetVContSupported (char flavor)
-{
- if (m_supports_vCont_c == eLazyBoolCalculate)
- {
- StringExtractorGDBRemote response;
- m_supports_vCont_any = eLazyBoolNo;
- m_supports_vCont_all = eLazyBoolNo;
- m_supports_vCont_c = eLazyBoolNo;
- m_supports_vCont_C = eLazyBoolNo;
- m_supports_vCont_s = eLazyBoolNo;
- m_supports_vCont_S = eLazyBoolNo;
- if (SendPacketAndWaitForResponse("vCont?", response, false))
- {
- const char *response_cstr = response.GetStringRef().c_str();
- if (::strstr (response_cstr, ";c"))
- m_supports_vCont_c = eLazyBoolYes;
-
- if (::strstr (response_cstr, ";C"))
- m_supports_vCont_C = eLazyBoolYes;
-
- if (::strstr (response_cstr, ";s"))
- m_supports_vCont_s = eLazyBoolYes;
-
- if (::strstr (response_cstr, ";S"))
- m_supports_vCont_S = eLazyBoolYes;
-
- if (m_supports_vCont_c == eLazyBoolYes &&
- m_supports_vCont_C == eLazyBoolYes &&
- m_supports_vCont_s == eLazyBoolYes &&
- m_supports_vCont_S == eLazyBoolYes)
- {
- m_supports_vCont_all = eLazyBoolYes;
- }
-
- if (m_supports_vCont_c == eLazyBoolYes ||
- m_supports_vCont_C == eLazyBoolYes ||
- m_supports_vCont_s == eLazyBoolYes ||
- m_supports_vCont_S == eLazyBoolYes)
- {
- m_supports_vCont_any = eLazyBoolYes;
- }
- }
- }
-
- switch (flavor)
- {
- case 'a': return m_supports_vCont_any;
- case 'A': return m_supports_vCont_all;
- case 'c': return m_supports_vCont_c;
- case 'C': return m_supports_vCont_C;
- case 's': return m_supports_vCont_s;
- case 'S': return m_supports_vCont_S;
- default: break;
- }
- return false;
-}
-
-
-size_t
-GDBRemoteCommunication::SendPacketAndWaitForResponse
-(
- const char *payload,
- StringExtractorGDBRemote &response,
- bool send_async
-)
-{
- return SendPacketAndWaitForResponse (payload,
- ::strlen (payload),
- response,
- send_async);
-}
-
-size_t
-GDBRemoteCommunication::SendPacketAndWaitForResponse
-(
- const char *payload,
- size_t payload_length,
- StringExtractorGDBRemote &response,
- bool send_async
-)
-{
- Mutex::Locker locker;
- TimeValue timeout_time;
- timeout_time = TimeValue::Now();
- timeout_time.OffsetWithSeconds (m_packet_timeout);
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
-
- if (GetSequenceMutex (locker))
- {
- if (SendPacketNoLock (payload, strlen(payload)))
- return WaitForPacketNoLock (response, &timeout_time);
- }
- else
- {
- if (send_async)
- {
- Mutex::Locker async_locker (m_async_mutex);
- m_async_packet.assign(payload, payload_length);
- m_async_packet_predicate.SetValue (true, eBroadcastNever);
-
- if (log)
- log->Printf ("async: async packet = %s", m_async_packet.c_str());
-
- bool timed_out = false;
- bool sent_interrupt = false;
- if (SendInterrupt(locker, 2, sent_interrupt, timed_out))
- {
- if (sent_interrupt)
- {
- if (log)
- log->Printf ("async: sent interrupt");
- if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
- {
- if (log)
- log->Printf ("async: got response");
- response = m_async_response;
- return response.GetStringRef().size();
- }
- else
- {
- if (log)
- log->Printf ("async: timed out waiting for response");
- }
-
- // Make sure we wait until the continue packet has been sent again...
- if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
- {
- if (log)
- log->Printf ("async: timed out waiting for process to resume");
- }
- }
- else
- {
- // We had a racy condition where we went to send the interrupt
- // yet we were able to get the loc
- }
- }
- else
- {
- if (log)
- log->Printf ("async: failed to interrupt");
- }
- }
- else
- {
- if (log)
- log->Printf ("mutex taken and send_async == false, aborting packet");
- }
- }
- return 0;
-}
-
-//template<typename _Tp>
-//class ScopedValueChanger
-//{
-//public:
-// // Take a value reference and the value to assign it to when this class
-// // instance goes out of scope.
-// ScopedValueChanger (_Tp &value_ref, _Tp value) :
-// m_value_ref (value_ref),
-// m_value (value)
-// {
-// }
-//
-// // This object is going out of scope, change the value pointed to by
-// // m_value_ref to the value we got during construction which was stored in
-// // m_value;
-// ~ScopedValueChanger ()
-// {
-// m_value_ref = m_value;
-// }
-//protected:
-// _Tp &m_value_ref; // A reference to the value we will change when this object destructs
-// _Tp m_value; // The value to assign to m_value_ref when this goes out of scope.
-//};
-
-StateType
-GDBRemoteCommunication::SendContinuePacketAndWaitForResponse
-(
- ProcessGDBRemote *process,
- const char *payload,
- size_t packet_length,
- StringExtractorGDBRemote &response
-)
-{
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("GDBRemoteCommunication::%s ()", __FUNCTION__);
-
- Mutex::Locker locker(m_sequence_mutex);
- StateType state = eStateRunning;
-
- BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
- m_public_is_running.SetValue (true, eBroadcastNever);
- // Set the starting continue packet into "continue_packet". This packet
- // make change if we are interrupted and we continue after an async packet...
- std::string continue_packet(payload, packet_length);
-
- while (state == eStateRunning)
- {
- if (log)
- log->Printf ("GDBRemoteCommunication::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
- if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0)
- state = eStateInvalid;
-
- m_private_is_running.SetValue (true, eBroadcastNever);
-
- if (log)
- log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(%.*s)", __FUNCTION__);
-
- if (WaitForPacket (response, (TimeValue*)NULL))
- {
- if (response.Empty())
- state = eStateInvalid;
- else
- {
- const char stop_type = response.GetChar();
- if (log)
- log->Printf ("GDBRemoteCommunication::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
- switch (stop_type)
- {
- case 'T':
- case 'S':
- if (process->GetStopID() == 0)
- {
- if (process->GetID() == LLDB_INVALID_PROCESS_ID)
- {
- lldb::pid_t pid = GetCurrentProcessID ();
- if (pid != LLDB_INVALID_PROCESS_ID)
- process->SetID (pid);
- }
- process->BuildDynamicRegisterInfo (true);
- }
-
- // Privately notify any internal threads that we have stopped
- // in case we wanted to interrupt our process, yet we might
- // send a packet and continue without returning control to the
- // user.
- m_private_is_running.SetValue (false, eBroadcastAlways);
- if (m_async_signal != -1)
- {
- if (log)
- log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
-
- // Save off the async signal we are supposed to send
- const int async_signal = m_async_signal;
- // Clear the async signal member so we don't end up
- // sending the signal multiple times...
- m_async_signal = -1;
- // Check which signal we stopped with
- uint8_t signo = response.GetHexU8(255);
- if (signo == async_signal)
- {
- if (log)
- log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
-
- // We already stopped with a signal that we wanted
- // to stop with, so we are done
- response.SetFilePos (0);
- }
- else
- {
- // We stopped with a different signal that the one
- // we wanted to stop with, so now we must resume
- // with the signal we want
- char signal_packet[32];
- int signal_packet_len = 0;
- signal_packet_len = ::snprintf (signal_packet,
- sizeof (signal_packet),
- "C%2.2x",
- async_signal);
-
- if (log)
- log->Printf ("async: stopped with signal %s, resume with %s",
- Host::GetSignalAsCString (signo),
- Host::GetSignalAsCString (async_signal));
-
- // Set the continue packet to resume...
- continue_packet.assign(signal_packet, signal_packet_len);
- continue;
- }
- }
- else if (m_async_packet_predicate.GetValue())
- {
- // We are supposed to send an asynchronous packet while
- // we are running.
- m_async_response.Clear();
- if (m_async_packet.empty())
- {
- if (log)
- log->Printf ("async: error: empty async packet");
-
- }
- else
- {
- if (log)
- log->Printf ("async: sending packet: %s",
- m_async_packet.c_str());
-
- SendPacketAndWaitForResponse (&m_async_packet[0],
- m_async_packet.size(),
- m_async_response,
- false);
- }
- // Let the other thread that was trying to send the async
- // packet know that the packet has been sent and response is
- // ready...
- m_async_packet_predicate.SetValue(false, eBroadcastAlways);
-
- // Set the continue packet to resume...
- continue_packet.assign (1, 'c');
- continue;
- }
- // Stop with signal and thread info
- state = eStateStopped;
- break;
-
- case 'W':
- case 'X':
- // process exited
- state = eStateExited;
- break;
-
- case 'O':
- // STDOUT
- {
- std::string inferior_stdout;
- inferior_stdout.reserve(response.GetBytesLeft () / 2);
- char ch;
- while ((ch = response.GetHexU8()) != '\0')
- inferior_stdout.append(1, ch);
- process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
- }
- break;
-
- case 'E':
- // ERROR
- state = eStateInvalid;
- break;
-
- default:
- if (log)
- log->Printf ("GDBRemoteCommunication::%s () unrecognized async packet", __FUNCTION__);
- state = eStateInvalid;
- break;
- }
- }
- }
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunication::%s () WaitForPacket(...) => false", __FUNCTION__);
- state = eStateInvalid;
- }
- }
- if (log)
- log->Printf ("GDBRemoteCommunication::%s () => %s", __FUNCTION__, StateAsCString(state));
- response.SetFilePos(0);
- m_private_is_running.SetValue (false, eBroadcastAlways);
- m_public_is_running.SetValue (false, eBroadcastAlways);
- return state;
-}
-
size_t
GDBRemoteCommunication::SendPacket (const char *payload)
{
@@ -583,9 +144,9 @@
char
GDBRemoteCommunication::GetAck ()
{
- StringExtractorGDBRemote response;
- if (WaitForPacket (response, m_packet_timeout) == 1)
- return response.GetChar();
+ StringExtractorGDBRemote packet;
+ if (WaitForPacket (packet, m_packet_timeout) == 1)
+ return packet.GetChar();
return 0;
}
@@ -595,98 +156,6 @@
return locker.TryLock (m_sequence_mutex.GetMutex());
}
-bool
-GDBRemoteCommunication::SendAsyncSignal (int signo)
-{
- m_async_signal = signo;
- bool timed_out = false;
- bool sent_interrupt = false;
- Mutex::Locker locker;
- if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
- return true;
- m_async_signal = -1;
- return false;
-}
-
-// This function takes a mutex locker as a parameter in case the GetSequenceMutex
-// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
-// (the expected result), then it will send the halt packet. If it does succeed
-// then the caller that requested the interrupt will want to keep the sequence
-// locked down so that no one else can send packets while the caller has control.
-// This function usually gets called when we are running and need to stop the
-// target. It can also be used when we are running and and we need to do something
-// else (like read/write memory), so we need to interrupt the running process
-// (gdb remote protocol requires this), and do what we need to do, then resume.
-
-bool
-GDBRemoteCommunication::SendInterrupt
-(
- Mutex::Locker& locker,
- uint32_t seconds_to_wait_for_stop,
- bool &sent_interrupt,
- bool &timed_out
-)
-{
- sent_interrupt = false;
- timed_out = false;
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
-
- if (IsRunning())
- {
- // Only send an interrupt if our debugserver is running...
- if (GetSequenceMutex (locker) == false)
- {
- // Someone has the mutex locked waiting for a response or for the
- // inferior to stop, so send the interrupt on the down low...
- char ctrl_c = '\x03';
- ConnectionStatus status = eConnectionStatusSuccess;
- TimeValue timeout;
- if (seconds_to_wait_for_stop)
- {
- timeout = TimeValue::Now();
- timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
- }
- size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
- ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
- if (bytes_written > 0)
- {
- sent_interrupt = true;
- if (seconds_to_wait_for_stop)
- {
- if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
- {
- if (log)
- log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, private state stopped", __FUNCTION__);
- return true;
- }
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__);
- }
- }
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunication::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);
- return true;
- }
- }
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunication::%s () - failed to write interrupt", __FUNCTION__);
- }
- return false;
- }
- else
- {
- if (log)
- log->Printf ("GDBRemoteCommunication::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
- }
- }
- return true;
-}
bool
GDBRemoteCommunication::WaitForNotRunningPrivate (const TimeValue *timeout_ptr)
@@ -695,27 +164,27 @@
}
size_t
-GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, uint32_t timeout_seconds)
+GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &packet, uint32_t timeout_seconds)
{
Mutex::Locker locker(m_sequence_mutex);
TimeValue timeout_time;
timeout_time = TimeValue::Now();
timeout_time.OffsetWithSeconds (timeout_seconds);
- return WaitForPacketNoLock (response, &timeout_time);
+ return WaitForPacketNoLock (packet, &timeout_time);
}
size_t
-GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
+GDBRemoteCommunication::WaitForPacket (StringExtractorGDBRemote &packet, const TimeValue* timeout_time_ptr)
{
Mutex::Locker locker(m_sequence_mutex);
- return WaitForPacketNoLock (response, timeout_time_ptr);
+ return WaitForPacketNoLock (packet, timeout_time_ptr);
}
size_t
-GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &response, const TimeValue* timeout_time_ptr)
+GDBRemoteCommunication::WaitForPacketNoLock (StringExtractorGDBRemote &packet, const TimeValue* timeout_time_ptr)
{
bool checksum_error = false;
- response.Clear ();
+ packet.Clear ();
EventSP event_sp;
@@ -734,7 +203,7 @@
const size_t packet_size = event_bytes->GetByteSize();
if (packet_data && packet_size > 0)
{
- std::string &response_str = response.GetStringRef();
+ std::string &packet_str = packet.GetStringRef();
if (packet_data[0] == '$')
{
bool success = false;
@@ -748,11 +217,11 @@
success = true;
if (success)
- response_str.assign (packet_data + 1, packet_size - 4);
+ packet_str.assign (packet_data + 1, packet_size - 4);
if (GetSendAcks ())
{
char packet_checksum = strtol (&packet_data[packet_size-2], NULL, 16);
- char actual_checksum = CalculcateChecksum (&response_str[0], response_str.size());
+ char actual_checksum = CalculcateChecksum (&packet_str[0], packet_str.size());
checksum_error = packet_checksum != actual_checksum;
// Send the ack or nack if needed
if (checksum_error || !success)
@@ -763,9 +232,9 @@
}
else
{
- response_str.assign (packet_data, packet_size);
+ packet_str.assign (packet_data, packet_size);
}
- return response_str.size();
+ return packet_str.size();
}
}
}
@@ -845,353 +314,3 @@
}
}
-lldb::pid_t
-GDBRemoteCommunication::GetCurrentProcessID ()
-{
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false))
- {
- if (response.GetChar() == 'Q')
- if (response.GetChar() == 'C')
- return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
- }
- return LLDB_INVALID_PROCESS_ID;
-}
-
-bool
-GDBRemoteCommunication::GetLaunchSuccess (std::string &error_str)
-{
- error_str.clear();
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false))
- {
- if (response.IsOKPacket())
- return true;
- if (response.GetChar() == 'E')
- {
- // A string the describes what failed when launching...
- error_str = response.GetStringRef().substr(1);
- }
- else
- {
- error_str.assign ("unknown error occurred launching process");
- }
- }
- else
- {
- error_str.assign ("failed to send the qLaunchSuccess packet");
- }
- return false;
-}
-
-int
-GDBRemoteCommunication::SendArgumentsPacket (char const *argv[])
-{
- if (argv && argv[0])
- {
- StreamString packet;
- packet.PutChar('A');
- const char *arg;
- for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
- {
- const int arg_len = strlen(arg);
- if (i > 0)
- packet.PutChar(',');
- packet.Printf("%i,%i,", arg_len * 2, i);
- packet.PutBytesAsRawHex8 (arg, arg_len);
- }
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
- {
- if (response.IsOKPacket())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- }
- }
- return -1;
-}
-
-int
-GDBRemoteCommunication::SendEnvironmentPacket (char const *name_equal_value)
-{
- if (name_equal_value && name_equal_value[0])
- {
- StreamString packet;
- packet.Printf("QEnvironment:%s", name_equal_value);
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
- {
- if (response.IsOKPacket())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- }
- }
- return -1;
-}
-
-bool
-GDBRemoteCommunication::GetHostInfo ()
-{
- if (m_supports_qHostInfo == eLazyBoolCalculate)
- {
- m_supports_qHostInfo = eLazyBoolNo;
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse ("qHostInfo", response, false))
- {
- if (response.IsUnsupportedPacket())
- return false;
-
- m_supports_qHostInfo = eLazyBoolYes;
-
- std::string name;
- std::string value;
- uint32_t cpu = LLDB_INVALID_CPUTYPE;
- uint32_t sub = 0;
-
- while (response.GetNameColonValue(name, value))
- {
- if (name.compare("cputype") == 0)
- {
- // exception type in big endian hex
- cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
- }
- else if (name.compare("cpusubtype") == 0)
- {
- // exception count in big endian hex
- sub = Args::StringToUInt32 (value.c_str(), 0, 0);
- }
- else if (name.compare("ostype") == 0)
- {
- // exception data in big endian hex
- m_os.SetCString(value.c_str());
- }
- else if (name.compare("vendor") == 0)
- {
- m_vendor.SetCString(value.c_str());
- }
- else if (name.compare("endian") == 0)
- {
- if (value.compare("little") == 0)
- m_byte_order = eByteOrderLittle;
- else if (value.compare("big") == 0)
- m_byte_order = eByteOrderBig;
- else if (value.compare("pdp") == 0)
- m_byte_order = eByteOrderPDP;
- }
- else if (name.compare("ptrsize") == 0)
- {
- m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
- }
- }
-
- if (cpu != LLDB_INVALID_CPUTYPE)
- m_arch.SetArchitecture (lldb::eArchTypeMachO, cpu, sub);
- }
- }
- return m_supports_qHostInfo == eLazyBoolYes;
-}
-
-int
-GDBRemoteCommunication::SendAttach
-(
- lldb::pid_t pid,
- StringExtractorGDBRemote& response
-)
-{
- if (pid != LLDB_INVALID_PROCESS_ID)
- {
- StreamString packet;
- packet.Printf("vAttach;%x", pid);
-
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
- {
- if (response.IsErrorPacket())
- return response.GetError();
- return 0;
- }
- }
- return -1;
-}
-
-const lldb_private::ArchSpec &
-GDBRemoteCommunication::GetHostArchitecture ()
-{
- if (!HostInfoIsValid ())
- GetHostInfo ();
- return m_arch;
-}
-
-const lldb_private::ConstString &
-GDBRemoteCommunication::GetOSString ()
-{
- if (!HostInfoIsValid ())
- GetHostInfo ();
- return m_os;
-}
-
-const lldb_private::ConstString &
-GDBRemoteCommunication::GetVendorString()
-{
- if (!HostInfoIsValid ())
- GetHostInfo ();
- return m_vendor;
-}
-
-lldb::ByteOrder
-GDBRemoteCommunication::GetByteOrder ()
-{
- if (!HostInfoIsValid ())
- GetHostInfo ();
- return m_byte_order;
-}
-
-uint32_t
-GDBRemoteCommunication::GetAddressByteSize ()
-{
- if (!HostInfoIsValid ())
- GetHostInfo ();
- return m_pointer_byte_size;
-}
-
-addr_t
-GDBRemoteCommunication::AllocateMemory (size_t size, uint32_t permissions)
-{
- char packet[64];
- ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
- permissions & lldb::ePermissionsReadable ? "r" : "",
- permissions & lldb::ePermissionsWritable ? "w" : "",
- permissions & lldb::ePermissionsExecutable ? "x" : "");
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, response, false))
- {
- if (!response.IsErrorPacket())
- return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
- }
- return LLDB_INVALID_ADDRESS;
-}
-
-bool
-GDBRemoteCommunication::DeallocateMemory (addr_t addr)
-{
- char packet[64];
- snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet, response, false))
- {
- if (response.IsOKPacket())
- return true;
- }
- return false;
-}
-
-int
-GDBRemoteCommunication::SetSTDIN (char const *path)
-{
- if (path && path[0])
- {
- StreamString packet;
- packet.PutCString("QSetSTDIN:");
- packet.PutBytesAsRawHex8(path, strlen(path));
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
- {
- if (response.IsOKPacket())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- }
- }
- return -1;
-}
-
-int
-GDBRemoteCommunication::SetSTDOUT (char const *path)
-{
- if (path && path[0])
- {
- StreamString packet;
- packet.PutCString("QSetSTDOUT:");
- packet.PutBytesAsRawHex8(path, strlen(path));
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
- {
- if (response.IsOKPacket())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- }
- }
- return -1;
-}
-
-int
-GDBRemoteCommunication::SetSTDERR (char const *path)
-{
- if (path && path[0])
- {
- StreamString packet;
- packet.PutCString("QSetSTDERR:");
- packet.PutBytesAsRawHex8(path, strlen(path));
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
- {
- if (response.IsOKPacket())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- }
- }
- return -1;
-}
-
-int
-GDBRemoteCommunication::SetWorkingDir (char const *path)
-{
- if (path && path[0])
- {
- StreamString packet;
- packet.PutCString("QSetWorkingDir:");
- packet.PutBytesAsRawHex8(path, strlen(path));
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
- {
- if (response.IsOKPacket())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- }
- }
- return -1;
-}
-
-int
-GDBRemoteCommunication::SetDisableASLR (bool enable)
-{
- StreamString packet;
- packet.Printf("QSetDisableASLR:%i", enable ? 1 : 0);
-
- StringExtractorGDBRemote response;
- if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
- {
- if (response.IsOKPacket())
- return 0;
- uint8_t error = response.GetError();
- if (error)
- return error;
- }
- return -1;
-}
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h?rev=128070&r1=128069&r2=128070&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h Mon Mar 21 23:00:09 2011
@@ -18,10 +18,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
-#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Communication.h"
-#include "lldb/Core/ConstString.h"
-#include "lldb/Core/Error.h"
#include "lldb/Core/Listener.h"
#include "lldb/Host/Mutex.h"
#include "lldb/Host/Predicate.h"
@@ -30,8 +27,7 @@
class ProcessGDBRemote;
-class GDBRemoteCommunication :
- public lldb_private::Communication
+class GDBRemoteCommunication : public lldb_private::Communication
{
public:
enum
@@ -41,7 +37,7 @@
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
- GDBRemoteCommunication();
+ GDBRemoteCommunication(const char *comm_name, const char *listener_name);
virtual
~GDBRemoteCommunication();
@@ -53,23 +49,6 @@
SendPacket (const char *payload,
size_t payload_length);
- size_t
- SendPacketAndWaitForResponse (const char *send_payload,
- StringExtractorGDBRemote &response,
- bool send_async);
-
- size_t
- SendPacketAndWaitForResponse (const char *send_payload,
- size_t send_length,
- StringExtractorGDBRemote &response,
- bool send_async);
-
- lldb::StateType
- SendContinuePacketAndWaitForResponse (ProcessGDBRemote *process,
- const char *packet_payload,
- size_t packet_length,
- StringExtractorGDBRemote &response);
-
// Wait for a packet within 'nsec' seconds
size_t
WaitForPacket (StringExtractorGDBRemote &response,
@@ -90,24 +69,11 @@
size_t
SendNack ();
-
char
CalculcateChecksum (const char *payload,
size_t payload_length);
bool
- GetThreadSuffixSupported ();
-
- bool
- SendAsyncSignal (int signo);
-
- bool
- SendInterrupt (lldb_private::Mutex::Locker &locker,
- uint32_t seconds_to_wait_for_stop,
- bool &sent_interrupt,
- bool &timed_out);
-
- bool
GetSequenceMutex(lldb_private::Mutex::Locker& locker);
//------------------------------------------------------------------
@@ -116,167 +82,29 @@
virtual void
AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast, lldb::ConnectionStatus status);
-
- lldb::pid_t
- GetCurrentProcessID ();
-
- bool
- GetLaunchSuccess (std::string &error_str);
-
- //------------------------------------------------------------------
- /// Sends a GDB remote protocol 'A' packet that delivers program
- /// arguments to the remote server.
- ///
- /// @param[in] argv
- /// A NULL terminated array of const C strings to use as the
- /// arguments.
- ///
- /// @return
- /// Zero if the response was "OK", a positive value if the
- /// the response was "Exx" where xx are two hex digits, or
- /// -1 if the call is unsupported or any other unexpected
- /// response was received.
- //------------------------------------------------------------------
- int
- SendArgumentsPacket (char const *argv[]);
-
- //------------------------------------------------------------------
- /// Sends a "QEnvironment:NAME=VALUE" packet that will build up the
- /// environment that will get used when launching an application
- /// in conjunction with the 'A' packet. This function can be called
- /// multiple times in a row in order to pass on the desired
- /// environment that the inferior should be launched with.
- ///
- /// @param[in] name_equal_value
- /// A NULL terminated C string that contains a single environment
- /// in the format "NAME=VALUE".
- ///
- /// @return
- /// Zero if the response was "OK", a positive value if the
- /// the response was "Exx" where xx are two hex digits, or
- /// -1 if the call is unsupported or any other unexpected
- /// response was received.
- //------------------------------------------------------------------
- int
- SendEnvironmentPacket (char const *name_equal_value);
-
- //------------------------------------------------------------------
- /// Sends a "vAttach:PID" where PID is in hex.
- ///
- /// @param[in] pid
- /// A process ID for the remote gdb server to attach to.
- ///
- /// @param[out] response
- /// The response received from the gdb server. If the return
- /// value is zero, \a response will contain a stop reply
- /// packet.
- ///
- /// @return
- /// Zero if the attach was successful, or an error indicating
- /// an error code.
- //------------------------------------------------------------------
- int
- SendAttach (lldb::pid_t pid,
- StringExtractorGDBRemote& response);
-
-
- //------------------------------------------------------------------
- /// Sets the path to use for stdin/out/err for a process
- /// that will be launched with the 'A' packet.
- ///
- /// @param[in] path
- /// The path to use for stdin/out/err
- ///
- /// @return
- /// Zero if the for success, or an error code for failure.
- //------------------------------------------------------------------
- int
- SetSTDIN (char const *path);
- int
- SetSTDOUT (char const *path);
- int
- SetSTDERR (char const *path);
-
- //------------------------------------------------------------------
- /// Sets the disable ASLR flag to \a enable for a process that will
- /// be launched with the 'A' packet.
- ///
- /// @param[in] enable
- /// A boolean value indicating wether to disable ASLR or not.
- ///
- /// @return
- /// Zero if the for success, or an error code for failure.
- //------------------------------------------------------------------
- int
- SetDisableASLR (bool enable);
-
- //------------------------------------------------------------------
- /// Sets the working directory to \a path for a process that will
- /// be launched with the 'A' packet.
- ///
- /// @param[in] path
- /// The path to a directory to use when launching our processs
- ///
- /// @return
- /// Zero if the for success, or an error code for failure.
- //------------------------------------------------------------------
- int
- SetWorkingDir (char const *path);
-
- lldb::addr_t
- AllocateMemory (size_t size, uint32_t permissions);
-
- bool
- DeallocateMemory (lldb::addr_t addr);
-
bool
IsRunning() const
{
return m_public_is_running.GetValue();
}
- const lldb_private::ArchSpec &
- GetHostArchitecture ();
-
- const lldb_private::ConstString &
- GetOSString ();
-
- const lldb_private::ConstString &
- GetVendorString();
-
- lldb::ByteOrder
- GetByteOrder ();
-
- uint32_t
- GetAddressByteSize ();
-
- bool
- GetVContSupported (char flavor);
-
- void
- ResetDiscoverableSettings();
-
- bool
- GetHostInfo ();
-
- bool
- GetSendAcks ();
-
- bool
- GetSupportsThreadSuffix ();
-
- bool
- HasFullVContSupport ()
- {
- return GetVContSupported ('A');
- }
+ //------------------------------------------------------------------
+ // Client and server must implement these pure virtual functions
+ //------------------------------------------------------------------
+ virtual bool
+ GetThreadSuffixSupported () = 0;
- bool
- HasAnyVContSupport ()
- {
- return GetVContSupported ('a');
- }
+ virtual bool
+ GetSendAcks () = 0;
+ //------------------------------------------------------------------
+ // Set the global packet timeout.
+ //
+ // For clients, this is the timeout that gets used when sending
+ // packets and waiting for responses. For servers, this might not
+ // get used, and if it doesn't this should be moved to the
+ // GDBRemoteCommunicationClient.
+ //------------------------------------------------------------------
uint32_t
SetPacketTimeout (uint32_t packet_timeout)
{
@@ -299,46 +127,15 @@
bool
WaitForNotRunningPrivate (const lldb_private::TimeValue *timeout_ptr);
- bool
- HostInfoIsValid () const
- {
- return m_supports_qHostInfo != lldb::eLazyBoolCalculate;
- }
-
//------------------------------------------------------------------
// Classes that inherit from GDBRemoteCommunication can see and modify these
//------------------------------------------------------------------
uint32_t m_packet_timeout;
- lldb::LazyBool m_supports_not_sending_acks;
- lldb::LazyBool m_supports_thread_suffix;
- lldb::LazyBool m_supports_qHostInfo;
- lldb::LazyBool m_supports_vCont_all;
- lldb::LazyBool m_supports_vCont_any;
- lldb::LazyBool m_supports_vCont_c;
- lldb::LazyBool m_supports_vCont_C;
- lldb::LazyBool m_supports_vCont_s;
- lldb::LazyBool m_supports_vCont_S;
lldb_private::Listener m_rx_packet_listener;
lldb_private::Mutex m_sequence_mutex; // Restrict access to sending/receiving packets to a single thread at a time
lldb_private::Predicate<bool> m_public_is_running;
lldb_private::Predicate<bool> m_private_is_running;
- // If we need to send a packet while the target is running, the m_async_XXX
- // member variables take care of making this happen.
- lldb_private::Mutex m_async_mutex;
- lldb_private::Predicate<bool> m_async_packet_predicate;
- std::string m_async_packet;
- StringExtractorGDBRemote m_async_response;
- int m_async_signal; // We were asked to deliver a signal to the inferior process.
-
- lldb_private::ArchSpec m_arch; // Results from the qHostInfo call
- uint32_t m_cpusubtype; // Results from the qHostInfo call
- lldb_private::ConstString m_os; // Results from the qHostInfo call
- lldb_private::ConstString m_vendor; // Results from the qHostInfo call
- lldb::ByteOrder m_byte_order; // Results from the qHostInfo call
- uint32_t m_pointer_byte_size; // Results from the qHostInfo call
-
-
private:
//------------------------------------------------------------------
// For GDBRemoteCommunication only
Added: 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=128070&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (added)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Mon Mar 21 23:00:09 2011
@@ -0,0 +1,934 @@
+//===-- GDBRemoteCommunicationClient.cpp ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "GDBRemoteCommunicationClient.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "llvm/ADT/Triple.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Core/ConnectionFileDescriptor.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/State.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/TimeValue.h"
+
+// Project includes
+#include "Utility/StringExtractorGDBRemote.h"
+#include "ProcessGDBRemote.h"
+#include "ProcessGDBRemoteLog.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// GDBRemoteCommunicationClient constructor
+//----------------------------------------------------------------------
+GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() :
+ GDBRemoteCommunication("gdb-remote.client", "gdb-remote.client.rx_packet"),
+ m_supports_not_sending_acks (eLazyBoolCalculate),
+ m_supports_thread_suffix (eLazyBoolCalculate),
+ m_supports_qHostInfo (eLazyBoolCalculate),
+ m_supports_vCont_all (eLazyBoolCalculate),
+ m_supports_vCont_any (eLazyBoolCalculate),
+ m_supports_vCont_c (eLazyBoolCalculate),
+ m_supports_vCont_C (eLazyBoolCalculate),
+ m_supports_vCont_s (eLazyBoolCalculate),
+ m_supports_vCont_S (eLazyBoolCalculate),
+ m_async_mutex (Mutex::eMutexTypeRecursive),
+ m_async_packet_predicate (false),
+ m_async_packet (),
+ m_async_response (),
+ m_async_signal (-1),
+ m_arch(),
+ m_os(),
+ m_vendor(),
+ m_byte_order(lldb::endian::InlHostByteOrder()),
+ m_pointer_byte_size(0)
+{
+ m_rx_packet_listener.StartListeningForEvents(this,
+ Communication::eBroadcastBitPacketAvailable |
+ Communication::eBroadcastBitReadThreadDidExit);
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient()
+{
+ m_rx_packet_listener.StopListeningForEvents(this,
+ Communication::eBroadcastBitPacketAvailable |
+ Communication::eBroadcastBitReadThreadDidExit);
+ if (IsConnected())
+ {
+ StopReadThread();
+ Disconnect();
+ }
+}
+
+bool
+GDBRemoteCommunicationClient::GetSendAcks ()
+{
+ if (m_supports_not_sending_acks == eLazyBoolCalculate)
+ {
+ StringExtractorGDBRemote response;
+ m_supports_not_sending_acks = eLazyBoolNo;
+ if (SendPacketAndWaitForResponse("QStartNoAckMode", response, false))
+ {
+ if (response.IsOKResponse())
+ m_supports_not_sending_acks = eLazyBoolYes;
+ }
+ }
+ return m_supports_not_sending_acks != eLazyBoolYes;
+}
+
+void
+GDBRemoteCommunicationClient::ResetDiscoverableSettings()
+{
+ m_supports_not_sending_acks = eLazyBoolCalculate;
+ m_supports_thread_suffix = eLazyBoolCalculate;
+ m_supports_qHostInfo = eLazyBoolCalculate;
+ m_supports_vCont_c = eLazyBoolCalculate;
+ m_supports_vCont_C = eLazyBoolCalculate;
+ m_supports_vCont_s = eLazyBoolCalculate;
+ m_supports_vCont_S = eLazyBoolCalculate;
+ m_arch.Clear();
+ m_os.Clear();
+ m_vendor.Clear();
+ m_byte_order = lldb::endian::InlHostByteOrder();
+ m_pointer_byte_size = 0;
+}
+
+
+bool
+GDBRemoteCommunicationClient::GetThreadSuffixSupported ()
+{
+ if (m_supports_thread_suffix == eLazyBoolCalculate)
+ {
+ StringExtractorGDBRemote response;
+ m_supports_thread_suffix = eLazyBoolNo;
+ if (SendPacketAndWaitForResponse("QThreadSuffixSupported", response, false))
+ {
+ if (response.IsOKResponse())
+ m_supports_thread_suffix = eLazyBoolYes;
+ }
+ }
+ return m_supports_thread_suffix;
+}
+bool
+GDBRemoteCommunicationClient::GetVContSupported (char flavor)
+{
+ if (m_supports_vCont_c == eLazyBoolCalculate)
+ {
+ StringExtractorGDBRemote response;
+ m_supports_vCont_any = eLazyBoolNo;
+ m_supports_vCont_all = eLazyBoolNo;
+ m_supports_vCont_c = eLazyBoolNo;
+ m_supports_vCont_C = eLazyBoolNo;
+ m_supports_vCont_s = eLazyBoolNo;
+ m_supports_vCont_S = eLazyBoolNo;
+ if (SendPacketAndWaitForResponse("vCont?", response, false))
+ {
+ const char *response_cstr = response.GetStringRef().c_str();
+ if (::strstr (response_cstr, ";c"))
+ m_supports_vCont_c = eLazyBoolYes;
+
+ if (::strstr (response_cstr, ";C"))
+ m_supports_vCont_C = eLazyBoolYes;
+
+ if (::strstr (response_cstr, ";s"))
+ m_supports_vCont_s = eLazyBoolYes;
+
+ if (::strstr (response_cstr, ";S"))
+ m_supports_vCont_S = eLazyBoolYes;
+
+ if (m_supports_vCont_c == eLazyBoolYes &&
+ m_supports_vCont_C == eLazyBoolYes &&
+ m_supports_vCont_s == eLazyBoolYes &&
+ m_supports_vCont_S == eLazyBoolYes)
+ {
+ m_supports_vCont_all = eLazyBoolYes;
+ }
+
+ if (m_supports_vCont_c == eLazyBoolYes ||
+ m_supports_vCont_C == eLazyBoolYes ||
+ m_supports_vCont_s == eLazyBoolYes ||
+ m_supports_vCont_S == eLazyBoolYes)
+ {
+ m_supports_vCont_any = eLazyBoolYes;
+ }
+ }
+ }
+
+ switch (flavor)
+ {
+ case 'a': return m_supports_vCont_any;
+ case 'A': return m_supports_vCont_all;
+ case 'c': return m_supports_vCont_c;
+ case 'C': return m_supports_vCont_C;
+ case 's': return m_supports_vCont_s;
+ case 'S': return m_supports_vCont_S;
+ default: break;
+ }
+ return false;
+}
+
+
+size_t
+GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
+(
+ const char *payload,
+ StringExtractorGDBRemote &response,
+ bool send_async
+)
+{
+ return SendPacketAndWaitForResponse (payload,
+ ::strlen (payload),
+ response,
+ send_async);
+}
+
+size_t
+GDBRemoteCommunicationClient::SendPacketAndWaitForResponse
+(
+ const char *payload,
+ size_t payload_length,
+ StringExtractorGDBRemote &response,
+ bool send_async
+)
+{
+ Mutex::Locker locker;
+ TimeValue timeout_time;
+ timeout_time = TimeValue::Now();
+ timeout_time.OffsetWithSeconds (m_packet_timeout);
+ LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+
+ if (GetSequenceMutex (locker))
+ {
+ if (SendPacketNoLock (payload, strlen(payload)))
+ return WaitForPacketNoLock (response, &timeout_time);
+ }
+ else
+ {
+ if (send_async)
+ {
+ Mutex::Locker async_locker (m_async_mutex);
+ m_async_packet.assign(payload, payload_length);
+ m_async_packet_predicate.SetValue (true, eBroadcastNever);
+
+ if (log)
+ log->Printf ("async: async packet = %s", m_async_packet.c_str());
+
+ bool timed_out = false;
+ bool sent_interrupt = false;
+ if (SendInterrupt(locker, 2, sent_interrupt, timed_out))
+ {
+ if (sent_interrupt)
+ {
+ if (log)
+ log->Printf ("async: sent interrupt");
+ if (m_async_packet_predicate.WaitForValueEqualTo (false, &timeout_time, &timed_out))
+ {
+ if (log)
+ log->Printf ("async: got response");
+ response = m_async_response;
+ return response.GetStringRef().size();
+ }
+ else
+ {
+ if (log)
+ log->Printf ("async: timed out waiting for response");
+ }
+
+ // Make sure we wait until the continue packet has been sent again...
+ if (m_private_is_running.WaitForValueEqualTo (true, &timeout_time, &timed_out))
+ {
+ if (log)
+ log->Printf ("async: timed out waiting for process to resume");
+ }
+ }
+ else
+ {
+ // We had a racy condition where we went to send the interrupt
+ // yet we were able to get the loc
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf ("async: failed to interrupt");
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf ("mutex taken and send_async == false, aborting packet");
+ }
+ }
+ return 0;
+}
+
+//template<typename _Tp>
+//class ScopedValueChanger
+//{
+//public:
+// // Take a value reference and the value to assign it to when this class
+// // instance goes out of scope.
+// ScopedValueChanger (_Tp &value_ref, _Tp value) :
+// m_value_ref (value_ref),
+// m_value (value)
+// {
+// }
+//
+// // This object is going out of scope, change the value pointed to by
+// // m_value_ref to the value we got during construction which was stored in
+// // m_value;
+// ~ScopedValueChanger ()
+// {
+// m_value_ref = m_value;
+// }
+//protected:
+// _Tp &m_value_ref; // A reference to the value we will change when this object destructs
+// _Tp m_value; // The value to assign to m_value_ref when this goes out of scope.
+//};
+
+StateType
+GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
+(
+ ProcessGDBRemote *process,
+ const char *payload,
+ size_t packet_length,
+ StringExtractorGDBRemote &response
+)
+{
+ LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+ if (log)
+ log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
+
+ Mutex::Locker locker(m_sequence_mutex);
+ StateType state = eStateRunning;
+
+ BroadcastEvent(eBroadcastBitRunPacketSent, NULL);
+ m_public_is_running.SetValue (true, eBroadcastNever);
+ // Set the starting continue packet into "continue_packet". This packet
+ // make change if we are interrupted and we continue after an async packet...
+ std::string continue_packet(payload, packet_length);
+
+ while (state == eStateRunning)
+ {
+ if (log)
+ log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
+ if (SendPacket(continue_packet.c_str(), continue_packet.size()) == 0)
+ state = eStateInvalid;
+
+ m_private_is_running.SetValue (true, eBroadcastNever);
+
+ if (log)
+ log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%.*s)", __FUNCTION__);
+
+ if (WaitForPacket (response, (TimeValue*)NULL))
+ {
+ if (response.Empty())
+ state = eStateInvalid;
+ else
+ {
+ const char stop_type = response.GetChar();
+ if (log)
+ log->Printf ("GDBRemoteCommunicationClient::%s () got packet: %s", __FUNCTION__, response.GetStringRef().c_str());
+ switch (stop_type)
+ {
+ case 'T':
+ case 'S':
+ if (process->GetStopID() == 0)
+ {
+ if (process->GetID() == LLDB_INVALID_PROCESS_ID)
+ {
+ lldb::pid_t pid = GetCurrentProcessID ();
+ if (pid != LLDB_INVALID_PROCESS_ID)
+ process->SetID (pid);
+ }
+ process->BuildDynamicRegisterInfo (true);
+ }
+
+ // Privately notify any internal threads that we have stopped
+ // in case we wanted to interrupt our process, yet we might
+ // send a packet and continue without returning control to the
+ // user.
+ m_private_is_running.SetValue (false, eBroadcastAlways);
+ if (m_async_signal != -1)
+ {
+ if (log)
+ log->Printf ("async: send signo = %s", Host::GetSignalAsCString (m_async_signal));
+
+ // Save off the async signal we are supposed to send
+ const int async_signal = m_async_signal;
+ // Clear the async signal member so we don't end up
+ // sending the signal multiple times...
+ m_async_signal = -1;
+ // Check which signal we stopped with
+ uint8_t signo = response.GetHexU8(255);
+ if (signo == async_signal)
+ {
+ if (log)
+ log->Printf ("async: stopped with signal %s, we are done running", Host::GetSignalAsCString (signo));
+
+ // We already stopped with a signal that we wanted
+ // to stop with, so we are done
+ response.SetFilePos (0);
+ }
+ else
+ {
+ // We stopped with a different signal that the one
+ // we wanted to stop with, so now we must resume
+ // with the signal we want
+ char signal_packet[32];
+ int signal_packet_len = 0;
+ signal_packet_len = ::snprintf (signal_packet,
+ sizeof (signal_packet),
+ "C%2.2x",
+ async_signal);
+
+ if (log)
+ log->Printf ("async: stopped with signal %s, resume with %s",
+ Host::GetSignalAsCString (signo),
+ Host::GetSignalAsCString (async_signal));
+
+ // Set the continue packet to resume...
+ continue_packet.assign(signal_packet, signal_packet_len);
+ continue;
+ }
+ }
+ else if (m_async_packet_predicate.GetValue())
+ {
+ // We are supposed to send an asynchronous packet while
+ // we are running.
+ m_async_response.Clear();
+ if (m_async_packet.empty())
+ {
+ if (log)
+ log->Printf ("async: error: empty async packet");
+
+ }
+ else
+ {
+ if (log)
+ log->Printf ("async: sending packet: %s",
+ m_async_packet.c_str());
+
+ SendPacketAndWaitForResponse (&m_async_packet[0],
+ m_async_packet.size(),
+ m_async_response,
+ false);
+ }
+ // Let the other thread that was trying to send the async
+ // packet know that the packet has been sent and response is
+ // ready...
+ m_async_packet_predicate.SetValue(false, eBroadcastAlways);
+
+ // Set the continue packet to resume...
+ continue_packet.assign (1, 'c');
+ continue;
+ }
+ // Stop with signal and thread info
+ state = eStateStopped;
+ break;
+
+ case 'W':
+ case 'X':
+ // process exited
+ state = eStateExited;
+ break;
+
+ case 'O':
+ // STDOUT
+ {
+ std::string inferior_stdout;
+ inferior_stdout.reserve(response.GetBytesLeft () / 2);
+ char ch;
+ while ((ch = response.GetHexU8()) != '\0')
+ inferior_stdout.append(1, ch);
+ process->AppendSTDOUT (inferior_stdout.c_str(), inferior_stdout.size());
+ }
+ break;
+
+ case 'E':
+ // ERROR
+ state = eStateInvalid;
+ break;
+
+ default:
+ if (log)
+ log->Printf ("GDBRemoteCommunicationClient::%s () unrecognized async packet", __FUNCTION__);
+ state = eStateInvalid;
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(...) => false", __FUNCTION__);
+ state = eStateInvalid;
+ }
+ }
+ if (log)
+ log->Printf ("GDBRemoteCommunicationClient::%s () => %s", __FUNCTION__, StateAsCString(state));
+ response.SetFilePos(0);
+ m_private_is_running.SetValue (false, eBroadcastAlways);
+ m_public_is_running.SetValue (false, eBroadcastAlways);
+ return state;
+}
+
+bool
+GDBRemoteCommunicationClient::SendAsyncSignal (int signo)
+{
+ m_async_signal = signo;
+ bool timed_out = false;
+ bool sent_interrupt = false;
+ Mutex::Locker locker;
+ if (SendInterrupt (locker, 1, sent_interrupt, timed_out))
+ return true;
+ m_async_signal = -1;
+ return false;
+}
+
+// This function takes a mutex locker as a parameter in case the GetSequenceMutex
+// actually succeeds. If it doesn't succeed in acquiring the sequence mutex
+// (the expected result), then it will send the halt packet. If it does succeed
+// then the caller that requested the interrupt will want to keep the sequence
+// locked down so that no one else can send packets while the caller has control.
+// This function usually gets called when we are running and need to stop the
+// target. It can also be used when we are running and and we need to do something
+// else (like read/write memory), so we need to interrupt the running process
+// (gdb remote protocol requires this), and do what we need to do, then resume.
+
+bool
+GDBRemoteCommunicationClient::SendInterrupt
+(
+ Mutex::Locker& locker,
+ uint32_t seconds_to_wait_for_stop,
+ bool &sent_interrupt,
+ bool &timed_out
+)
+{
+ sent_interrupt = false;
+ timed_out = false;
+ LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+
+ if (IsRunning())
+ {
+ // Only send an interrupt if our debugserver is running...
+ if (GetSequenceMutex (locker) == false)
+ {
+ // Someone has the mutex locked waiting for a response or for the
+ // inferior to stop, so send the interrupt on the down low...
+ char ctrl_c = '\x03';
+ ConnectionStatus status = eConnectionStatusSuccess;
+ TimeValue timeout;
+ if (seconds_to_wait_for_stop)
+ {
+ timeout = TimeValue::Now();
+ timeout.OffsetWithSeconds (seconds_to_wait_for_stop);
+ }
+ size_t bytes_written = Write (&ctrl_c, 1, status, NULL);
+ ProcessGDBRemoteLog::LogIf (GDBR_LOG_PACKETS | GDBR_LOG_PROCESS, "send packet: \\x03");
+ if (bytes_written > 0)
+ {
+ sent_interrupt = true;
+ if (seconds_to_wait_for_stop)
+ {
+ if (m_private_is_running.WaitForValueEqualTo (false, &timeout, &timed_out))
+ {
+ if (log)
+ log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, private state stopped", __FUNCTION__);
+ return true;
+ }
+ else
+ {
+ if (log)
+ log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, timed out wating for async thread resume", __FUNCTION__);
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf ("GDBRemoteCommunicationClient::%s () - sent interrupt, not waiting for stop...", __FUNCTION__);
+ return true;
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf ("GDBRemoteCommunicationClient::%s () - failed to write interrupt", __FUNCTION__);
+ }
+ return false;
+ }
+ else
+ {
+ if (log)
+ log->Printf ("GDBRemoteCommunicationClient::%s () - got sequence mutex without having to interrupt", __FUNCTION__);
+ }
+ }
+ return true;
+}
+
+lldb::pid_t
+GDBRemoteCommunicationClient::GetCurrentProcessID ()
+{
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qC", strlen("qC"), response, false))
+ {
+ if (response.GetChar() == 'Q')
+ if (response.GetChar() == 'C')
+ return response.GetHexMaxU32 (false, LLDB_INVALID_PROCESS_ID);
+ }
+ return LLDB_INVALID_PROCESS_ID;
+}
+
+bool
+GDBRemoteCommunicationClient::GetLaunchSuccess (std::string &error_str)
+{
+ error_str.clear();
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse("qLaunchSuccess", strlen("qLaunchSuccess"), response, false))
+ {
+ if (response.IsOKResponse())
+ return true;
+ if (response.GetChar() == 'E')
+ {
+ // A string the describes what failed when launching...
+ error_str = response.GetStringRef().substr(1);
+ }
+ else
+ {
+ error_str.assign ("unknown error occurred launching process");
+ }
+ }
+ else
+ {
+ error_str.assign ("failed to send the qLaunchSuccess packet");
+ }
+ return false;
+}
+
+int
+GDBRemoteCommunicationClient::SendArgumentsPacket (char const *argv[])
+{
+ if (argv && argv[0])
+ {
+ StreamString packet;
+ packet.PutChar('A');
+ const char *arg;
+ for (uint32_t i = 0; (arg = argv[i]) != NULL; ++i)
+ {
+ const int arg_len = strlen(arg);
+ if (i > 0)
+ packet.PutChar(',');
+ packet.Printf("%i,%i,", arg_len * 2, i);
+ packet.PutBytesAsRawHex8 (arg, arg_len);
+ }
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
+ }
+ }
+ return -1;
+}
+
+int
+GDBRemoteCommunicationClient::SendEnvironmentPacket (char const *name_equal_value)
+{
+ if (name_equal_value && name_equal_value[0])
+ {
+ StreamString packet;
+ packet.Printf("QEnvironment:%s", name_equal_value);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
+ }
+ }
+ return -1;
+}
+
+bool
+GDBRemoteCommunicationClient::GetHostInfo ()
+{
+ if (m_supports_qHostInfo == eLazyBoolCalculate)
+ {
+ m_supports_qHostInfo = eLazyBoolNo;
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse ("qHostInfo", response, false))
+ {
+ if (response.IsUnsupportedResponse())
+ return false;
+
+ m_supports_qHostInfo = eLazyBoolYes;
+
+ std::string name;
+ std::string value;
+ uint32_t cpu = LLDB_INVALID_CPUTYPE;
+ uint32_t sub = 0;
+
+ while (response.GetNameColonValue(name, value))
+ {
+ if (name.compare("cputype") == 0)
+ {
+ // exception type in big endian hex
+ cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 0);
+ }
+ else if (name.compare("cpusubtype") == 0)
+ {
+ // exception count in big endian hex
+ sub = Args::StringToUInt32 (value.c_str(), 0, 0);
+ }
+ else if (name.compare("ostype") == 0)
+ {
+ // exception data in big endian hex
+ m_os.SetCString(value.c_str());
+ }
+ else if (name.compare("vendor") == 0)
+ {
+ m_vendor.SetCString(value.c_str());
+ }
+ else if (name.compare("endian") == 0)
+ {
+ if (value.compare("little") == 0)
+ m_byte_order = eByteOrderLittle;
+ else if (value.compare("big") == 0)
+ m_byte_order = eByteOrderBig;
+ else if (value.compare("pdp") == 0)
+ m_byte_order = eByteOrderPDP;
+ }
+ else if (name.compare("ptrsize") == 0)
+ {
+ m_pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 0);
+ }
+ }
+
+ if (cpu != LLDB_INVALID_CPUTYPE)
+ m_arch.SetArchitecture (lldb::eArchTypeMachO, cpu, sub);
+ }
+ }
+ return m_supports_qHostInfo == eLazyBoolYes;
+}
+
+int
+GDBRemoteCommunicationClient::SendAttach
+(
+ lldb::pid_t pid,
+ StringExtractorGDBRemote& response
+)
+{
+ if (pid != LLDB_INVALID_PROCESS_ID)
+ {
+ StreamString packet;
+ packet.Printf("vAttach;%x", pid);
+
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ {
+ if (response.IsErrorResponse())
+ return response.GetError();
+ return 0;
+ }
+ }
+ return -1;
+}
+
+const lldb_private::ArchSpec &
+GDBRemoteCommunicationClient::GetHostArchitecture ()
+{
+ if (!HostInfoIsValid ())
+ GetHostInfo ();
+ return m_arch;
+}
+
+const lldb_private::ConstString &
+GDBRemoteCommunicationClient::GetOSString ()
+{
+ if (!HostInfoIsValid ())
+ GetHostInfo ();
+ return m_os;
+}
+
+const lldb_private::ConstString &
+GDBRemoteCommunicationClient::GetVendorString()
+{
+ if (!HostInfoIsValid ())
+ GetHostInfo ();
+ return m_vendor;
+}
+
+lldb::ByteOrder
+GDBRemoteCommunicationClient::GetByteOrder ()
+{
+ if (!HostInfoIsValid ())
+ GetHostInfo ();
+ return m_byte_order;
+}
+
+uint32_t
+GDBRemoteCommunicationClient::GetAddressByteSize ()
+{
+ if (!HostInfoIsValid ())
+ GetHostInfo ();
+ return m_pointer_byte_size;
+}
+
+addr_t
+GDBRemoteCommunicationClient::AllocateMemory (size_t size, uint32_t permissions)
+{
+ char packet[64];
+ ::snprintf (packet, sizeof(packet), "_M%zx,%s%s%s", size,
+ permissions & lldb::ePermissionsReadable ? "r" : "",
+ permissions & lldb::ePermissionsWritable ? "w" : "",
+ permissions & lldb::ePermissionsExecutable ? "x" : "");
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse (packet, response, false))
+ {
+ if (!response.IsErrorResponse())
+ return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
+ }
+ return LLDB_INVALID_ADDRESS;
+}
+
+bool
+GDBRemoteCommunicationClient::DeallocateMemory (addr_t addr)
+{
+ char packet[64];
+ snprintf(packet, sizeof(packet), "_m%llx", (uint64_t)addr);
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse (packet, response, false))
+ {
+ if (response.IsOKResponse())
+ return true;
+ }
+ return false;
+}
+
+int
+GDBRemoteCommunicationClient::SetSTDIN (char const *path)
+{
+ if (path && path[0])
+ {
+ StreamString packet;
+ packet.PutCString("QSetSTDIN:");
+ packet.PutBytesAsRawHex8(path, strlen(path));
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
+ }
+ }
+ return -1;
+}
+
+int
+GDBRemoteCommunicationClient::SetSTDOUT (char const *path)
+{
+ if (path && path[0])
+ {
+ StreamString packet;
+ packet.PutCString("QSetSTDOUT:");
+ packet.PutBytesAsRawHex8(path, strlen(path));
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
+ }
+ }
+ return -1;
+}
+
+int
+GDBRemoteCommunicationClient::SetSTDERR (char const *path)
+{
+ if (path && path[0])
+ {
+ StreamString packet;
+ packet.PutCString("QSetSTDERR:");
+ packet.PutBytesAsRawHex8(path, strlen(path));
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
+ }
+ }
+ return -1;
+}
+
+int
+GDBRemoteCommunicationClient::SetWorkingDir (char const *path)
+{
+ if (path && path[0])
+ {
+ StreamString packet;
+ packet.PutCString("QSetWorkingDir:");
+ packet.PutBytesAsRawHex8(path, strlen(path));
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
+ }
+ }
+ return -1;
+}
+
+int
+GDBRemoteCommunicationClient::SetDisableASLR (bool enable)
+{
+ StreamString packet;
+ packet.Printf("QSetDisableASLR:%i", enable ? 1 : 0);
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse (packet.GetData(), packet.GetSize(), response, false))
+ {
+ if (response.IsOKResponse())
+ return 0;
+ uint8_t error = response.GetError();
+ if (error)
+ return error;
+ }
+ return -1;
+}
Added: 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=128070&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (added)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Mon Mar 21 23:00:09 2011
@@ -0,0 +1,268 @@
+//===-- GDBRemoteCommunicationClient.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_GDBRemoteCommunicationClient_h_
+#define liblldb_GDBRemoteCommunicationClient_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/ArchSpec.h"
+
+#include "GDBRemoteCommunication.h"
+
+class GDBRemoteCommunicationClient : public GDBRemoteCommunication
+{
+public:
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ GDBRemoteCommunicationClient();
+
+ virtual
+ ~GDBRemoteCommunicationClient();
+
+ size_t
+ SendPacketAndWaitForResponse (const char *send_payload,
+ StringExtractorGDBRemote &response,
+ bool send_async);
+
+ size_t
+ SendPacketAndWaitForResponse (const char *send_payload,
+ size_t send_length,
+ StringExtractorGDBRemote &response,
+ bool send_async);
+
+ lldb::StateType
+ SendContinuePacketAndWaitForResponse (ProcessGDBRemote *process,
+ const char *packet_payload,
+ size_t packet_length,
+ StringExtractorGDBRemote &response);
+
+ virtual bool
+ GetThreadSuffixSupported ();
+
+ virtual bool
+ GetSendAcks ();
+
+ bool
+ SendAsyncSignal (int signo);
+
+ bool
+ SendInterrupt (lldb_private::Mutex::Locker &locker,
+ uint32_t seconds_to_wait_for_stop,
+ bool &sent_interrupt,
+ bool &timed_out);
+
+ lldb::pid_t
+ GetCurrentProcessID ();
+
+ bool
+ GetLaunchSuccess (std::string &error_str);
+
+ //------------------------------------------------------------------
+ /// Sends a GDB remote protocol 'A' packet that delivers program
+ /// arguments to the remote server.
+ ///
+ /// @param[in] argv
+ /// A NULL terminated array of const C strings to use as the
+ /// arguments.
+ ///
+ /// @return
+ /// Zero if the response was "OK", a positive value if the
+ /// the response was "Exx" where xx are two hex digits, or
+ /// -1 if the call is unsupported or any other unexpected
+ /// response was received.
+ //------------------------------------------------------------------
+ int
+ SendArgumentsPacket (char const *argv[]);
+
+ //------------------------------------------------------------------
+ /// Sends a "QEnvironment:NAME=VALUE" packet that will build up the
+ /// environment that will get used when launching an application
+ /// in conjunction with the 'A' packet. This function can be called
+ /// multiple times in a row in order to pass on the desired
+ /// environment that the inferior should be launched with.
+ ///
+ /// @param[in] name_equal_value
+ /// A NULL terminated C string that contains a single environment
+ /// in the format "NAME=VALUE".
+ ///
+ /// @return
+ /// Zero if the response was "OK", a positive value if the
+ /// the response was "Exx" where xx are two hex digits, or
+ /// -1 if the call is unsupported or any other unexpected
+ /// response was received.
+ //------------------------------------------------------------------
+ int
+ SendEnvironmentPacket (char const *name_equal_value);
+
+ //------------------------------------------------------------------
+ /// Sends a "vAttach:PID" where PID is in hex.
+ ///
+ /// @param[in] pid
+ /// A process ID for the remote gdb server to attach to.
+ ///
+ /// @param[out] response
+ /// The response received from the gdb server. If the return
+ /// value is zero, \a response will contain a stop reply
+ /// packet.
+ ///
+ /// @return
+ /// Zero if the attach was successful, or an error indicating
+ /// an error code.
+ //------------------------------------------------------------------
+ int
+ SendAttach (lldb::pid_t pid,
+ StringExtractorGDBRemote& response);
+
+
+ //------------------------------------------------------------------
+ /// Sets the path to use for stdin/out/err for a process
+ /// that will be launched with the 'A' packet.
+ ///
+ /// @param[in] path
+ /// The path to use for stdin/out/err
+ ///
+ /// @return
+ /// Zero if the for success, or an error code for failure.
+ //------------------------------------------------------------------
+ int
+ SetSTDIN (char const *path);
+ int
+ SetSTDOUT (char const *path);
+ int
+ SetSTDERR (char const *path);
+
+ //------------------------------------------------------------------
+ /// Sets the disable ASLR flag to \a enable for a process that will
+ /// be launched with the 'A' packet.
+ ///
+ /// @param[in] enable
+ /// A boolean value indicating wether to disable ASLR or not.
+ ///
+ /// @return
+ /// Zero if the for success, or an error code for failure.
+ //------------------------------------------------------------------
+ int
+ SetDisableASLR (bool enable);
+
+ //------------------------------------------------------------------
+ /// Sets the working directory to \a path for a process that will
+ /// be launched with the 'A' packet.
+ ///
+ /// @param[in] path
+ /// The path to a directory to use when launching our processs
+ ///
+ /// @return
+ /// Zero if the for success, or an error code for failure.
+ //------------------------------------------------------------------
+ int
+ SetWorkingDir (char const *path);
+
+ lldb::addr_t
+ AllocateMemory (size_t size, uint32_t permissions);
+
+ bool
+ DeallocateMemory (lldb::addr_t addr);
+
+ const lldb_private::ArchSpec &
+ GetHostArchitecture ();
+
+ const lldb_private::ConstString &
+ GetOSString ();
+
+ const lldb_private::ConstString &
+ GetVendorString();
+
+ lldb::ByteOrder
+ GetByteOrder ();
+
+ uint32_t
+ GetAddressByteSize ();
+
+ bool
+ GetVContSupported (char flavor);
+
+ void
+ ResetDiscoverableSettings();
+
+ bool
+ GetHostInfo ();
+
+ bool
+ GetSupportsThreadSuffix ();
+
+ bool
+ HasFullVContSupport ()
+ {
+ return GetVContSupported ('A');
+ }
+
+ bool
+ HasAnyVContSupport ()
+ {
+ return GetVContSupported ('a');
+ }
+
+ uint32_t
+ SetPacketTimeout (uint32_t packet_timeout)
+ {
+ const uint32_t old_packet_timeout = m_packet_timeout;
+ m_packet_timeout = packet_timeout;
+ return old_packet_timeout;
+ }
+
+protected:
+
+ bool
+ HostInfoIsValid () const
+ {
+ return m_supports_qHostInfo != lldb::eLazyBoolCalculate;
+ }
+
+ //------------------------------------------------------------------
+ // Classes that inherit from GDBRemoteCommunicationClient can see and modify these
+ //------------------------------------------------------------------
+ lldb::LazyBool m_supports_not_sending_acks;
+ lldb::LazyBool m_supports_thread_suffix;
+ lldb::LazyBool m_supports_qHostInfo;
+ lldb::LazyBool m_supports_vCont_all;
+ lldb::LazyBool m_supports_vCont_any;
+ lldb::LazyBool m_supports_vCont_c;
+ lldb::LazyBool m_supports_vCont_C;
+ lldb::LazyBool m_supports_vCont_s;
+ lldb::LazyBool m_supports_vCont_S;
+
+ // If we need to send a packet while the target is running, the m_async_XXX
+ // member variables take care of making this happen.
+ lldb_private::Mutex m_async_mutex;
+ lldb_private::Predicate<bool> m_async_packet_predicate;
+ std::string m_async_packet;
+ StringExtractorGDBRemote m_async_response;
+ int m_async_signal; // We were asked to deliver a signal to the inferior process.
+
+ lldb_private::ArchSpec m_arch;
+ uint32_t m_cpusubtype;
+ lldb_private::ConstString m_os;
+ lldb_private::ConstString m_vendor;
+ lldb::ByteOrder m_byte_order;
+ uint32_t m_pointer_byte_size;
+
+
+
+private:
+ //------------------------------------------------------------------
+ // For GDBRemoteCommunicationClient only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationClient);
+};
+
+#endif // liblldb_GDBRemoteCommunicationClient_h_
Added: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp?rev=128070&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp (added)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp Mon Mar 21 23:00:09 2011
@@ -0,0 +1,134 @@
+//===-- GDBRemoteCommunicationServer.cpp ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#include "GDBRemoteCommunicationServer.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+#include "llvm/ADT/Triple.h"
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Core/ConnectionFileDescriptor.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/State.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Host/Host.h"
+#include "lldb/Host/TimeValue.h"
+
+// Project includes
+#include "Utility/StringExtractorGDBRemote.h"
+#include "ProcessGDBRemote.h"
+#include "ProcessGDBRemoteLog.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// GDBRemoteCommunicationServer constructor
+//----------------------------------------------------------------------
+GDBRemoteCommunicationServer::GDBRemoteCommunicationServer() :
+ GDBRemoteCommunication ("gdb-remote.server", "gdb-remote.server.rx_packet"),
+ m_async_thread (LLDB_INVALID_HOST_THREAD),
+ m_send_acks (true)
+{
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer()
+{
+}
+
+
+//void *
+//GDBRemoteCommunicationServer::AsyncThread (void *arg)
+//{
+// GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer*) arg;
+//
+// LogSP log;// (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+// if (log)
+// log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID());
+//
+// StringExtractorGDBRemote packet;
+//
+// while ()
+// {
+// if (packet.
+// }
+//
+// if (log)
+// log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread exiting...", __FUNCTION__, arg, process->GetID());
+//
+// process->m_async_thread = LLDB_INVALID_HOST_THREAD;
+// return NULL;
+//}
+//
+bool
+GDBRemoteCommunicationServer::GetPacketAndSendResponse (const TimeValue* timeout_time_ptr)
+{
+ StringExtractorGDBRemote packet;
+ if (WaitForPacketNoLock (packet, timeout_time_ptr))
+ {
+ const StringExtractorGDBRemote::ServerPacketType packet_type = packet.GetServerPacketType ();
+ switch (packet_type)
+ {
+ case StringExtractorGDBRemote::eServerPacketType_nack:
+ case StringExtractorGDBRemote::eServerPacketType_ack:
+ break;
+
+ case StringExtractorGDBRemote::eServerPacketType_invalid:
+ case StringExtractorGDBRemote::eServerPacketType_unimplemented:
+ return SendUnimplementedResponse () > 0;
+
+ case StringExtractorGDBRemote::eServerPacketType_qHostInfo:
+ return Handle_qHostInfo ();
+ }
+ return true;
+ }
+ return false;
+}
+
+size_t
+GDBRemoteCommunicationServer::SendUnimplementedResponse ()
+{
+ return SendPacket ("");
+}
+
+
+bool
+GDBRemoteCommunicationServer::Handle_qHostInfo ()
+{
+ StreamString response;
+
+ // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00
+
+ ArchSpec host_arch (Host::GetArchitecture ());
+
+ const llvm::Triple &host_triple = host_arch.GetTriple();
+ const llvm::StringRef arch_name (host_triple.getArchName());
+ const llvm::StringRef vendor_name (host_triple.getOSName());
+ const llvm::StringRef os_name (host_triple.getVendorName());
+ response.Printf ("arch:%.*s;ostype:%.*s;vendor:%.*s;ptrsize:%u",
+ (int)arch_name.size(), arch_name.data(),
+ (int)os_name.size(), os_name.data(),
+ (int)vendor_name.size(), vendor_name.data(),
+ host_arch.GetAddressByteSize());
+
+ switch (lldb::endian::InlHostByteOrder())
+ {
+ case eByteOrderBig: response.PutCString ("endian:big;"); break;
+ case eByteOrderLittle: response.PutCString ("endian:little;"); break;
+ case eByteOrderPDP: response.PutCString ("endian:pdp;"); break;
+ default: response.PutCString ("endian:unknown;"); break;
+ }
+
+ return SendPacket (response.GetString().c_str(),response.GetString().size()) > 0;
+}
Added: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h?rev=128070&view=auto
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h (added)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h Mon Mar 21 23:00:09 2011
@@ -0,0 +1,69 @@
+//===-- GDBRemoteCommunicationServer.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_GDBRemoteCommunicationServer_h_
+#define liblldb_GDBRemoteCommunicationServer_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "GDBRemoteCommunication.h"
+
+class ProcessGDBRemote;
+
+class GDBRemoteCommunicationServer : public GDBRemoteCommunication
+{
+public:
+ enum
+ {
+ eBroadcastBitRunPacketSent = kLoUserBroadcastBit
+ };
+ //------------------------------------------------------------------
+ // Constructors and Destructors
+ //------------------------------------------------------------------
+ GDBRemoteCommunicationServer();
+
+ virtual
+ ~GDBRemoteCommunicationServer();
+
+ bool
+ GetPacketAndSendResponse (const lldb_private::TimeValue* timeout_time_ptr);
+
+ virtual bool
+ GetThreadSuffixSupported ()
+ {
+ return true;
+ }
+
+ virtual bool
+ GetSendAcks ()
+ {
+ return m_send_acks;
+ }
+
+protected:
+ lldb::thread_t m_async_thread;
+ bool m_send_acks;
+
+ size_t
+ SendUnimplementedResponse ();
+
+
+ bool
+ Handle_qHostInfo ();
+
+private:
+ //------------------------------------------------------------------
+ // For GDBRemoteCommunicationServer only
+ //------------------------------------------------------------------
+ DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunicationServer);
+};
+
+#endif // liblldb_GDBRemoteCommunicationServer_h_
Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp?rev=128070&r1=128069&r2=128070&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp Mon Mar 21 23:00:09 2011
@@ -208,7 +208,7 @@
bool
GDBRemoteRegisterContext::ReadRegisterBytes (uint32_t reg, DataExtractor &data)
{
- GDBRemoteCommunication &gdb_comm = GetGDBProcess().GetGDBRemote();
+ GDBRemoteCommunicationClient &gdb_comm (GetGDBProcess().GetGDBRemote());
InvalidateIfNeeded(false);
@@ -235,7 +235,7 @@
assert (packet_len < (sizeof(packet) - 1));
if (gdb_comm.SendPacketAndWaitForResponse(packet, response, false))
{
- if (response.IsNormalPacket())
+ if (response.IsNormalResponse())
if (response.GetHexBytes ((void *)m_reg_data.GetDataStart(), m_reg_data.GetByteSize(), '\xcc') == m_reg_data.GetByteSize())
SetAllRegisterValid (true);
}
@@ -290,7 +290,7 @@
bool
GDBRemoteRegisterContext::WriteRegisterBytes (uint32_t reg, DataExtractor &data, uint32_t data_offset)
{
- GDBRemoteCommunication &gdb_comm = GetGDBProcess().GetGDBRemote();
+ GDBRemoteCommunicationClient &gdb_comm (GetGDBProcess().GetGDBRemote());
// FIXME: This check isn't right because IsRunning checks the Public state, but this
// is work you need to do - for instance in ShouldStop & friends - before the public
// state has been changed.
@@ -358,7 +358,7 @@
false))
{
SetAllRegisterValid (false);
- if (response.IsOKPacket())
+ if (response.IsOKResponse())
{
return true;
}
@@ -383,7 +383,7 @@
response,
false))
{
- if (response.IsOKPacket())
+ if (response.IsOKResponse())
{
return true;
}
@@ -399,7 +399,7 @@
bool
GDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
{
- GDBRemoteCommunication &gdb_comm = GetGDBProcess().GetGDBRemote();
+ GDBRemoteCommunicationClient &gdb_comm (GetGDBProcess().GetGDBRemote());
StringExtractorGDBRemote response;
Mutex::Locker locker;
@@ -418,7 +418,7 @@
if (gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
{
- if (response.IsErrorPacket())
+ if (response.IsErrorResponse())
return false;
response.GetStringRef().insert(0, 1, 'G');
@@ -443,7 +443,7 @@
if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0)
return false;
- GDBRemoteCommunication &gdb_comm = GetGDBProcess().GetGDBRemote();
+ GDBRemoteCommunicationClient &gdb_comm (GetGDBProcess().GetGDBRemote());
StringExtractorGDBRemote response;
Mutex::Locker locker;
if (gdb_comm.GetSequenceMutex (locker))
@@ -456,7 +456,7 @@
response,
false))
{
- if (response.IsOKPacket())
+ if (response.IsOKResponse())
return true;
}
}
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=128070&r1=128069&r2=128070&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Mon Mar 21 23:00:09 2011
@@ -170,18 +170,20 @@
char packet[128];
m_register_info.Clear();
- StringExtractorGDBRemote::Type packet_type = StringExtractorGDBRemote::eResponse;
uint32_t reg_offset = 0;
uint32_t reg_num = 0;
- for (; packet_type == StringExtractorGDBRemote::eResponse; ++reg_num)
+ StringExtractorGDBRemote::ResponseType response_type;
+ for (response_type = StringExtractorGDBRemote::eResponse;
+ response_type == StringExtractorGDBRemote::eResponse;
+ ++reg_num)
{
const int packet_len = ::snprintf (packet, sizeof(packet), "qRegisterInfo%x", reg_num);
assert (packet_len < sizeof(packet));
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
{
- packet_type = response.GetType();
- if (packet_type == StringExtractorGDBRemote::eResponse)
+ response_type = response.GetResponseType();
+ if (response_type == StringExtractorGDBRemote::eResponse)
{
std::string name;
std::string value;
@@ -298,7 +300,7 @@
}
else
{
- packet_type = StringExtractorGDBRemote::eError;
+ response_type = StringExtractorGDBRemote::eError;
}
}
@@ -1044,7 +1046,7 @@
Error err;
StringExtractorGDBRemote response;
for (m_gdb_comm.SendPacketAndWaitForResponse("qfThreadInfo", response, false);
- response.IsNormalPacket();
+ response.IsNormalResponse();
m_gdb_comm.SendPacketAndWaitForResponse("qsThreadInfo", response, false))
{
char ch = response.GetChar();
@@ -1460,7 +1462,7 @@
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse("qShlibInfoAddr", ::strlen ("qShlibInfoAddr"), response, false))
{
- if (response.IsNormalPacket())
+ if (response.IsNormalResponse())
return response.GetHexMaxU64(false, LLDB_INVALID_ADDRESS);
}
}
@@ -1487,14 +1489,14 @@
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true))
{
- if (response.IsNormalPacket())
+ if (response.IsNormalResponse())
{
error.Clear();
return response.GetHexBytes(buf, size, '\xdd');
}
- else if (response.IsErrorPacket())
+ else if (response.IsErrorResponse())
error.SetErrorStringWithFormat("gdb remote returned an error: %s", response.GetStringRef().c_str());
- else if (response.IsUnsupportedPacket())
+ else if (response.IsUnsupportedResponse())
error.SetErrorStringWithFormat("'%s' packet unsupported", packet);
else
error.SetErrorStringWithFormat("unexpected response to '%s': '%s'", packet, response.GetStringRef().c_str());
@@ -1515,14 +1517,14 @@
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse(packet.GetData(), packet.GetSize(), response, true))
{
- if (response.IsOKPacket())
+ if (response.IsOKResponse())
{
error.Clear();
return size;
}
- else if (response.IsErrorPacket())
+ else if (response.IsErrorResponse())
error.SetErrorStringWithFormat("gdb remote returned an error: %s", response.GetStringRef().c_str());
- else if (response.IsUnsupportedPacket())
+ else if (response.IsUnsupportedResponse())
error.SetErrorStringWithFormat("'%s' packet unsupported", packet.GetString().c_str());
else
error.SetErrorStringWithFormat("unexpected response to '%s': '%s'", packet.GetString().c_str(), response.GetStringRef().c_str());
@@ -1640,13 +1642,13 @@
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true))
{
- if (response.IsUnsupportedPacket())
+ if (response.IsUnsupportedResponse())
{
// Disable z packet support and try again
m_z0_supported = 0;
return EnableBreakpoint (bp_site);
}
- else if (response.IsOKPacket())
+ else if (response.IsOKResponse())
{
bp_site->SetEnabled(true);
bp_site->SetType (BreakpointSite::eExternal);
@@ -1708,11 +1710,11 @@
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, true))
{
- if (response.IsUnsupportedPacket())
+ if (response.IsUnsupportedResponse())
{
error.SetErrorString("Breakpoint site was set with Z packet, yet remote debugserver states z packets are not supported.");
}
- else if (response.IsOKPacket())
+ else if (response.IsOKResponse())
{
if (log)
log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %d) addr = 0x%8.8llx -- SUCCESS", site_id, (uint64_t)addr);
@@ -2121,7 +2123,7 @@
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
{
- if (response.IsOKPacket())
+ if (response.IsOKResponse())
{
m_curr_tid = tid;
return true;
@@ -2147,7 +2149,7 @@
StringExtractorGDBRemote response;
if (m_gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false))
{
- if (response.IsOKPacket())
+ if (response.IsOKResponse())
{
m_curr_tid_run = tid;
return true;
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=128070&r1=128069&r2=128070&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Mon Mar 21 23:00:09 2011
@@ -27,7 +27,7 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/Thread.h"
-#include "GDBRemoteCommunication.h"
+#include "GDBRemoteCommunicationClient.h"
#include "Utility/StringExtractor.h"
#include "GDBRemoteRegisterContext.h"
@@ -212,7 +212,7 @@
protected:
friend class ThreadGDBRemote;
- friend class GDBRemoteCommunication;
+ friend class GDBRemoteCommunicationClient;
friend class GDBRemoteRegisterContext;
bool
@@ -289,7 +289,7 @@
void
BuildDynamicRegisterInfo (bool force);
- GDBRemoteCommunication &
+ GDBRemoteCommunicationClient &
GetGDBRemote()
{
return m_gdb_comm;
@@ -306,7 +306,7 @@
lldb_private::Flags m_flags; // Process specific flags (see eFlags enums)
lldb_private::Mutex m_stdio_mutex; // Multithreaded protection for stdio
- GDBRemoteCommunication m_gdb_comm;
+ GDBRemoteCommunicationClient m_gdb_comm;
lldb::pid_t m_debugserver_pid;
lldb::thread_t m_debugserver_thread;
StringExtractor m_last_stop_packet;
Modified: lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp?rev=128070&r1=128069&r2=128070&view=diff
==============================================================================
--- lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp (original)
+++ lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp Mon Mar 21 23:00:09 2011
@@ -16,8 +16,8 @@
-StringExtractorGDBRemote::Type
-StringExtractorGDBRemote::GetType () const
+StringExtractorGDBRemote::ResponseType
+StringExtractorGDBRemote::GetResponseType () const
{
if (m_packet.empty())
return eUnsupported;
@@ -49,29 +49,57 @@
return eResponse;
}
+StringExtractorGDBRemote::ServerPacketType
+StringExtractorGDBRemote::GetServerPacketType () const
+{
+ // Empty is not a supported packet...
+ if (m_packet.empty())
+ return eServerPacketType_invalid;
+
+ const char *packet_cstr = m_packet.c_str();
+ switch (m_packet[0])
+ {
+ case '-':
+ if (m_packet.size() == 1)
+ return eServerPacketType_nack;
+ break;
+
+ case '+':
+ if (m_packet.size() == 1)
+ return eServerPacketType_ack;
+ break;
+
+ case 'q':
+ if (strcmp (packet_cstr, "qHostInfo") == 0)
+ return eServerPacketType_qHostInfo;
+ break;
+ }
+ return eServerPacketType_unimplemented;
+}
+
bool
-StringExtractorGDBRemote::IsOKPacket() const
+StringExtractorGDBRemote::IsOKResponse() const
{
- return GetType () == eOK;
+ return GetResponseType () == eOK;
}
bool
-StringExtractorGDBRemote::IsUnsupportedPacket() const
+StringExtractorGDBRemote::IsUnsupportedResponse() const
{
- return GetType () == eUnsupported;
+ return GetResponseType () == eUnsupported;
}
bool
-StringExtractorGDBRemote::IsNormalPacket() const
+StringExtractorGDBRemote::IsNormalResponse() const
{
- return GetType () == eResponse;
+ return GetResponseType () == eResponse;
}
bool
-StringExtractorGDBRemote::IsErrorPacket() const
+StringExtractorGDBRemote::IsErrorResponse() const
{
- return GetType () == eError &&
+ return GetResponseType () == eError &&
m_packet.size() == 3 &&
isxdigit(m_packet[1]) &&
isxdigit(m_packet[2]);
@@ -80,7 +108,7 @@
uint8_t
StringExtractorGDBRemote::GetError ()
{
- if (GetType() == eError)
+ if (GetResponseType() == eError)
{
SetFilePos(1);
return GetHexU8(255);
Modified: lldb/trunk/source/Utility/StringExtractorGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/StringExtractorGDBRemote.h?rev=128070&r1=128069&r2=128070&view=diff
==============================================================================
--- lldb/trunk/source/Utility/StringExtractorGDBRemote.h (original)
+++ lldb/trunk/source/Utility/StringExtractorGDBRemote.h Mon Mar 21 23:00:09 2011
@@ -39,30 +39,42 @@
{
}
- enum Type
+ enum ServerPacketType
+ {
+ eServerPacketType_nack = 0,
+ eServerPacketType_ack,
+ eServerPacketType_invalid,
+ eServerPacketType_unimplemented,
+ eServerPacketType_qHostInfo
+ };
+
+ ServerPacketType
+ GetServerPacketType () const;
+
+ enum ResponseType
{
eUnsupported = 0,
eAck,
eNack,
eError,
eOK,
- eResponse
+ eResponse,
};
- StringExtractorGDBRemote::Type
- GetType () const;
+ ResponseType
+ GetResponseType () const;
bool
- IsOKPacket() const;
+ IsOKResponse() const;
bool
- IsUnsupportedPacket() const;
+ IsUnsupportedResponse() const;
bool
- IsNormalPacket () const;
+ IsNormalResponse () const;
bool
- IsErrorPacket() const;
+ IsErrorResponse() const;
// Returns zero if the packet isn't a EXX packet where XX are two hex
// digits. Otherwise the error encoded in XX is returned.
Modified: lldb/trunk/tools/lldb-platform/lldb-platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-platform/lldb-platform.cpp?rev=128070&r1=128069&r2=128070&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-platform/lldb-platform.cpp (original)
+++ lldb/trunk/tools/lldb-platform/lldb-platform.cpp Mon Mar 21 23:00:09 2011
@@ -15,7 +15,7 @@
#include <stdlib.h>
#include <string.h>
-#include "GDBRemoteCommunication.h"
+#include "GDBRemoteCommunicationServer.h"
//----------------------------------------------------------------------
// option descriptors for getopt_long()
@@ -106,7 +106,7 @@
argv += optind;
- GDBRemoteCommunication gdb_comm;
+ GDBRemoteCommunicationServer gdb_comm;
return 0;
}
More information about the lldb-commits
mailing list