LLDB  mainline
GDBRemoteCommunicationServer.cpp
Go to the documentation of this file.
1 //===-- GDBRemoteCommunicationServer.cpp ----------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include <cerrno>
10 
11 #include "lldb/Host/Config.h"
12 
14 
15 #include "ProcessGDBRemoteLog.h"
19 #include "llvm/Support/JSON.h"
20 #include <cstring>
21 
22 using namespace lldb;
23 using namespace lldb_private;
24 using namespace lldb_private::process_gdb_remote;
25 using namespace llvm;
26 
27 GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(
28  const char *comm_name, const char *listener_name)
29  : GDBRemoteCommunication(comm_name, listener_name), m_exit_now(false) {
32  [this](StringExtractorGDBRemote packet, Status &error, bool &interrupt,
33  bool &quit) { return this->Handle_QErrorStringEnable(packet); });
34 }
35 
37 
40  PacketHandler handler) {
41  m_packet_handlers[packet_type] = std::move(handler);
42 }
43 
46  Timeout<std::micro> timeout, Status &error, bool &interrupt, bool &quit) {
48 
49  PacketResult packet_result = WaitForPacketNoLock(packet, timeout, false);
50  if (packet_result == PacketResult::Success) {
52  packet.GetServerPacketType();
53  switch (packet_type) {
56  break;
57 
59  error.SetErrorString("invalid packet");
60  quit = true;
61  break;
62 
64  packet_result = SendUnimplementedResponse(packet.GetStringRef().data());
65  break;
66 
67  default:
68  auto handler_it = m_packet_handlers.find(packet_type);
69  if (handler_it == m_packet_handlers.end())
70  packet_result = SendUnimplementedResponse(packet.GetStringRef().data());
71  else
72  packet_result = handler_it->second(packet, error, interrupt, quit);
73  break;
74  }
75  } else {
76  if (!IsConnected()) {
77  error.SetErrorString("lost connection");
78  quit = true;
79  } else {
80  error.SetErrorString("timeout");
81  }
82  }
83 
84  // Check if anything occurred that would force us to want to exit.
85  if (m_exit_now)
86  quit = true;
87 
88  return packet_result;
89 }
90 
93  // TODO: Log the packet we aren't handling...
94  return SendPacketNoLock("");
95 }
96 
99  char packet[16];
100  int packet_len = ::snprintf(packet, sizeof(packet), "E%2.2x", err);
101  assert(packet_len < (int)sizeof(packet));
102  return SendPacketNoLock(llvm::StringRef(packet, packet_len));
103 }
104 
107  if (m_send_error_strings) {
109  packet.Printf("E%2.2x;", static_cast<uint8_t>(error.GetError()));
110  packet.PutStringAsRawHex8(error.AsCString());
111  return SendPacketNoLock(packet.GetString());
112  } else
113  return SendErrorResponse(error.GetError());
114 }
115 
118  assert(error);
119  std::unique_ptr<llvm::ErrorInfoBase> EIB;
120  std::unique_ptr<UnimplementedError> UE;
121  llvm::handleAllErrors(
122  std::move(error),
123  [&](std::unique_ptr<UnimplementedError> E) { UE = std::move(E); },
124  [&](std::unique_ptr<llvm::ErrorInfoBase> E) { EIB = std::move(E); });
125 
126  if (EIB)
127  return SendErrorResponse(Status(llvm::Error(std::move(EIB))));
128  return SendUnimplementedResponse("");
129 }
130 
133  StringExtractorGDBRemote &packet) {
134  m_send_error_strings = true;
135  return SendOKResponse();
136 }
137 
140  const StringExtractorGDBRemote &failed_packet, const char *message) {
142  LLDB_LOGF(log, "GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)",
143  __FUNCTION__, failed_packet.GetStringRef().data(),
144  message ? message : "");
145  return SendErrorResponse(0x03);
146 }
147 
150  return SendPacketNoLock("OK");
151 }
152 
154  return GetAck() == PacketResult::Success;
155 }
156 
158 GDBRemoteCommunicationServer::SendJSONResponse(const json::Value &value) {
159  std::string json_string;
160  raw_string_ostream os(json_string);
161  os << value;
162  os.flush();
163  StreamGDBRemote escaped_response;
164  escaped_response.PutEscapedBytes(json_string.c_str(), json_string.size());
165  return SendPacketNoLock(escaped_response.GetString());
166 }
167 
169 GDBRemoteCommunicationServer::SendJSONResponse(Expected<json::Value> value) {
170  if (!value)
171  return SendErrorResponse(value.takeError());
172  return SendJSONResponse(*value);
173 }
StringExtractorGDBRemote::GetServerPacketType
ServerPacketType GetServerPacketType() const
Definition: StringExtractorGDBRemote.cpp:57
lldb_private::process_gdb_remote::GDBRemoteCommunicationServer::SendErrorResponse
PacketResult SendErrorResponse(const Status &error)
Definition: GDBRemoteCommunicationServer.cpp:106
llvm
Definition: Debugger.h:49
lldb_private::process_gdb_remote::GDBRemoteCommunicationServer::RegisterPacketHandler
void RegisterPacketHandler(StringExtractorGDBRemote::ServerPacketType packet_type, PacketHandler handler)
Definition: GDBRemoteCommunicationServer.cpp:38
StringExtractorGDBRemote::eServerPacketType_unimplemented
@ eServerPacketType_unimplemented
Definition: StringExtractorGDBRemote.h:50
StringExtractor::GetStringRef
llvm::StringRef GetStringRef() const
Definition: StringExtractor.h:48
lldb_private::process_gdb_remote::GDBRemoteCommunication::PacketResult
PacketResult
Definition: GDBRemoteCommunication.h:66
LLDB_LOGF
#define LLDB_LOGF(log,...)
Definition: Log.h:249
lldb_private::process_gdb_remote::GDBRemoteCommunicationServer::GetPacketAndSendResponse
PacketResult GetPacketAndSendResponse(Timeout< std::micro > timeout, Status &error, bool &interrupt, bool &quit)
Definition: GDBRemoteCommunicationServer.cpp:45
lldb_private::process_gdb_remote::GDBRemoteCommunication
Definition: GDBRemoteCommunication.h:56
lldb_private::process_gdb_remote::GDBRemoteCommunicationServer::PacketHandler
std::function< PacketResult(StringExtractorGDBRemote &packet, Status &error, bool &interrupt, bool &quit)> PacketHandler
Definition: GDBRemoteCommunicationServer.h:32
StringExtractorGDBRemote.h
StringExtractorGDBRemote::eServerPacketType_invalid
@ eServerPacketType_invalid
Definition: StringExtractorGDBRemote.h:49
lldb_private::Stream::PutStringAsRawHex8
size_t PutStringAsRawHex8(llvm::StringRef s)
Definition: Stream.cpp:382
lldb_private::process_gdb_remote::GDBRemoteCommunication::WaitForPacketNoLock
PacketResult WaitForPacketNoLock(StringExtractorGDBRemote &response, Timeout< std::micro > timeout, bool sync_on_timeout)
Definition: GDBRemoteCommunication.cpp:266
lldb_private::StreamString::GetString
llvm::StringRef GetString() const
Definition: StreamString.cpp:51
lldb_private::process_gdb_remote::GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer
~GDBRemoteCommunicationServer() override
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
StringExtractorGDBRemote::eServerPacketType_nack
@ eServerPacketType_nack
Definition: StringExtractorGDBRemote.h:47
UnimplementedError.h
StreamString.h
GDBRemoteCommunicationServer.h
lldb_private::StreamString
Definition: StreamString.h:23
lldb_private::process_gdb_remote::GDBRemoteCommunicationServer::SendJSONResponse
PacketResult SendJSONResponse(const llvm::json::Value &value)
Serialize and send a JSON object response.
lldb_private::process_gdb_remote::GDBRemoteCommunicationServer::Handle_QErrorStringEnable
PacketResult Handle_QErrorStringEnable(StringExtractorGDBRemote &packet)
Definition: GDBRemoteCommunicationServer.cpp:132
lldb_private::process_gdb_remote::GDBRemoteCommunicationServer::m_exit_now
bool m_exit_now
Definition: GDBRemoteCommunicationServer.h:54
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:39
lldb_private::process_gdb_remote
Definition: GDBRemoteClientBase.h:17
lldb_private::process_gdb_remote::GDBRemoteCommunication::PacketResult::Success
@ Success
lldb_private::process_gdb_remote::GDBRemoteCommunication::GetAck
PacketResult GetAck()
Definition: GDBRemoteCommunication.cpp:195
lldb_private::process_gdb_remote::GDBRemoteCommunicationServer::SendUnimplementedResponse
PacketResult SendUnimplementedResponse(const char *packet)
Definition: GDBRemoteCommunicationServer.cpp:92
lldb_private::process_gdb_remote::GDBRemoteCommunicationServer::m_packet_handlers
std::map< StringExtractorGDBRemote::ServerPacketType, PacketHandler > m_packet_handlers
Definition: GDBRemoteCommunicationServer.h:53
StringExtractorGDBRemote::ServerPacketType
ServerPacketType
Definition: StringExtractorGDBRemote.h:46
lldb_private::process_gdb_remote::GDBRemoteCommunicationServer::HandshakeWithClient
bool HandshakeWithClient()
Definition: GDBRemoteCommunicationServer.cpp:153
lldb_private::Status
Definition: Status.h:44
lldb_private::Timeout< std::micro >
message
message(FATAL_ERROR "invalid libipt include path provided") endif() include_directories($
Definition: Plugins/Trace/intel-pt/CMakeLists.txt:6
StringExtractorGDBRemote::eServerPacketType_QEnableErrorStrings
@ eServerPacketType_QEnableErrorStrings
Definition: StringExtractorGDBRemote.h:70
StringExtractorGDBRemote::eServerPacketType_ack
@ eServerPacketType_ack
Definition: StringExtractorGDBRemote.h:48
lldb_private::StreamGDBRemote
Definition: GDBRemote.h:27
lldb_private::process_gdb_remote::GDBRemoteCommunication::SendPacketNoLock
PacketResult SendPacketNoLock(llvm::StringRef payload)
Definition: GDBRemoteCommunication.cpp:122
lldb_private::Communication::IsConnected
bool IsConnected() const
Check if the connection is valid.
Definition: Communication.cpp:116
ProcessGDBRemoteLog.h
lldb_private::process_gdb_remote::GDBRemoteCommunicationServer::SendOKResponse
PacketResult SendOKResponse()
Definition: GDBRemoteCommunicationServer.cpp:149
lldb_private::Stream::Printf
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
lldb_private::process_gdb_remote::ProcessGDBRemoteLog::GetLogIfAllCategoriesSet
static Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: ProcessGDBRemoteLog.h:38
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::StreamGDBRemote::PutEscapedBytes
int PutEscapedBytes(const void *s, size_t src_len)
Output a block of data to the stream performing GDB-remote escaping.
Definition: GDBRemote.cpp:29
Error
llvm::Error Error
Definition: UdtRecordCompleter.cpp:29
lldb_private::process_gdb_remote::GDBRemoteCommunicationServer::m_send_error_strings
bool m_send_error_strings
Definition: GDBRemoteCommunicationServer.h:57
StringExtractorGDBRemote
Definition: StringExtractorGDBRemote.h:21
lldb_private::Log
Definition: Log.h:49
GDBR_LOG_PACKETS
#define GDBR_LOG_PACKETS
Definition: ProcessGDBRemoteLog.h:16
lldb
Definition: SBAddress.h:15
lldb_private::process_gdb_remote::GDBRemoteCommunicationServer::SendIllFormedResponse
PacketResult SendIllFormedResponse(const StringExtractorGDBRemote &packet, const char *error_message)
Definition: GDBRemoteCommunicationServer.cpp:139