113 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			113 lines
		
	
	
		
			4.4 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_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_TESTCLIENT_H
 | 
						|
#define LLDB_UNITTESTS_TOOLS_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_UNITTESTS_TOOLS_LLDB_SERVER_TESTS_TESTCLIENT_H
 |