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
22using namespace lldb;
23using namespace lldb_private;
25using namespace llvm;
26
28 : GDBRemoteCommunication(), m_exit_now(false) {
31 [this](StringExtractorGDBRemote packet, Status &error, bool &interrupt,
32 bool &quit) { return this->Handle_QErrorStringEnable(packet); });
33}
34
36
39 PacketHandler handler) {
40 m_packet_handlers[packet_type] = std::move(handler);
41}
42
45 Timeout<std::micro> timeout, Status &error, bool &interrupt, bool &quit) {
47
48 PacketResult packet_result = ReadPacket(packet, timeout, false);
49 if (packet_result == PacketResult::Success) {
51 packet.GetServerPacketType();
52 switch (packet_type) {
55 break;
56
58 error.SetErrorString("invalid packet");
59 quit = true;
60 break;
61
63 packet_result = SendUnimplementedResponse(packet.GetStringRef().data());
64 break;
65
66 default:
67 auto handler_it = m_packet_handlers.find(packet_type);
68 if (handler_it == m_packet_handlers.end())
69 packet_result = SendUnimplementedResponse(packet.GetStringRef().data());
70 else
71 packet_result = handler_it->second(packet, error, interrupt, quit);
72 break;
73 }
74 } else {
75 if (!IsConnected()) {
76 error.SetErrorString("lost connection");
77 quit = true;
78 } else {
79 error.SetErrorString("timeout");
80 }
81 }
82
83 // Check if anything occurred that would force us to want to exit.
84 if (m_exit_now)
85 quit = true;
86
87 return packet_result;
88}
89
92 // TODO: Log the packet we aren't handling...
93 return SendPacketNoLock("");
94}
95
98 char packet[16];
99 int packet_len = ::snprintf(packet, sizeof(packet), "E%2.2x", err);
100 assert(packet_len < (int)sizeof(packet));
101 return SendPacketNoLock(llvm::StringRef(packet, packet_len));
102}
103
108 packet.Printf("E%2.2x;", static_cast<uint8_t>(error.GetError()));
109 packet.PutStringAsRawHex8(error.AsCString());
110 return SendPacketNoLock(packet.GetString());
111 } else
112 return SendErrorResponse(error.GetError());
113}
114
117 assert(error);
118 std::unique_ptr<llvm::ErrorInfoBase> EIB;
119 std::unique_ptr<UnimplementedError> UE;
120 llvm::handleAllErrors(
121 std::move(error),
122 [&](std::unique_ptr<UnimplementedError> E) { UE = std::move(E); },
123 [&](std::unique_ptr<llvm::ErrorInfoBase> E) { EIB = std::move(E); });
124
125 if (EIB)
126 return SendErrorResponse(Status(llvm::Error(std::move(EIB))));
127 return SendUnimplementedResponse("");
128}
129
132 StringExtractorGDBRemote &packet) {
134 return SendOKResponse();
135}
136
139 const StringExtractorGDBRemote &failed_packet, const char *message) {
141 LLDB_LOGF(log, "GDBRemoteCommunicationServer::%s: ILLFORMED: '%s' (%s)",
142 __FUNCTION__, failed_packet.GetStringRef().data(),
143 message ? message : "");
144 return SendErrorResponse(0x03);
145}
146
149 return SendPacketNoLock("OK");
150}
151
153GDBRemoteCommunicationServer::SendJSONResponse(const json::Value &value) {
154 std::string json_string;
155 raw_string_ostream os(json_string);
156 os << value;
157 os.flush();
158 StreamGDBRemote escaped_response;
159 escaped_response.PutEscapedBytes(json_string.c_str(), json_string.size());
160 return SendPacketNoLock(escaped_response.GetString());
161}
162
164GDBRemoteCommunicationServer::SendJSONResponse(Expected<json::Value> value) {
165 if (!value)
166 return SendErrorResponse(value.takeError());
167 return SendJSONResponse(*value);
168}
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOGF(log,...)
Definition: Log.h:349
ServerPacketType GetServerPacketType() const
llvm::StringRef GetStringRef() const
bool IsConnected() const
Check if the connection is valid.
An error handling class.
Definition: Status.h:44
int PutEscapedBytes(const void *s, size_t src_len)
Output a block of data to the stream performing GDB-remote escaping.
Definition: GDBRemote.cpp:28
llvm::StringRef GetString() const
size_t PutStringAsRawHex8(llvm::StringRef s)
Definition: Stream.cpp:410
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:134
std::function< PacketResult(StringExtractorGDBRemote &packet, Status &error, bool &interrupt, bool &quit)> PacketHandler
void RegisterPacketHandler(StringExtractorGDBRemote::ServerPacketType packet_type, PacketHandler handler)
std::map< StringExtractorGDBRemote::ServerPacketType, PacketHandler > m_packet_handlers
PacketResult Handle_QErrorStringEnable(StringExtractorGDBRemote &packet)
PacketResult SendIllFormedResponse(const StringExtractorGDBRemote &packet, const char *error_message)
PacketResult GetPacketAndSendResponse(Timeout< std::micro > timeout, Status &error, bool &interrupt, bool &quit)
PacketResult SendJSONResponse(const llvm::json::Value &value)
Serialize and send a JSON object response.
PacketResult ReadPacket(StringExtractorGDBRemote &response, Timeout< std::micro > timeout, bool sync_on_timeout)
A class that represents a running process on the host machine.
Definition: SBAttachInfo.h:14
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:314
Definition: SBAddress.h:15
Definition: Debugger.h:53