LLDB mainline
PlatformWebInspectorWasm.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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
12#include "lldb/Host/Host.h"
15#include "lldb/Utility/Log.h"
16#include "llvm/ADT/StringExtras.h"
17#include "llvm/Support/ErrorExtras.h"
18
19#include <chrono>
20#include <csignal>
21#include <thread>
22
23using namespace lldb;
24using namespace lldb_private;
25
27
28static constexpr llvm::StringLiteral kServerBinary =
29 "/System/Cryptexes/App/usr/libexec/webinspector-wasm-lldb-platform";
30static constexpr uint8_t kConnectAttempts = 5;
31static constexpr auto kConnectDelay = std::chrono::milliseconds(100);
32
34 if (llvm::Error err = EnsureConnected()) {
36 "EnsureConnected failed: {0}");
37 }
38}
39
41 return "Platform for debugging Wasm via WebInspector";
42}
43
49
53
55 const ArchSpec *arch) {
57 LLDB_LOG(log, "force = {0}, arch = ({1}, {2})", force,
58 arch ? arch->GetArchitectureName() : "<null>",
59 arch ? arch->GetTriple().getTriple() : "<null>");
60 return force ? PlatformSP(new PlatformWebInspectorWasm()) : PlatformSP();
61}
62
67
70
72 return llvm::createStringErrorV("platform binary not found: {0}",
74
75 // Find two free TCP ports.
76 llvm::Expected<uint16_t> expected_platform_port = FindFreeTCPPort();
77 if (!expected_platform_port)
78 return expected_platform_port.takeError();
79 uint16_t platform_port = *expected_platform_port;
80
81 llvm::Expected<uint16_t> expected_debugserver_port = FindFreeTCPPort();
82 if (!expected_debugserver_port)
83 return expected_debugserver_port.takeError();
84 uint16_t debugserver_port = *expected_debugserver_port;
85
86 ProcessLaunchInfo launch_info;
88 /*add_exe_file_as_first_arg=*/true);
89 Args args;
91 args.AppendArgument("--platform");
92 args.AppendArgument(llvm::utostr(platform_port));
93 args.AppendArgument("--debugserver");
94 args.AppendArgument(llvm::utostr(debugserver_port));
95 launch_info.SetArguments(args, /*first_arg_is_executable=*/true);
96 launch_info.SetLaunchInSeparateProcessGroup(true);
97 launch_info.GetFlags().Clear(eLaunchFlagDebug);
98
99 launch_info.SetMonitorProcessCallback(
100 [log](lldb::pid_t pid, int signal, int status) {
101 LLDB_LOG(log,
102 "Platform exited: pid = {0}, signal = "
103 "{1}, status = {2}",
104 pid, signal, status);
105 });
106
107 LLDB_LOG(log, "{0}", GetArgRange(launch_info.GetArguments()));
108
109 Status status = Host::LaunchProcess(launch_info);
110 if (status.Fail())
111 return status.takeError();
112
113 m_server_pid = launch_info.GetProcessID();
114 LLDB_LOG(log, "Platform launched: pid = {0}", m_server_pid);
115
116 Args connect_args;
117 connect_args.AppendArgument(
118 llvm::formatv("connect://localhost:{0}", platform_port).str());
119
120 // The platform may need some time to bind a socket to the requested port.
121 for (uint8_t attempt = 0; attempt < kConnectAttempts; attempt++) {
122 status = PlatformWasm::ConnectRemote(connect_args);
123 if (status.Success())
124 return llvm::Error::success();
125
126 LLDB_LOG(
127 log,
128 "[{0}/{1}] platform not yet listening on port {2}: trying again in {3}",
129 attempt, kConnectAttempts, platform_port, kConnectDelay);
130 std::this_thread::sleep_for(kConnectDelay);
131 }
132 return status.takeError();
133}
134
137 return llvm::Error::success();
138 return LaunchPlatformServer();
139}
140
146
148 Debugger &debugger, Target *target,
149 Status &status) {
151 if (status.Fail())
152 return nullptr;
153 return PlatformWasm::Attach(attach_info, debugger, target, status);
154}
155
157 const ProcessInstanceInfoMatch &match_info,
158 ProcessInstanceInfoList &proc_infos) {
159 if (llvm::Error err = EnsureConnected()) {
160 LLDB_LOG_ERROR(GetLog(LLDBLog::Platform), std::move(err),
161 "EnsureConnected failed: {0}");
162 return 0;
163 }
164 return PlatformWasm::FindProcesses(match_info, proc_infos);
165}
166
168 ProcessInstanceInfo &proc_info) {
169 if (llvm::Error err = EnsureConnected()) {
170 LLDB_LOG_ERROR(GetLog(LLDBLog::Platform), std::move(err),
171 "EnsureConnected failed: {0}");
172 return false;
173 }
174 return PlatformWasm::GetProcessInfo(pid, proc_info);
175}
176
179 Debugger &debugger, Target &target,
180 Status &error) {
181 error = Status::FromErrorStringWithFormatv("{0} does not support launching",
183 return nullptr;
184}
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:364
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:394
static constexpr llvm::StringLiteral kServerBinary
static constexpr uint8_t kConnectAttempts
static constexpr auto kConnectDelay
#define LLDB_PLUGIN_DEFINE(PluginName)
An architecture specification class.
Definition ArchSpec.h:32
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition ArchSpec.h:460
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
Definition ArchSpec.cpp:557
A command line argument class.
Definition Args.h:33
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition Args.h:120
void AppendArgument(llvm::StringRef arg_str, char quote_char='\0')
Appends a new argument to the end of the list argument list.
Definition Args.cpp:332
A class to manage flag bits.
Definition Debugger.h:100
A file utility class.
Definition FileSpec.h:57
static FileSystem & Instance()
ValueType Clear(ValueType mask=~static_cast< ValueType >(0))
Clear one or more flags.
Definition Flags.h:61
static Status LaunchProcess(ProcessLaunchInfo &launch_info)
Launch the process specified in launch_info.
static void Kill(lldb::pid_t pid, int signo)
static auto GetArgRange(const Args &args)
Status ConnectRemote(Args &args) override
static llvm::Expected< uint16_t > FindFreeTCPPort()
Find a free TCP port by binding to port 0.
lldb::ProcessSP Attach(ProcessAttachInfo &attach_info, Debugger &debugger, Target *target, Status &status) override
Attach to an existing process using a process ID.
lldb::ProcessSP DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, Target &target, Status &error) override
Subclasses do not need to implement this function as it uses the Platform::LaunchProcess() followed b...
uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &proc_infos) override
Attach to an existing process by process name.
static lldb::PlatformSP CreateInstance(bool force, const ArchSpec *arch)
lldb::ProcessSP Attach(ProcessAttachInfo &attach_info, Debugger &debugger, Target *target, Status &status) override
Attach to an existing process using a process ID.
bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info) override
virtual uint32_t FindProcesses(const ProcessInstanceInfoMatch &match_info, ProcessInstanceInfoList &proc_infos)
Attach to an existing process by process name.
virtual bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info)
Definition Platform.cpp:996
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
void SetExecutableFile(const FileSpec &exe_file, bool add_exe_file_as_first_arg)
lldb::pid_t GetProcessID() const
Definition ProcessInfo.h:68
void SetArguments(const Args &args, bool first_arg_is_executable)
void SetMonitorProcessCallback(Host::MonitorChildProcessCallback callback)
void SetLaunchInSeparateProcessGroup(bool separate)
An error handling class.
Definition Status.h:118
bool Fail() const
Test for error condition.
Definition Status.cpp:293
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition Status.h:151
static Status FromError(llvm::Error error)
Avoid using this in new code. Migrate APIs to llvm::Expected instead.
Definition Status.cpp:136
#define LLDB_INVALID_PROCESS_ID
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:327
std::vector< ProcessInstanceInfo > ProcessInstanceInfoList
Definition Host.h:32
std::shared_ptr< lldb_private::Platform > PlatformSP
std::shared_ptr< lldb_private::Process > ProcessSP
uint64_t pid_t
Definition lldb-types.h:83