aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/Process
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-05-29 16:26:31 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-05-29 16:26:31 +0000
commit61b440f5005f0bf4e5864ba9cff4107ac56be404 (patch)
tree7d21c36d6cfd2c3053c6673f6303dceb45bc07c6 /source/Plugins/Process
parentfb19dde5bfd42a03786ee50e6b300e47c45ace47 (diff)
Vendor import of lldb trunk r304149:vendor/lldb/lldb-trunk-r304149
Notes
Notes: svn path=/vendor/lldb/dist/; revision=319150 svn path=/vendor/lldb/lldb-trunk-r304149/; revision=319151; tag=vendor/lldb/lldb-trunk-r304149
Diffstat (limited to 'source/Plugins/Process')
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.cpp4
-rw-r--r--source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp31
-rw-r--r--source/Plugins/Process/NetBSD/NativeProcessNetBSD.h2
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp206
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h21
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp241
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h8
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp26
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.h16
9 files changed, 542 insertions, 13 deletions
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
index 1667490f1344..34d99cd39de2 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
@@ -1132,6 +1132,10 @@ ProcessMessage ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor,
case 0:
case TRAP_TRACE:
+#ifdef TRAP_CAP
+ // Map TRAP_CAP to a trace trap in the absense of a more specific handler.
+ case TRAP_CAP:
+#endif
if (log)
log->Printf("ProcessMonitor::%s() received trace event, tid = %" PRIu64
" : si_code = %d",
diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
index 80751147b4f5..efb19fc414f9 100644
--- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -167,8 +167,6 @@ NativeProcessNetBSD::NativeProcessNetBSD()
// Handles all waitpid events from the inferior process.
void NativeProcessNetBSD::MonitorCallback(lldb::pid_t pid, int signal) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
switch (signal) {
case SIGTRAP:
return MonitorSIGTRAP(pid);
@@ -196,7 +194,6 @@ void NativeProcessNetBSD::MonitorExited(lldb::pid_t pid, int signal,
}
void NativeProcessNetBSD::MonitorSIGSTOP(lldb::pid_t pid) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
ptrace_siginfo_t info;
const auto siginfo_err =
@@ -305,8 +302,6 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
}
void NativeProcessNetBSD::MonitorSignal(lldb::pid_t pid, int signal) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
ptrace_siginfo_t info;
const auto siginfo_err =
PtraceWrapper(PT_GET_SIGINFO, pid, &info, sizeof(info));
@@ -898,6 +893,19 @@ void NativeProcessNetBSD::SigchldHandler() {
MonitorCallback(wait_pid, signal);
}
+bool NativeProcessNetBSD::HasThreadNoLock(lldb::tid_t thread_id) {
+ for (auto thread_sp : m_threads) {
+ assert(thread_sp && "thread list should not contain NULL threads");
+ if (thread_sp->GetID() == thread_id) {
+ // We have this thread.
+ return true;
+ }
+ }
+
+ // We don't have this thread.
+ return false;
+}
+
NativeThreadNetBSDSP NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_THREAD));
@@ -916,8 +924,6 @@ NativeThreadNetBSDSP NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) {
}
::pid_t NativeProcessNetBSD::Attach(lldb::pid_t pid, Status &error) {
- Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
if (pid <= 1) {
error.SetErrorToGenericError();
error.SetErrorString("Attaching to process 1 is not allowed.");
@@ -1006,7 +1012,7 @@ Status NativeProcessNetBSD::WriteMemory(lldb::addr_t addr, const void *buf,
io.piod_len = size;
do {
- io.piod_addr = (void *)(src + bytes_written);
+ io.piod_addr = const_cast<void *>(static_cast<const void *>(src + bytes_written));
io.piod_offs = (void *)(addr + bytes_written);
Status error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io);
@@ -1034,10 +1040,11 @@ NativeProcessNetBSD::GetAuxvData() const {
ErrorOr<std::unique_ptr<MemoryBuffer>> buf =
llvm::MemoryBuffer::getNewMemBuffer(auxv_size);
- struct ptrace_io_desc io = {.piod_op = PIOD_READ_AUXV,
- .piod_offs = 0,
- .piod_addr = (void *)buf.get()->getBufferStart(),
- .piod_len = auxv_size};
+ struct ptrace_io_desc io;
+ io.piod_op = PIOD_READ_AUXV;
+ io.piod_offs = 0;
+ io.piod_addr = const_cast<void *>(static_cast<const void *>(buf.get()->getBufferStart()));
+ io.piod_len = auxv_size;
Status error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io);
diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
index e18ba162e523..758956e3dca1 100644
--- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
+++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
@@ -115,6 +115,8 @@ private:
// ---------------------------------------------------------------------
NativeProcessNetBSD();
+ bool HasThreadNoLock(lldb::tid_t thread_id);
+
NativeThreadNetBSDSP AddThread(lldb::tid_t thread_id);
Status LaunchInferior(MainLoop &mainloop, ProcessLaunchInfo &launch_info);
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 550ec0ea499a..33aed7a43c4a 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -30,7 +30,6 @@
#include "lldb/Utility/JSON.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Log.h"
-#include "lldb/Utility/StreamGDBRemote.h"
#include "lldb/Utility/StreamString.h"
// Project includes
@@ -3152,6 +3151,211 @@ bool GDBRemoteCommunicationClient::SyncThreadState(lldb::tid_t tid) {
response.IsOKResponse();
}
+lldb::user_id_t
+GDBRemoteCommunicationClient::SendStartTracePacket(const TraceOptions &options,
+ Status &error) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ lldb::user_id_t ret_uid = LLDB_INVALID_UID;
+
+ StreamGDBRemote escaped_packet;
+ escaped_packet.PutCString("jTraceStart:");
+
+ StructuredData::Dictionary json_packet;
+ json_packet.AddIntegerItem("type", options.getType());
+ json_packet.AddIntegerItem("buffersize", options.getTraceBufferSize());
+ json_packet.AddIntegerItem("metabuffersize", options.getMetaDataBufferSize());
+
+ if (options.getThreadID() != LLDB_INVALID_THREAD_ID)
+ json_packet.AddIntegerItem("threadid", options.getThreadID());
+
+ StructuredData::DictionarySP custom_params = options.getTraceParams();
+ if (custom_params)
+ json_packet.AddItem("params", custom_params);
+
+ StreamString json_string;
+ json_packet.Dump(json_string, false);
+ escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
+ true) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ if (!response.IsNormalResponse()) {
+ error.SetError(response.GetError(), eErrorTypeGeneric);
+ LLDB_LOG(log, "Target does not support Tracing");
+ } else {
+ ret_uid = response.GetHexMaxU64(false, LLDB_INVALID_UID);
+ }
+ } else {
+ LLDB_LOG(log, "failed to send packet");
+ error.SetErrorStringWithFormat("failed to send packet: '%s'",
+ escaped_packet.GetData());
+ }
+ return ret_uid;
+}
+
+Status
+GDBRemoteCommunicationClient::SendStopTracePacket(lldb::user_id_t uid,
+ lldb::tid_t thread_id) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ StringExtractorGDBRemote response;
+ Status error;
+
+ StructuredData::Dictionary json_packet;
+ StreamGDBRemote escaped_packet;
+ StreamString json_string;
+ escaped_packet.PutCString("jTraceStop:");
+
+ json_packet.AddIntegerItem("traceid", uid);
+
+ if (thread_id != LLDB_INVALID_THREAD_ID)
+ json_packet.AddIntegerItem("threadid", thread_id);
+
+ json_packet.Dump(json_string, false);
+
+ escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
+
+ if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
+ true) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ if (!response.IsOKResponse()) {
+ error.SetError(response.GetError(), eErrorTypeGeneric);
+ LLDB_LOG(log, "stop tracing failed");
+ }
+ } else {
+ LLDB_LOG(log, "failed to send packet");
+ error.SetErrorStringWithFormat(
+ "failed to send packet: '%s' with error '%d'", escaped_packet.GetData(),
+ response.GetError());
+ }
+ return error;
+}
+
+Status GDBRemoteCommunicationClient::SendGetDataPacket(
+ lldb::user_id_t uid, lldb::tid_t thread_id,
+ llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
+ StreamGDBRemote escaped_packet;
+ escaped_packet.PutCString("jTraceBufferRead:");
+ return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
+}
+
+Status GDBRemoteCommunicationClient::SendGetMetaDataPacket(
+ lldb::user_id_t uid, lldb::tid_t thread_id,
+ llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
+ StreamGDBRemote escaped_packet;
+ escaped_packet.PutCString("jTraceMetaRead:");
+ return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
+}
+
+Status
+GDBRemoteCommunicationClient::SendGetTraceConfigPacket(lldb::user_id_t uid,
+ TraceOptions &options) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ StringExtractorGDBRemote response;
+ Status error;
+
+ StreamString json_string;
+ StreamGDBRemote escaped_packet;
+ escaped_packet.PutCString("jTraceConfigRead:");
+
+ StructuredData::Dictionary json_packet;
+ json_packet.AddIntegerItem("traceid", uid);
+
+ if (options.getThreadID() != LLDB_INVALID_THREAD_ID)
+ json_packet.AddIntegerItem("threadid", options.getThreadID());
+
+ json_packet.Dump(json_string, false);
+ escaped_packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
+
+ if (SendPacketAndWaitForResponse(escaped_packet.GetString(), response,
+ true) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ if (response.IsNormalResponse()) {
+ uint64_t type = std::numeric_limits<uint64_t>::max();
+ uint64_t buffersize = std::numeric_limits<uint64_t>::max();
+ uint64_t metabuffersize = std::numeric_limits<uint64_t>::max();
+
+ auto json_object = StructuredData::ParseJSON(response.Peek());
+
+ if (!json_object ||
+ json_object->GetType() != lldb::eStructuredDataTypeDictionary) {
+ error.SetErrorString("Invalid Configuration obtained");
+ return error;
+ }
+
+ auto json_dict = json_object->GetAsDictionary();
+
+ json_dict->GetValueForKeyAsInteger<uint64_t>("metabuffersize",
+ metabuffersize);
+ options.setMetaDataBufferSize(metabuffersize);
+
+ json_dict->GetValueForKeyAsInteger<uint64_t>("buffersize", buffersize);
+ options.setTraceBufferSize(buffersize);
+
+ json_dict->GetValueForKeyAsInteger<uint64_t>("type", type);
+ options.setType(static_cast<lldb::TraceType>(type));
+
+ StructuredData::ObjectSP custom_params_sp =
+ json_dict->GetValueForKey("params");
+ if (custom_params_sp) {
+ if (custom_params_sp->GetType() !=
+ lldb::eStructuredDataTypeDictionary) {
+ error.SetErrorString("Invalid Configuration obtained");
+ return error;
+ } else
+ options.setTraceParams(
+ static_pointer_cast<StructuredData::Dictionary>(
+ custom_params_sp));
+ }
+ } else {
+ error.SetError(response.GetError(), eErrorTypeGeneric);
+ }
+ } else {
+ LLDB_LOG(log, "failed to send packet");
+ error.SetErrorStringWithFormat("failed to send packet: '%s'",
+ escaped_packet.GetData());
+ }
+ return error;
+}
+
+Status GDBRemoteCommunicationClient::SendGetTraceDataPacket(
+ StreamGDBRemote &packet, lldb::user_id_t uid, lldb::tid_t thread_id,
+ llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
+ Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ Status error;
+
+ StructuredData::Dictionary json_packet;
+
+ json_packet.AddIntegerItem("traceid", uid);
+ json_packet.AddIntegerItem("offset", offset);
+ json_packet.AddIntegerItem("buffersize", buffer.size());
+
+ if (thread_id != LLDB_INVALID_THREAD_ID)
+ json_packet.AddIntegerItem("threadid", thread_id);
+
+ StreamString json_string;
+ json_packet.Dump(json_string, false);
+
+ packet.PutEscapedBytes(json_string.GetData(), json_string.GetSize());
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse(packet.GetString(), response, true) ==
+ GDBRemoteCommunication::PacketResult::Success) {
+ if (response.IsNormalResponse()) {
+ size_t filled_size = response.GetHexBytesAvail(buffer);
+ buffer = llvm::MutableArrayRef<uint8_t>(buffer.data(), filled_size);
+ } else {
+ error.SetError(response.GetError(), eErrorTypeGeneric);
+ buffer = buffer.slice(buffer.size());
+ }
+ } else {
+ LLDB_LOG(log, "failed to send packet");
+ error.SetErrorStringWithFormat("failed to send packet: '%s'",
+ packet.GetData());
+ buffer = buffer.slice(buffer.size());
+ }
+ return error;
+}
+
bool GDBRemoteCommunicationClient::GetModuleInfo(
const FileSpec &module_file_spec, const lldb_private::ArchSpec &arch_spec,
ModuleSpec &module_spec) {
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 08d0bd5d690b..6306651da7a1 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -25,6 +25,7 @@
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/Target/Process.h"
+#include "lldb/Utility/StreamGDBRemote.h"
#include "llvm/ADT/Optional.h"
@@ -499,6 +500,21 @@ public:
ConfigureRemoteStructuredData(const ConstString &type_name,
const StructuredData::ObjectSP &config_sp);
+ lldb::user_id_t SendStartTracePacket(const TraceOptions &options,
+ Status &error);
+
+ Status SendStopTracePacket(lldb::user_id_t uid, lldb::tid_t thread_id);
+
+ Status SendGetDataPacket(lldb::user_id_t uid, lldb::tid_t thread_id,
+ llvm::MutableArrayRef<uint8_t> &buffer,
+ size_t offset = 0);
+
+ Status SendGetMetaDataPacket(lldb::user_id_t uid, lldb::tid_t thread_id,
+ llvm::MutableArrayRef<uint8_t> &buffer,
+ size_t offset = 0);
+
+ Status SendGetTraceConfigPacket(lldb::user_id_t uid, TraceOptions &options);
+
protected:
LazyBool m_supports_not_sending_acks;
LazyBool m_supports_thread_suffix;
@@ -587,6 +603,11 @@ protected:
lldb::tid_t tid, StreamString &&payload,
StringExtractorGDBRemote &response, bool send_async);
+ Status SendGetTraceDataPacket(StreamGDBRemote &packet, lldb::user_id_t uid,
+ lldb::tid_t thread_id,
+ llvm::MutableArrayRef<uint8_t> &buffer,
+ size_t offset);
+
private:
DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationClient);
};
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index ec7c2f5330d7..d318c35366f1 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -183,6 +183,22 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
StringExtractorGDBRemote::eServerPacketType_QPassSignals,
&GDBRemoteCommunicationServerLLGS::Handle_QPassSignals);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_jTraceStart,
+ &GDBRemoteCommunicationServerLLGS::Handle_jTraceStart);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_jTraceBufferRead,
+ &GDBRemoteCommunicationServerLLGS::Handle_jTraceRead);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_jTraceMetaRead,
+ &GDBRemoteCommunicationServerLLGS::Handle_jTraceRead);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_jTraceStop,
+ &GDBRemoteCommunicationServerLLGS::Handle_jTraceStop);
+ RegisterMemberFunctionHandler(
+ StringExtractorGDBRemote::eServerPacketType_jTraceConfigRead,
+ &GDBRemoteCommunicationServerLLGS::Handle_jTraceConfigRead);
+
RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_k,
[this](StringExtractorGDBRemote packet, Status &error,
bool &interrupt, bool &quit) {
@@ -1084,6 +1100,231 @@ void GDBRemoteCommunicationServerLLGS::SendProcessOutput() {
}
GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_jTraceStart(
+ StringExtractorGDBRemote &packet) {
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(68);
+
+ if (!packet.ConsumeFront("jTraceStart:"))
+ return SendIllFormedResponse(packet, "jTraceStart: Ill formed packet ");
+
+ TraceOptions options;
+ uint64_t type = std::numeric_limits<uint64_t>::max();
+ uint64_t buffersize = std::numeric_limits<uint64_t>::max();
+ lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
+ uint64_t metabuffersize = std::numeric_limits<uint64_t>::max();
+
+ auto json_object = StructuredData::ParseJSON(packet.Peek());
+
+ if (!json_object ||
+ json_object->GetType() != lldb::eStructuredDataTypeDictionary)
+ return SendIllFormedResponse(packet, "jTraceStart: Ill formed packet ");
+
+ auto json_dict = json_object->GetAsDictionary();
+
+ json_dict->GetValueForKeyAsInteger("metabuffersize", metabuffersize);
+ options.setMetaDataBufferSize(metabuffersize);
+
+ json_dict->GetValueForKeyAsInteger("buffersize", buffersize);
+ options.setTraceBufferSize(buffersize);
+
+ json_dict->GetValueForKeyAsInteger("type", type);
+ options.setType(static_cast<lldb::TraceType>(type));
+
+ json_dict->GetValueForKeyAsInteger("threadid", tid);
+ options.setThreadID(tid);
+
+ StructuredData::ObjectSP custom_params_sp =
+ json_dict->GetValueForKey("params");
+ if (custom_params_sp &&
+ custom_params_sp->GetType() != lldb::eStructuredDataTypeDictionary)
+ return SendIllFormedResponse(packet, "jTraceStart: Ill formed packet ");
+
+ options.setTraceParams(
+ static_pointer_cast<StructuredData::Dictionary>(custom_params_sp));
+
+ if (buffersize == std::numeric_limits<uint64_t>::max() ||
+ type != lldb::TraceType::eTraceTypeProcessorTrace) {
+ LLDB_LOG(log, "Ill formed packet buffersize = {0} type = {1}", buffersize,
+ type);
+ return SendIllFormedResponse(packet, "JTrace:start: Ill formed packet ");
+ }
+
+ Status error;
+ lldb::user_id_t uid = LLDB_INVALID_UID;
+ uid = m_debugged_process_sp->StartTrace(options, error);
+ LLDB_LOG(log, "uid is {0} , error is {1}", uid, error.GetError());
+ if (error.Fail())
+ return SendErrorResponse(error.GetError());
+
+ StreamGDBRemote response;
+ response.Printf("%" PRIx64, uid);
+ return SendPacketNoLock(response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_jTraceStop(
+ StringExtractorGDBRemote &packet) {
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(68);
+
+ if (!packet.ConsumeFront("jTraceStop:"))
+ return SendIllFormedResponse(packet, "jTraceStop: Ill formed packet ");
+
+ lldb::user_id_t uid = LLDB_INVALID_UID;
+ lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
+
+ auto json_object = StructuredData::ParseJSON(packet.Peek());
+
+ if (!json_object ||
+ json_object->GetType() != lldb::eStructuredDataTypeDictionary)
+ return SendIllFormedResponse(packet, "jTraceStop: Ill formed packet ");
+
+ auto json_dict = json_object->GetAsDictionary();
+
+ if (!json_dict->GetValueForKeyAsInteger("traceid", uid))
+ return SendIllFormedResponse(packet, "jTraceStop: Ill formed packet ");
+
+ json_dict->GetValueForKeyAsInteger("threadid", tid);
+
+ Status error = m_debugged_process_sp->StopTrace(uid, tid);
+
+ if (error.Fail())
+ return SendErrorResponse(error.GetError());
+
+ return SendOKResponse();
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_jTraceConfigRead(
+ StringExtractorGDBRemote &packet) {
+
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(68);
+
+ if (!packet.ConsumeFront("jTraceConfigRead:"))
+ return SendIllFormedResponse(packet,
+ "jTraceConfigRead: Ill formed packet ");
+
+ lldb::user_id_t uid = LLDB_INVALID_UID;
+ lldb::tid_t threadid = LLDB_INVALID_THREAD_ID;
+
+ auto json_object = StructuredData::ParseJSON(packet.Peek());
+
+ if (!json_object ||
+ json_object->GetType() != lldb::eStructuredDataTypeDictionary)
+ return SendIllFormedResponse(packet,
+ "jTraceConfigRead: Ill formed packet ");
+
+ auto json_dict = json_object->GetAsDictionary();
+
+ if (!json_dict->GetValueForKeyAsInteger("traceid", uid))
+ return SendIllFormedResponse(packet,
+ "jTraceConfigRead: Ill formed packet ");
+
+ json_dict->GetValueForKeyAsInteger("threadid", threadid);
+
+ TraceOptions options;
+ StreamGDBRemote response;
+
+ options.setThreadID(threadid);
+ Status error = m_debugged_process_sp->GetTraceConfig(uid, options);
+
+ if (error.Fail())
+ return SendErrorResponse(error.GetError());
+
+ StreamGDBRemote escaped_response;
+ StructuredData::Dictionary json_packet;
+
+ json_packet.AddIntegerItem("type", options.getType());
+ json_packet.AddIntegerItem("buffersize", options.getTraceBufferSize());
+ json_packet.AddIntegerItem("metabuffersize", options.getMetaDataBufferSize());
+
+ StructuredData::DictionarySP custom_params = options.getTraceParams();
+ if (custom_params)
+ json_packet.AddItem("params", custom_params);
+
+ StreamString json_string;
+ json_packet.Dump(json_string, false);
+ escaped_response.PutEscapedBytes(json_string.GetData(),
+ json_string.GetSize());
+ return SendPacketNoLock(escaped_response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_jTraceRead(
+ StringExtractorGDBRemote &packet) {
+
+ // Fail if we don't have a current process.
+ if (!m_debugged_process_sp ||
+ (m_debugged_process_sp->GetID() == LLDB_INVALID_PROCESS_ID))
+ return SendErrorResponse(68);
+
+ enum PacketType { MetaData, BufferData };
+ PacketType tracetype = MetaData;
+
+ if (packet.ConsumeFront("jTraceBufferRead:"))
+ tracetype = BufferData;
+ else if (packet.ConsumeFront("jTraceMetaRead:"))
+ tracetype = MetaData;
+ else {
+ return SendIllFormedResponse(packet, "jTrace: Ill formed packet ");
+ }
+
+ lldb::user_id_t uid = LLDB_INVALID_UID;
+
+ size_t byte_count = std::numeric_limits<size_t>::max();
+ lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
+ size_t offset = std::numeric_limits<size_t>::max();
+
+ auto json_object = StructuredData::ParseJSON(packet.Peek());
+
+ if (!json_object ||
+ json_object->GetType() != lldb::eStructuredDataTypeDictionary)
+ return SendIllFormedResponse(packet, "jTrace: Ill formed packet ");
+
+ auto json_dict = json_object->GetAsDictionary();
+
+ if (!json_dict->GetValueForKeyAsInteger("traceid", uid) ||
+ !json_dict->GetValueForKeyAsInteger("offset", offset) ||
+ !json_dict->GetValueForKeyAsInteger("buffersize", byte_count))
+ return SendIllFormedResponse(packet, "jTrace: Ill formed packet ");
+
+ json_dict->GetValueForKeyAsInteger("threadid", tid);
+
+ // Allocate the response buffer.
+ std::unique_ptr<uint8_t[]> buffer (new (std::nothrow) uint8_t[byte_count]);
+ if (!buffer)
+ return SendErrorResponse(0x78);
+
+ StreamGDBRemote response;
+ Status error;
+ llvm::MutableArrayRef<uint8_t> buf(buffer.get(), byte_count);
+
+ if (tracetype == BufferData)
+ error = m_debugged_process_sp->GetData(uid, tid, buf, offset);
+ else if (tracetype == MetaData)
+ error = m_debugged_process_sp->GetMetaData(uid, tid, buf, offset);
+
+ if (error.Fail())
+ return SendErrorResponse(error.GetError());
+
+ for (size_t i = 0; i < buf.size(); ++i)
+ response.PutHex8(buf[i]);
+
+ StreamGDBRemote escaped_response;
+ escaped_response.PutEscapedBytes(response.GetData(), response.GetSize());
+ return SendPacketNoLock(escaped_response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo(
StringExtractorGDBRemote &packet) {
// Fail if we don't have a current process.
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index ebda9a911d3c..a7d7850d454f 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -189,6 +189,14 @@ protected:
PacketResult Handle_QSaveRegisterState(StringExtractorGDBRemote &packet);
+ PacketResult Handle_jTraceStart(StringExtractorGDBRemote &packet);
+
+ PacketResult Handle_jTraceRead(StringExtractorGDBRemote &packet);
+
+ PacketResult Handle_jTraceStop(StringExtractorGDBRemote &packet);
+
+ PacketResult Handle_jTraceConfigRead(StringExtractorGDBRemote &packet);
+
PacketResult Handle_QRestoreRegisterState(StringExtractorGDBRemote &packet);
PacketResult Handle_vAttach(StringExtractorGDBRemote &packet);
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 64684c5963b3..aeb7c742b4f4 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1236,6 +1236,32 @@ Status ProcessGDBRemote::DoAttachToProcessWithName(
return error;
}
+lldb::user_id_t ProcessGDBRemote::StartTrace(const TraceOptions &options,
+ Status &error) {
+ return m_gdb_comm.SendStartTracePacket(options, error);
+}
+
+Status ProcessGDBRemote::StopTrace(lldb::user_id_t uid, lldb::tid_t thread_id) {
+ return m_gdb_comm.SendStopTracePacket(uid, thread_id);
+}
+
+Status ProcessGDBRemote::GetData(lldb::user_id_t uid, lldb::tid_t thread_id,
+ llvm::MutableArrayRef<uint8_t> &buffer,
+ size_t offset) {
+ return m_gdb_comm.SendGetDataPacket(uid, thread_id, buffer, offset);
+}
+
+Status ProcessGDBRemote::GetMetaData(lldb::user_id_t uid, lldb::tid_t thread_id,
+ llvm::MutableArrayRef<uint8_t> &buffer,
+ size_t offset) {
+ return m_gdb_comm.SendGetMetaDataPacket(uid, thread_id, buffer, offset);
+}
+
+Status ProcessGDBRemote::GetTraceConfig(lldb::user_id_t uid,
+ TraceOptions &options) {
+ return m_gdb_comm.SendGetTraceConfigPacket(uid, options);
+}
+
void ProcessGDBRemote::DidExit() {
// When we exit, disconnect from the GDB server communications
m_gdb_comm.Disconnect();
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 60f0464f86bb..d7a4e961b540 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -31,6 +31,7 @@
#include "lldb/Target/Thread.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Status.h"
+#include "lldb/Utility/StreamGDBRemote.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/Utility/StringExtractor.h"
#include "lldb/Utility/StringList.h"
@@ -177,6 +178,21 @@ public:
Status GetWatchpointSupportInfo(uint32_t &num) override;
+ lldb::user_id_t StartTrace(const TraceOptions &options,
+ Status &error) override;
+
+ Status StopTrace(lldb::user_id_t uid, lldb::tid_t thread_id) override;
+
+ Status GetData(lldb::user_id_t uid, lldb::tid_t thread_id,
+ llvm::MutableArrayRef<uint8_t> &buffer,
+ size_t offset = 0) override;
+
+ Status GetMetaData(lldb::user_id_t uid, lldb::tid_t thread_id,
+ llvm::MutableArrayRef<uint8_t> &buffer,
+ size_t offset = 0) override;
+
+ Status GetTraceConfig(lldb::user_id_t uid, TraceOptions &options) override;
+
Status GetWatchpointSupportInfo(uint32_t &num, bool &after) override;
bool StartNoticingNewThreads() override;