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 return "Platform for debugging Wasm via WebInspector";
35}
36
42
46
48 const ArchSpec *arch) {
50 LLDB_LOG(log, "force = {0}, arch = ({1}, {2})", force,
51 arch ? arch->GetArchitectureName() : "<null>",
52 arch ? arch->GetTriple().getTriple() : "<null>");
53 return force ? PlatformSP(new PlatformWebInspectorWasm()) : PlatformSP();
54}
55
60
63
65 return llvm::createStringErrorV("platform binary not found: {0}",
67
68 // Find two free TCP ports.
69 llvm::Expected<uint16_t> expected_platform_port = FindFreeTCPPort();
70 if (!expected_platform_port)
71 return expected_platform_port.takeError();
72 uint16_t platform_port = *expected_platform_port;
73
74 llvm::Expected<uint16_t> expected_debugserver_port = FindFreeTCPPort();
75 if (!expected_debugserver_port)
76 return expected_debugserver_port.takeError();
77 uint16_t debugserver_port = *expected_debugserver_port;
78
79 ProcessLaunchInfo launch_info;
81 /*add_exe_file_as_first_arg=*/true);
82 Args args;
84 args.AppendArgument("--platform");
85 args.AppendArgument(llvm::utostr(platform_port));
86 args.AppendArgument("--debugserver");
87 args.AppendArgument(llvm::utostr(debugserver_port));
88 launch_info.SetArguments(args, /*first_arg_is_executable=*/true);
89 launch_info.SetLaunchInSeparateProcessGroup(true);
90 launch_info.GetFlags().Clear(eLaunchFlagDebug);
91
92 launch_info.SetMonitorProcessCallback(
93 [log](lldb::pid_t pid, int signal, int status) {
94 LLDB_LOG(log,
95 "Platform exited: pid = {0}, signal = "
96 "{1}, status = {2}",
97 pid, signal, status);
98 });
99
100 LLDB_LOG(log, "{0}", GetArgRange(launch_info.GetArguments()));
101
102 Status status = Host::LaunchProcess(launch_info);
103 if (status.Fail())
104 return status.takeError();
105
106 m_server_pid = launch_info.GetProcessID();
107 LLDB_LOG(log, "Platform launched: pid = {0}", m_server_pid);
108
109 Args connect_args;
110 connect_args.AppendArgument(
111 llvm::formatv("connect://localhost:{0}", platform_port).str());
112
113 // The platform may need some time to bind a socket to the requested port.
114 for (uint8_t attempt = 0; attempt < kConnectAttempts; attempt++) {
115 status = PlatformWasm::ConnectRemote(connect_args);
116 if (status.Success())
117 return llvm::Error::success();
118
119 LLDB_LOG(
120 log,
121 "[{0}/{1}] platform not yet listening on port {2}: trying again in {3}",
122 attempt, kConnectAttempts, platform_port, kConnectDelay);
123 std::this_thread::sleep_for(kConnectDelay);
124 }
125 return status.takeError();
126}
127
130 return llvm::Error::success();
131 return LaunchPlatformServer();
132}
133
139
141 Debugger &debugger, Target *target,
142 Status &status) {
144 if (status.Fail())
145 return nullptr;
146 return PlatformWasm::Attach(attach_info, debugger, target, status);
147}
148
150 const ProcessInstanceInfoMatch &match_info,
151 ProcessInstanceInfoList &proc_infos) {
152 if (llvm::Error err = EnsureConnected()) {
153 LLDB_LOG_ERROR(GetLog(LLDBLog::Platform), std::move(err),
154 "EnsureConnected failed: {0}");
155 return 0;
156 }
157 return PlatformWasm::FindProcesses(match_info, proc_infos);
158}
159
161 ProcessInstanceInfo &proc_info) {
162 if (llvm::Error err = EnsureConnected()) {
163 LLDB_LOG_ERROR(GetLog(LLDBLog::Platform), std::move(err),
164 "EnsureConnected failed: {0}");
165 return false;
166 }
167 return PlatformWasm::GetProcessInfo(pid, proc_info);
168}
169
172 Debugger &debugger, Target &target,
173 Status &error) {
174 error = Status::FromErrorStringWithFormatv("{0} does not support launching",
176 return nullptr;
177}
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:369
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:399
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:457
const char * GetArchitectureName() const
Returns a static string representing the current architecture.
Definition ArchSpec.cpp:548
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:101
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.
Definition Platform.cpp:982
virtual bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info)
Definition Platform.cpp:973
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:332
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