================
@@ -7,21 +7,129 @@
 
//===----------------------------------------------------------------------===//
 
 #include "LLDBServerMockAcceleratorPlugin.h"
+#include "ProcessMockAccelerator.h"
 
+#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h"
+#include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h"
+#include "lldb/Host/HostInfo.h"
+#include "lldb/Host/ProcessLaunchInfo.h"
+#include "lldb/Host/Socket.h"
+#include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Host/common/TCPSocket.h"
+#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h"
+#include "lldb/Utility/Args.h"
+#include "lldb/Utility/Connection.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+#include "llvm/Support/FormatVariadic.h"
+
+#include <cstdlib>
+
+using namespace lldb;
 using namespace lldb_private;
 using namespace lldb_private::lldb_server;
+using namespace lldb_private::process_gdb_remote;
+
+// Read a mock-accelerator setting from an environment variable so tests can
+// configure the connection the mock advertises; falls back to default_value.
+static std::string GetMockEnvSetting(const char *env_var,
+                                     std::string default_value) {
+  if (const char *value = ::getenv(env_var))
+    return value;
+  return default_value;
+}
 
 LLDBServerMockAcceleratorPlugin::LLDBServerMockAcceleratorPlugin(
-    GDBServer &gdb_server, MainLoop &main_loop)
-    : LLDBServerAcceleratorPlugin(gdb_server, main_loop) {}
+    GDBServer &native_gdb_server, MainLoop &native_main_loop)
+    : LLDBServerAcceleratorPlugin(native_gdb_server, native_main_loop) {
+  Log *log = GetLog(GDBRLog::Plugin);
+
+  // Run a second gdb-remote server inside this lldb-server process, on its own
+  // main loop and thread (separate from the native process so neither slows 
the
+  // other's packets), backed by ProcessMockAccelerator. No real process is
+  // launched or exec'd: ProcessMockAccelerator::Manager just returns a
+  // synthetic, already-stopped process with a single thread and a fixed set of
+  // registers.
+  m_process_manager_up =
+      std::make_unique<ProcessMockAccelerator::Manager>(m_mock_main_loop);
+  m_accelerator_gdb_server = 
std::make_unique<GDBRemoteCommunicationServerLLGS>(
+      m_mock_main_loop, *m_process_manager_up);
+
+  // LaunchProcess() is how LLGS obtains its current process; it routes to
+  // ProcessMockAccelerator::Manager::Launch() (which ignores this info) and
+  // only requires a non-empty argument list, so a single placeholder is 
enough.
+  ProcessLaunchInfo info;
+  Args args;
+  args.AppendArgument("/pretend/path/to/mockgpu");
+  info.SetArguments(args, /*first_arg_is_executable=*/true);
+  m_accelerator_gdb_server->SetLaunchInfo(info);
+  if (Status error = m_accelerator_gdb_server->LaunchProcess(); error.Fail())
+    LLDB_LOG(log, "failed to create mock accelerator process: {0}",
+             error.AsCString());
+
+  // Listen on an ephemeral local port for the client's connection, registering
+  // the accept handler now -- before the main loop thread starts -- so the
+  // loop's handles are only ever touched from its own thread.
+  llvm::Expected<std::unique_ptr<TCPSocket>> sock =
+      Socket::TcpListen("localhost:0");
+  if (!sock) {
+    LLDB_LOG_ERROR(log, sock.takeError(),
+                   "mock accelerator failed to listen: {0}");
+    return;
+  }
+  m_listen_socket = std::move(*sock);
+  llvm::Expected<std::vector<MainLoopBase::ReadHandleUP>> handles =
+      m_listen_socket->Accept(
+          m_mock_main_loop, [this](std::unique_ptr<Socket> socket) {
+            std::unique_ptr<Connection> connection_up =
+                std::make_unique<ConnectionFileDescriptor>(std::move(socket));
+            m_accelerator_gdb_server->InitializeConnection(
+                std::move(connection_up));
+          });
+  if (!handles) {
+    LLDB_LOG_ERROR(log, handles.takeError(),
+                   "mock accelerator failed to accept: {0}");
+    return;
+  }
+  m_read_handles = std::move(*handles);
+  m_connect_url = llvm::formatv("connect://localhost:{0}",
+                                m_listen_socket->GetLocalPortNumber());
+
+  // Service the mock accelerator server on its own thread.
+  llvm::Expected<HostThread> loop_thread = ThreadLauncher::LaunchThread(
+      "mock-accel.loop", [this]() -> lldb::thread_result_t {
+        m_mock_main_loop.Run();
+        return {};
+      });
+  if (!loop_thread) {
+    LLDB_LOG_ERROR(log, loop_thread.takeError(),
+                   "mock accelerator failed to start its main loop: {0}");
+    m_connect_url.clear();
+    return;
+  }
+  m_mock_main_loop_thread = *loop_thread;
+}
----------------
satyajanga wrote:

done moved it.

https://github.com/llvm/llvm-project/pull/201449
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to