diff options
Diffstat (limited to 'source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp')
| -rw-r--r-- | source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp | 241 | 
1 files changed, 241 insertions, 0 deletions
| 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. | 
