1 //===-- TestClient.h --------------------------------------------*- C++ -*-===//
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 #ifndef LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_TESTCLIENT_H
10 #define LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_TESTCLIENT_H
11
12 #include "MessageObjects.h"
13 #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h"
14 #include "lldb/Host/ProcessLaunchInfo.h"
15 #include "lldb/Utility/ArchSpec.h"
16 #include "lldb/Utility/Connection.h"
17 #include "llvm/ADT/Optional.h"
18 #include "llvm/Support/Casting.h"
19 #include "llvm/Support/FormatVariadic.h"
20 #include <memory>
21 #include <string>
22
23 #if LLDB_SERVER_IS_DEBUGSERVER
24 #define LLGS_TEST(x) DISABLED_ ## x
25 #define DS_TEST(x) x
26 #else
27 #define LLGS_TEST(x) x
28 #define DS_TEST(x) DISABLED_ ## x
29 #endif
30
31 namespace llgs_tests {
32 class TestClient
33 : public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient {
34 public:
IsDebugServer()35 static bool IsDebugServer() { return LLDB_SERVER_IS_DEBUGSERVER; }
IsLldbServer()36 static bool IsLldbServer() { return !IsDebugServer(); }
37
38 /// Launches the server, connects it to the client and returns the client. If
39 /// Log is non-empty, the server will write it's log to this file.
40 static llvm::Expected<std::unique_ptr<TestClient>> launch(llvm::StringRef Log);
41
42 /// Launches the server, while specifying the inferior on its command line.
43 /// When the client connects, it already has a process ready.
44 static llvm::Expected<std::unique_ptr<TestClient>>
45 launch(llvm::StringRef Log, llvm::ArrayRef<llvm::StringRef> InferiorArgs);
46
47 /// Allows user to pass additional arguments to the server. Be careful when
48 /// using this for generic tests, as the two stubs have different
49 /// command-line interfaces.
50 static llvm::Expected<std::unique_ptr<TestClient>>
51 launchCustom(llvm::StringRef Log, llvm::ArrayRef<llvm::StringRef> ServerArgs, llvm::ArrayRef<llvm::StringRef> InferiorArgs);
52
53
54 ~TestClient() override;
55 llvm::Error SetInferior(llvm::ArrayRef<std::string> inferior_args);
56 llvm::Error ListThreadsInStopReply();
57 llvm::Error SetBreakpoint(unsigned long address);
58 llvm::Error ContinueAll();
59 llvm::Error ContinueThread(unsigned long thread_id);
60 const ProcessInfo &GetProcessInfo();
61 llvm::Expected<JThreadsInfo> GetJThreadsInfo();
62 const StopReply &GetLatestStopReply();
GetLatestStopReplyAs()63 template <typename T> llvm::Expected<const T &> GetLatestStopReplyAs() {
64 assert(m_stop_reply);
65 if (const auto *Reply = llvm::dyn_cast<T>(m_stop_reply.get()))
66 return *Reply;
67 return llvm::make_error<llvm::StringError>(
68 llvm::formatv("Unexpected Stop Reply {0}", m_stop_reply->getKind()),
69 llvm::inconvertibleErrorCode());
70 }
71 llvm::Error SendMessage(llvm::StringRef message);
72 llvm::Error SendMessage(llvm::StringRef message,
73 std::string &response_string);
74 llvm::Error SendMessage(llvm::StringRef message, std::string &response_string,
75 PacketResult expected_result);
76
77 template <typename P, typename... CreateArgs>
78 llvm::Expected<typename P::result_type> SendMessage(llvm::StringRef Message,
79 CreateArgs &&... Args);
80 unsigned int GetPcRegisterId();
81
82 private:
83 TestClient(std::unique_ptr<lldb_private::Connection> Conn);
84
85 llvm::Error initializeConnection();
86 llvm::Error qProcessInfo();
87 llvm::Error qRegisterInfos();
88 llvm::Error queryProcess();
89 llvm::Error Continue(llvm::StringRef message);
90 std::string FormatFailedResult(
91 const std::string &message,
92 lldb_private::process_gdb_remote::GDBRemoteCommunication::PacketResult
93 result);
94
95 llvm::Optional<ProcessInfo> m_process_info;
96 std::unique_ptr<StopReply> m_stop_reply;
97 std::vector<lldb_private::RegisterInfo> m_register_infos;
98 unsigned int m_pc_register = LLDB_INVALID_REGNUM;
99 };
100
101 template <typename P, typename... CreateArgs>
102 llvm::Expected<typename P::result_type>
SendMessage(llvm::StringRef Message,CreateArgs &&...Args)103 TestClient::SendMessage(llvm::StringRef Message, CreateArgs &&... Args) {
104 std::string ResponseText;
105 if (llvm::Error E = SendMessage(Message, ResponseText))
106 return std::move(E);
107 return P::create(ResponseText, std::forward<CreateArgs>(Args)...);
108 }
109
110 } // namespace llgs_tests
111
112 #endif // LLDB_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_TESTCLIENT_H
113