mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-27 15:28:53 -04:00

Modifed lldb_private::Process to be able to handle connecting to a remote target that isn't running a process. This leaves lldb_private::Process in the eStateConnected state from which we can then do an attach or launch. Modified ProcessGDBRemote to be able to set stdin, stdout, stderr, working dir, disable ASLR and a few other settings down by using new GDB remote packets. This allows us to keep all of our current launch flags and settings intact and still be able to communicate them over to the remote GDB server. Previously these were being sent as arguments to the debugserver binary that we were spawning. Also modified ProcessGDBRemote to handle losing connection to the remote GDB server and always exit immediately. We do this by watching the lldb_private::Communication event bit for the read thread exiting in the ProcessGDBRemote async thread. Added support for many of the new 'Q' packets for setting stdin, stdout, stderr, working dir and disable ASLR to the GDBRemoteCommunication class for easy accesss. Modified debugserver for all of the new 'Q' packets and also made it so that debugserver always exists if it loses connection with the remote debugger. llvm-svn: 126444
364 lines
12 KiB
C++
364 lines
12 KiB
C++
//===-- GDBRemoteCommunication.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_GDBRemoteCommunication_h_
|
|
#define liblldb_GDBRemoteCommunication_h_
|
|
|
|
// C Includes
|
|
// C++ Includes
|
|
#include <list>
|
|
#include <string>
|
|
|
|
// 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"
|
|
|
|
#include "Utility/StringExtractorGDBRemote.h"
|
|
|
|
class ProcessGDBRemote;
|
|
|
|
class GDBRemoteCommunication :
|
|
public lldb_private::Communication
|
|
{
|
|
public:
|
|
enum
|
|
{
|
|
eBroadcastBitRunPacketSent = kLoUserBroadcastBit
|
|
};
|
|
//------------------------------------------------------------------
|
|
// Constructors and Destructors
|
|
//------------------------------------------------------------------
|
|
GDBRemoteCommunication();
|
|
|
|
virtual
|
|
~GDBRemoteCommunication();
|
|
|
|
size_t
|
|
SendPacket (const char *payload);
|
|
|
|
size_t
|
|
SendPacket (const char *payload,
|
|
size_t payload_length);
|
|
|
|
size_t
|
|
SendPacketAndWaitForResponse (const char *send_payload,
|
|
StringExtractorGDBRemote &response,
|
|
uint32_t timeout_seconds,
|
|
bool send_async);
|
|
|
|
size_t
|
|
SendPacketAndWaitForResponse (const char *send_payload,
|
|
size_t send_length,
|
|
StringExtractorGDBRemote &response,
|
|
uint32_t timeout_seconds,
|
|
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,
|
|
uint32_t nsec);
|
|
|
|
// Wait for a packet with an absolute timeout time. If 'timeout' is NULL
|
|
// wait indefinitely.
|
|
size_t
|
|
WaitForPacket (StringExtractorGDBRemote &response,
|
|
const lldb_private::TimeValue* timeout);
|
|
|
|
char
|
|
GetAck (uint32_t timeout_seconds);
|
|
|
|
size_t
|
|
SendAck ();
|
|
|
|
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);
|
|
|
|
//------------------------------------------------------------------
|
|
// Communication overrides
|
|
//------------------------------------------------------------------
|
|
virtual void
|
|
AppendBytesToCache (const uint8_t *src, size_t src_len, bool broadcast, lldb::ConnectionStatus status);
|
|
|
|
|
|
lldb::pid_t
|
|
GetCurrentProcessID (uint32_t timeout_seconds);
|
|
|
|
bool
|
|
GetLaunchSuccess (uint32_t timeout_seconds, 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.
|
|
///
|
|
/// @param[in] timeout_seconds
|
|
/// The number of seconds to wait for a response from the remote
|
|
/// server.
|
|
///
|
|
/// @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[], uint32_t timeout_seconds);
|
|
|
|
//------------------------------------------------------------------
|
|
/// 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".
|
|
///
|
|
/// @param[in] timeout_seconds
|
|
/// The number of seconds to wait for a response from the remote
|
|
/// server.
|
|
///
|
|
/// @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,
|
|
uint32_t timeout_seconds);
|
|
|
|
//------------------------------------------------------------------
|
|
/// Sends a "vAttach:PID" where PID is in hex.
|
|
///
|
|
/// @param[in] pid
|
|
/// A process ID for the remote gdb server to attach to.
|
|
///
|
|
/// @param[in] timeout_seconds
|
|
/// The number of seconds to wait for a response from the remote
|
|
/// server.
|
|
///
|
|
/// @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,
|
|
uint32_t timeout_seconds,
|
|
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, uint32_t timeout_seconds);
|
|
|
|
bool
|
|
DeallocateMemory (lldb::addr_t addr, uint32_t timeout_seconds);
|
|
|
|
bool
|
|
IsRunning() const
|
|
{
|
|
return m_public_is_running.GetValue();
|
|
}
|
|
|
|
bool
|
|
WaitForNotRunning (const lldb_private::TimeValue *timeout_ptr);
|
|
|
|
bool
|
|
GetHostInfo (uint32_t timeout_seconds);
|
|
|
|
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');
|
|
}
|
|
|
|
bool
|
|
HasAnyVContSupport ()
|
|
{
|
|
return GetVContSupported ('a');
|
|
}
|
|
|
|
protected:
|
|
typedef std::list<std::string> packet_collection;
|
|
|
|
size_t
|
|
SendPacketNoLock (const char *payload,
|
|
size_t payload_length);
|
|
|
|
size_t
|
|
WaitForPacketNoLock (StringExtractorGDBRemote &response,
|
|
const lldb_private::TimeValue* timeout_ptr);
|
|
|
|
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
|
|
//------------------------------------------------------------------
|
|
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;
|
|
uint32_t m_async_timeout;
|
|
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
|
|
//------------------------------------------------------------------
|
|
DISALLOW_COPY_AND_ASSIGN (GDBRemoteCommunication);
|
|
};
|
|
|
|
#endif // liblldb_GDBRemoteCommunication_h_
|