Summary: These classes describe the details of the process we are about to launch, and so they are naturally used by the launching code in the Host module. Previously they were present in Target because that is the most important (but by far not the only) user of the launching code. Since the launching code has other customers, must of which do not care about Targets, it makes sense to move these classes to the Host layer, next to the launching code. This move reduces the number of times that Target is included from host to 8 (it used to be 14). Reviewers: zturner, clayborg, jingham, davide, teemperor Subscribers: emaste, mgorny, lldb-commits Differential Revision: https://reviews.llvm.org/D56602 llvm-svn: 353047
113 lines
4.3 KiB
C++
113 lines
4.3 KiB
C++
//===-- TestClient.h --------------------------------------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLDB_SERVER_TESTS_TESTCLIENT_H
|
|
#define LLDB_SERVER_TESTS_TESTCLIENT_H
|
|
|
|
#include "MessageObjects.h"
|
|
#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h"
|
|
#include "lldb/Host/ProcessLaunchInfo.h"
|
|
#include "lldb/Utility/ArchSpec.h"
|
|
#include "lldb/Utility/Connection.h"
|
|
#include "llvm/ADT/Optional.h"
|
|
#include "llvm/Support/Casting.h"
|
|
#include "llvm/Support/FormatVariadic.h"
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
#if LLDB_SERVER_IS_DEBUGSERVER
|
|
#define LLGS_TEST(x) DISABLED_ ## x
|
|
#define DS_TEST(x) x
|
|
#else
|
|
#define LLGS_TEST(x) x
|
|
#define DS_TEST(x) DISABLED_ ## x
|
|
#endif
|
|
|
|
namespace llgs_tests {
|
|
class TestClient
|
|
: public lldb_private::process_gdb_remote::GDBRemoteCommunicationClient {
|
|
public:
|
|
static bool IsDebugServer() { return LLDB_SERVER_IS_DEBUGSERVER; }
|
|
static bool IsLldbServer() { return !IsDebugServer(); }
|
|
|
|
/// Launches the server, connects it to the client and returns the client. If
|
|
/// Log is non-empty, the server will write it's log to this file.
|
|
static llvm::Expected<std::unique_ptr<TestClient>> launch(llvm::StringRef Log);
|
|
|
|
/// Launches the server, while specifying the inferior on its command line.
|
|
/// When the client connects, it already has a process ready.
|
|
static llvm::Expected<std::unique_ptr<TestClient>>
|
|
launch(llvm::StringRef Log, llvm::ArrayRef<llvm::StringRef> InferiorArgs);
|
|
|
|
/// Allows user to pass additional arguments to the server. Be careful when
|
|
/// using this for generic tests, as the two stubs have different
|
|
/// command-line interfaces.
|
|
static llvm::Expected<std::unique_ptr<TestClient>>
|
|
launchCustom(llvm::StringRef Log, llvm::ArrayRef<llvm::StringRef> ServerArgs, llvm::ArrayRef<llvm::StringRef> InferiorArgs);
|
|
|
|
|
|
~TestClient() override;
|
|
llvm::Error SetInferior(llvm::ArrayRef<std::string> inferior_args);
|
|
llvm::Error ListThreadsInStopReply();
|
|
llvm::Error SetBreakpoint(unsigned long address);
|
|
llvm::Error ContinueAll();
|
|
llvm::Error ContinueThread(unsigned long thread_id);
|
|
const ProcessInfo &GetProcessInfo();
|
|
llvm::Expected<JThreadsInfo> GetJThreadsInfo();
|
|
const StopReply &GetLatestStopReply();
|
|
template <typename T> llvm::Expected<const T &> GetLatestStopReplyAs() {
|
|
assert(m_stop_reply);
|
|
if (const auto *Reply = llvm::dyn_cast<T>(m_stop_reply.get()))
|
|
return *Reply;
|
|
return llvm::make_error<llvm::StringError>(
|
|
llvm::formatv("Unexpected Stop Reply {0}", m_stop_reply->getKind()),
|
|
llvm::inconvertibleErrorCode());
|
|
}
|
|
llvm::Error SendMessage(llvm::StringRef message);
|
|
llvm::Error SendMessage(llvm::StringRef message,
|
|
std::string &response_string);
|
|
llvm::Error SendMessage(llvm::StringRef message, std::string &response_string,
|
|
PacketResult expected_result);
|
|
|
|
template <typename P, typename... CreateArgs>
|
|
llvm::Expected<typename P::result_type> SendMessage(llvm::StringRef Message,
|
|
CreateArgs &&... Args);
|
|
unsigned int GetPcRegisterId();
|
|
|
|
private:
|
|
TestClient(std::unique_ptr<lldb_private::Connection> Conn);
|
|
|
|
llvm::Error initializeConnection();
|
|
llvm::Error qProcessInfo();
|
|
llvm::Error qRegisterInfos();
|
|
llvm::Error queryProcess();
|
|
llvm::Error Continue(llvm::StringRef message);
|
|
std::string FormatFailedResult(
|
|
const std::string &message,
|
|
lldb_private::process_gdb_remote::GDBRemoteCommunication::PacketResult
|
|
result);
|
|
|
|
llvm::Optional<ProcessInfo> m_process_info;
|
|
std::unique_ptr<StopReply> m_stop_reply;
|
|
std::vector<lldb_private::RegisterInfo> m_register_infos;
|
|
unsigned int m_pc_register = LLDB_INVALID_REGNUM;
|
|
};
|
|
|
|
template <typename P, typename... CreateArgs>
|
|
llvm::Expected<typename P::result_type>
|
|
TestClient::SendMessage(llvm::StringRef Message, CreateArgs &&... Args) {
|
|
std::string ResponseText;
|
|
if (llvm::Error E = SendMessage(Message, ResponseText))
|
|
return std::move(E);
|
|
return P::create(ResponseText, std::forward<CreateArgs>(Args)...);
|
|
}
|
|
|
|
} // namespace llgs_tests
|
|
|
|
#endif // LLDB_SERVER_TESTS_TESTCLIENT_H
|