1 | //===-- SBPlatform.cpp ----------------------------------------------------===// |
---|---|
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 | |
9 | #include "lldb/API/SBPlatform.h" |
10 | #include "lldb/API/SBDebugger.h" |
11 | #include "lldb/API/SBEnvironment.h" |
12 | #include "lldb/API/SBError.h" |
13 | #include "lldb/API/SBFileSpec.h" |
14 | #include "lldb/API/SBLaunchInfo.h" |
15 | #include "lldb/API/SBModuleSpec.h" |
16 | #include "lldb/API/SBProcessInfoList.h" |
17 | #include "lldb/API/SBTarget.h" |
18 | #include "lldb/API/SBUnixSignals.h" |
19 | #include "lldb/Host/File.h" |
20 | #include "lldb/Target/Platform.h" |
21 | #include "lldb/Target/Target.h" |
22 | #include "lldb/Utility/ArchSpec.h" |
23 | #include "lldb/Utility/Args.h" |
24 | #include "lldb/Utility/Instrumentation.h" |
25 | #include "lldb/Utility/Status.h" |
26 | |
27 | #include "llvm/Support/FileSystem.h" |
28 | |
29 | #include <functional> |
30 | |
31 | using namespace lldb; |
32 | using namespace lldb_private; |
33 | |
34 | // PlatformConnectOptions |
35 | struct PlatformConnectOptions { |
36 | PlatformConnectOptions(const char *url = nullptr) { |
37 | if (url && url[0]) |
38 | m_url = url; |
39 | } |
40 | |
41 | ~PlatformConnectOptions() = default; |
42 | |
43 | std::string m_url; |
44 | std::string m_rsync_options; |
45 | std::string m_rsync_remote_path_prefix; |
46 | bool m_rsync_enabled = false; |
47 | bool m_rsync_omit_hostname_from_remote_path = false; |
48 | ConstString m_local_cache_directory; |
49 | }; |
50 | |
51 | // PlatformShellCommand |
52 | struct PlatformShellCommand { |
53 | PlatformShellCommand(llvm::StringRef shell_interpreter, |
54 | llvm::StringRef shell_command) { |
55 | if (!shell_interpreter.empty()) |
56 | m_shell = shell_interpreter.str(); |
57 | |
58 | if (!m_shell.empty() && !shell_command.empty()) |
59 | m_command = shell_command.str(); |
60 | } |
61 | |
62 | PlatformShellCommand(llvm::StringRef shell_command = llvm::StringRef()) { |
63 | if (!shell_command.empty()) |
64 | m_command = shell_command.str(); |
65 | } |
66 | |
67 | ~PlatformShellCommand() = default; |
68 | |
69 | std::string m_shell; |
70 | std::string m_command; |
71 | std::string m_working_dir; |
72 | std::string m_output; |
73 | int m_status = 0; |
74 | int m_signo = 0; |
75 | Timeout<std::ratio<1>> m_timeout = std::nullopt; |
76 | }; |
77 | // SBPlatformConnectOptions |
78 | SBPlatformConnectOptions::SBPlatformConnectOptions(const char *url) |
79 | : m_opaque_ptr(new PlatformConnectOptions(url)) { |
80 | LLDB_INSTRUMENT_VA(this, url); |
81 | } |
82 | |
83 | SBPlatformConnectOptions::SBPlatformConnectOptions( |
84 | const SBPlatformConnectOptions &rhs) |
85 | : m_opaque_ptr(new PlatformConnectOptions()) { |
86 | LLDB_INSTRUMENT_VA(this, rhs); |
87 | |
88 | *m_opaque_ptr = *rhs.m_opaque_ptr; |
89 | } |
90 | |
91 | SBPlatformConnectOptions::~SBPlatformConnectOptions() { delete m_opaque_ptr; } |
92 | |
93 | SBPlatformConnectOptions & |
94 | SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) { |
95 | LLDB_INSTRUMENT_VA(this, rhs); |
96 | |
97 | *m_opaque_ptr = *rhs.m_opaque_ptr; |
98 | return *this; |
99 | } |
100 | |
101 | const char *SBPlatformConnectOptions::GetURL() { |
102 | LLDB_INSTRUMENT_VA(this); |
103 | |
104 | if (m_opaque_ptr->m_url.empty()) |
105 | return nullptr; |
106 | return ConstString(m_opaque_ptr->m_url.c_str()).GetCString(); |
107 | } |
108 | |
109 | void SBPlatformConnectOptions::SetURL(const char *url) { |
110 | LLDB_INSTRUMENT_VA(this, url); |
111 | |
112 | if (url && url[0]) |
113 | m_opaque_ptr->m_url = url; |
114 | else |
115 | m_opaque_ptr->m_url.clear(); |
116 | } |
117 | |
118 | bool SBPlatformConnectOptions::GetRsyncEnabled() { |
119 | LLDB_INSTRUMENT_VA(this); |
120 | |
121 | return m_opaque_ptr->m_rsync_enabled; |
122 | } |
123 | |
124 | void SBPlatformConnectOptions::EnableRsync( |
125 | const char *options, const char *remote_path_prefix, |
126 | bool omit_hostname_from_remote_path) { |
127 | LLDB_INSTRUMENT_VA(this, options, remote_path_prefix, |
128 | omit_hostname_from_remote_path); |
129 | |
130 | m_opaque_ptr->m_rsync_enabled = true; |
131 | m_opaque_ptr->m_rsync_omit_hostname_from_remote_path = |
132 | omit_hostname_from_remote_path; |
133 | if (remote_path_prefix && remote_path_prefix[0]) |
134 | m_opaque_ptr->m_rsync_remote_path_prefix = remote_path_prefix; |
135 | else |
136 | m_opaque_ptr->m_rsync_remote_path_prefix.clear(); |
137 | |
138 | if (options && options[0]) |
139 | m_opaque_ptr->m_rsync_options = options; |
140 | else |
141 | m_opaque_ptr->m_rsync_options.clear(); |
142 | } |
143 | |
144 | void SBPlatformConnectOptions::DisableRsync() { |
145 | LLDB_INSTRUMENT_VA(this); |
146 | |
147 | m_opaque_ptr->m_rsync_enabled = false; |
148 | } |
149 | |
150 | const char *SBPlatformConnectOptions::GetLocalCacheDirectory() { |
151 | LLDB_INSTRUMENT_VA(this); |
152 | |
153 | return m_opaque_ptr->m_local_cache_directory.GetCString(); |
154 | } |
155 | |
156 | void SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path) { |
157 | LLDB_INSTRUMENT_VA(this, path); |
158 | |
159 | if (path && path[0]) |
160 | m_opaque_ptr->m_local_cache_directory.SetCString(path); |
161 | else |
162 | m_opaque_ptr->m_local_cache_directory = ConstString(); |
163 | } |
164 | |
165 | // SBPlatformShellCommand |
166 | SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_interpreter, |
167 | const char *shell_command) |
168 | : m_opaque_ptr(new PlatformShellCommand(shell_interpreter, shell_command)) { |
169 | LLDB_INSTRUMENT_VA(this, shell_interpreter, shell_command); |
170 | } |
171 | |
172 | SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_command) |
173 | : m_opaque_ptr(new PlatformShellCommand(shell_command)) { |
174 | LLDB_INSTRUMENT_VA(this, shell_command); |
175 | } |
176 | |
177 | SBPlatformShellCommand::SBPlatformShellCommand( |
178 | const SBPlatformShellCommand &rhs) |
179 | : m_opaque_ptr(new PlatformShellCommand()) { |
180 | LLDB_INSTRUMENT_VA(this, rhs); |
181 | |
182 | *m_opaque_ptr = *rhs.m_opaque_ptr; |
183 | } |
184 | |
185 | SBPlatformShellCommand & |
186 | SBPlatformShellCommand::operator=(const SBPlatformShellCommand &rhs) { |
187 | |
188 | LLDB_INSTRUMENT_VA(this, rhs); |
189 | |
190 | *m_opaque_ptr = *rhs.m_opaque_ptr; |
191 | return *this; |
192 | } |
193 | |
194 | SBPlatformShellCommand::~SBPlatformShellCommand() { delete m_opaque_ptr; } |
195 | |
196 | void SBPlatformShellCommand::Clear() { |
197 | LLDB_INSTRUMENT_VA(this); |
198 | |
199 | m_opaque_ptr->m_output = std::string(); |
200 | m_opaque_ptr->m_status = 0; |
201 | m_opaque_ptr->m_signo = 0; |
202 | } |
203 | |
204 | const char *SBPlatformShellCommand::GetShell() { |
205 | LLDB_INSTRUMENT_VA(this); |
206 | |
207 | if (m_opaque_ptr->m_shell.empty()) |
208 | return nullptr; |
209 | return ConstString(m_opaque_ptr->m_shell.c_str()).GetCString(); |
210 | } |
211 | |
212 | void SBPlatformShellCommand::SetShell(const char *shell_interpreter) { |
213 | LLDB_INSTRUMENT_VA(this, shell_interpreter); |
214 | |
215 | if (shell_interpreter && shell_interpreter[0]) |
216 | m_opaque_ptr->m_shell = shell_interpreter; |
217 | else |
218 | m_opaque_ptr->m_shell.clear(); |
219 | } |
220 | |
221 | const char *SBPlatformShellCommand::GetCommand() { |
222 | LLDB_INSTRUMENT_VA(this); |
223 | |
224 | if (m_opaque_ptr->m_command.empty()) |
225 | return nullptr; |
226 | return ConstString(m_opaque_ptr->m_command.c_str()).GetCString(); |
227 | } |
228 | |
229 | void SBPlatformShellCommand::SetCommand(const char *shell_command) { |
230 | LLDB_INSTRUMENT_VA(this, shell_command); |
231 | |
232 | if (shell_command && shell_command[0]) |
233 | m_opaque_ptr->m_command = shell_command; |
234 | else |
235 | m_opaque_ptr->m_command.clear(); |
236 | } |
237 | |
238 | const char *SBPlatformShellCommand::GetWorkingDirectory() { |
239 | LLDB_INSTRUMENT_VA(this); |
240 | |
241 | if (m_opaque_ptr->m_working_dir.empty()) |
242 | return nullptr; |
243 | return ConstString(m_opaque_ptr->m_working_dir.c_str()).GetCString(); |
244 | } |
245 | |
246 | void SBPlatformShellCommand::SetWorkingDirectory(const char *path) { |
247 | LLDB_INSTRUMENT_VA(this, path); |
248 | |
249 | if (path && path[0]) |
250 | m_opaque_ptr->m_working_dir = path; |
251 | else |
252 | m_opaque_ptr->m_working_dir.clear(); |
253 | } |
254 | |
255 | uint32_t SBPlatformShellCommand::GetTimeoutSeconds() { |
256 | LLDB_INSTRUMENT_VA(this); |
257 | |
258 | if (m_opaque_ptr->m_timeout) |
259 | return m_opaque_ptr->m_timeout->count(); |
260 | return UINT32_MAX; |
261 | } |
262 | |
263 | void SBPlatformShellCommand::SetTimeoutSeconds(uint32_t sec) { |
264 | LLDB_INSTRUMENT_VA(this, sec); |
265 | |
266 | if (sec == UINT32_MAX) |
267 | m_opaque_ptr->m_timeout = std::nullopt; |
268 | else |
269 | m_opaque_ptr->m_timeout = std::chrono::seconds(sec); |
270 | } |
271 | |
272 | int SBPlatformShellCommand::GetSignal() { |
273 | LLDB_INSTRUMENT_VA(this); |
274 | |
275 | return m_opaque_ptr->m_signo; |
276 | } |
277 | |
278 | int SBPlatformShellCommand::GetStatus() { |
279 | LLDB_INSTRUMENT_VA(this); |
280 | |
281 | return m_opaque_ptr->m_status; |
282 | } |
283 | |
284 | const char *SBPlatformShellCommand::GetOutput() { |
285 | LLDB_INSTRUMENT_VA(this); |
286 | |
287 | if (m_opaque_ptr->m_output.empty()) |
288 | return nullptr; |
289 | return ConstString(m_opaque_ptr->m_output.c_str()).GetCString(); |
290 | } |
291 | |
292 | // SBPlatform |
293 | SBPlatform::SBPlatform() { LLDB_INSTRUMENT_VA(this); } |
294 | |
295 | SBPlatform::SBPlatform(const char *platform_name) { |
296 | LLDB_INSTRUMENT_VA(this, platform_name); |
297 | |
298 | m_opaque_sp = Platform::Create(name: platform_name); |
299 | } |
300 | |
301 | SBPlatform::SBPlatform(const SBPlatform &rhs) { |
302 | LLDB_INSTRUMENT_VA(this, rhs); |
303 | |
304 | m_opaque_sp = rhs.m_opaque_sp; |
305 | } |
306 | |
307 | SBPlatform &SBPlatform::operator=(const SBPlatform &rhs) { |
308 | LLDB_INSTRUMENT_VA(this, rhs); |
309 | |
310 | m_opaque_sp = rhs.m_opaque_sp; |
311 | return *this; |
312 | } |
313 | |
314 | SBPlatform::~SBPlatform() = default; |
315 | |
316 | SBPlatform SBPlatform::GetHostPlatform() { |
317 | LLDB_INSTRUMENT(); |
318 | |
319 | SBPlatform host_platform; |
320 | host_platform.m_opaque_sp = Platform::GetHostPlatform(); |
321 | return host_platform; |
322 | } |
323 | |
324 | bool SBPlatform::IsValid() const { |
325 | LLDB_INSTRUMENT_VA(this); |
326 | return this->operator bool(); |
327 | } |
328 | SBPlatform::operator bool() const { |
329 | LLDB_INSTRUMENT_VA(this); |
330 | |
331 | return m_opaque_sp.get() != nullptr; |
332 | } |
333 | |
334 | void SBPlatform::Clear() { |
335 | LLDB_INSTRUMENT_VA(this); |
336 | |
337 | m_opaque_sp.reset(); |
338 | } |
339 | |
340 | const char *SBPlatform::GetName() { |
341 | LLDB_INSTRUMENT_VA(this); |
342 | |
343 | PlatformSP platform_sp(GetSP()); |
344 | if (platform_sp) |
345 | return ConstString(platform_sp->GetName()).AsCString(); |
346 | return nullptr; |
347 | } |
348 | |
349 | lldb::PlatformSP SBPlatform::GetSP() const { return m_opaque_sp; } |
350 | |
351 | void SBPlatform::SetSP(const lldb::PlatformSP &platform_sp) { |
352 | m_opaque_sp = platform_sp; |
353 | } |
354 | |
355 | const char *SBPlatform::GetWorkingDirectory() { |
356 | LLDB_INSTRUMENT_VA(this); |
357 | |
358 | PlatformSP platform_sp(GetSP()); |
359 | if (platform_sp) |
360 | return platform_sp->GetWorkingDirectory().GetPathAsConstString().AsCString(); |
361 | return nullptr; |
362 | } |
363 | |
364 | bool SBPlatform::SetWorkingDirectory(const char *path) { |
365 | LLDB_INSTRUMENT_VA(this, path); |
366 | |
367 | PlatformSP platform_sp(GetSP()); |
368 | if (platform_sp) { |
369 | if (path) |
370 | platform_sp->SetWorkingDirectory(FileSpec(path)); |
371 | else |
372 | platform_sp->SetWorkingDirectory(FileSpec()); |
373 | return true; |
374 | } |
375 | return false; |
376 | } |
377 | |
378 | SBError SBPlatform::ConnectRemote(SBPlatformConnectOptions &connect_options) { |
379 | LLDB_INSTRUMENT_VA(this, connect_options); |
380 | |
381 | SBError sb_error; |
382 | PlatformSP platform_sp(GetSP()); |
383 | if (platform_sp && connect_options.GetURL()) { |
384 | Args args; |
385 | args.AppendArgument(arg_str: connect_options.GetURL()); |
386 | sb_error.ref() = platform_sp->ConnectRemote(args); |
387 | } else { |
388 | sb_error = Status::FromErrorString(str: "invalid platform"); |
389 | } |
390 | return sb_error; |
391 | } |
392 | |
393 | void SBPlatform::DisconnectRemote() { |
394 | LLDB_INSTRUMENT_VA(this); |
395 | |
396 | PlatformSP platform_sp(GetSP()); |
397 | if (platform_sp) |
398 | platform_sp->DisconnectRemote(); |
399 | } |
400 | |
401 | bool SBPlatform::IsConnected() { |
402 | LLDB_INSTRUMENT_VA(this); |
403 | |
404 | PlatformSP platform_sp(GetSP()); |
405 | if (platform_sp) |
406 | return platform_sp->IsConnected(); |
407 | return false; |
408 | } |
409 | |
410 | const char *SBPlatform::GetTriple() { |
411 | LLDB_INSTRUMENT_VA(this); |
412 | |
413 | PlatformSP platform_sp(GetSP()); |
414 | if (platform_sp) { |
415 | ArchSpec arch(platform_sp->GetSystemArchitecture()); |
416 | if (arch.IsValid()) { |
417 | // Const-ify the string so we don't need to worry about the lifetime of |
418 | // the string |
419 | return ConstString(arch.GetTriple().getTriple().c_str()).GetCString(); |
420 | } |
421 | } |
422 | return nullptr; |
423 | } |
424 | |
425 | const char *SBPlatform::GetOSBuild() { |
426 | LLDB_INSTRUMENT_VA(this); |
427 | |
428 | PlatformSP platform_sp(GetSP()); |
429 | if (platform_sp) { |
430 | std::string s = platform_sp->GetOSBuildString().value_or(u: ""); |
431 | if (!s.empty()) { |
432 | // Const-ify the string so we don't need to worry about the lifetime of |
433 | // the string |
434 | return ConstString(s).GetCString(); |
435 | } |
436 | } |
437 | return nullptr; |
438 | } |
439 | |
440 | const char *SBPlatform::GetOSDescription() { |
441 | LLDB_INSTRUMENT_VA(this); |
442 | |
443 | PlatformSP platform_sp(GetSP()); |
444 | if (platform_sp) { |
445 | std::string s = platform_sp->GetOSKernelDescription().value_or(u: ""); |
446 | if (!s.empty()) { |
447 | // Const-ify the string so we don't need to worry about the lifetime of |
448 | // the string |
449 | return ConstString(s.c_str()).GetCString(); |
450 | } |
451 | } |
452 | return nullptr; |
453 | } |
454 | |
455 | const char *SBPlatform::GetHostname() { |
456 | LLDB_INSTRUMENT_VA(this); |
457 | |
458 | PlatformSP platform_sp(GetSP()); |
459 | if (platform_sp) |
460 | return ConstString(platform_sp->GetHostname()).GetCString(); |
461 | return nullptr; |
462 | } |
463 | |
464 | uint32_t SBPlatform::GetOSMajorVersion() { |
465 | LLDB_INSTRUMENT_VA(this); |
466 | |
467 | llvm::VersionTuple version; |
468 | if (PlatformSP platform_sp = GetSP()) |
469 | version = platform_sp->GetOSVersion(); |
470 | return version.empty() ? UINT32_MAX : version.getMajor(); |
471 | } |
472 | |
473 | uint32_t SBPlatform::GetOSMinorVersion() { |
474 | LLDB_INSTRUMENT_VA(this); |
475 | |
476 | llvm::VersionTuple version; |
477 | if (PlatformSP platform_sp = GetSP()) |
478 | version = platform_sp->GetOSVersion(); |
479 | return version.getMinor().value_or(UINT32_MAX); |
480 | } |
481 | |
482 | uint32_t SBPlatform::GetOSUpdateVersion() { |
483 | LLDB_INSTRUMENT_VA(this); |
484 | |
485 | llvm::VersionTuple version; |
486 | if (PlatformSP platform_sp = GetSP()) |
487 | version = platform_sp->GetOSVersion(); |
488 | return version.getSubminor().value_or(UINT32_MAX); |
489 | } |
490 | |
491 | void SBPlatform::SetSDKRoot(const char *sysroot) { |
492 | LLDB_INSTRUMENT_VA(this, sysroot); |
493 | if (PlatformSP platform_sp = GetSP()) |
494 | platform_sp->SetSDKRootDirectory(llvm::StringRef(sysroot).str()); |
495 | } |
496 | |
497 | SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &dst) { |
498 | LLDB_INSTRUMENT_VA(this, src, dst); |
499 | |
500 | SBError sb_error; |
501 | PlatformSP platform_sp(GetSP()); |
502 | if (platform_sp) { |
503 | sb_error.ref() = platform_sp->GetFile(source: src.ref(), destination: dst.ref()); |
504 | } else { |
505 | sb_error = Status::FromErrorString(str: "invalid platform"); |
506 | } |
507 | return sb_error; |
508 | } |
509 | |
510 | SBError SBPlatform::Put(SBFileSpec &src, SBFileSpec &dst) { |
511 | LLDB_INSTRUMENT_VA(this, src, dst); |
512 | return ExecuteConnected(func: [&](const lldb::PlatformSP &platform_sp) { |
513 | if (src.Exists()) { |
514 | uint32_t permissions = FileSystem::Instance().GetPermissions(file_spec: src.ref()); |
515 | if (permissions == 0) { |
516 | if (FileSystem::Instance().IsDirectory(file_spec: src.ref())) |
517 | permissions = eFilePermissionsDirectoryDefault; |
518 | else |
519 | permissions = eFilePermissionsFileDefault; |
520 | } |
521 | |
522 | return platform_sp->PutFile(source: src.ref(), destination: dst.ref(), uid: permissions); |
523 | } |
524 | |
525 | return Status::FromErrorStringWithFormat( |
526 | format: "'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str()); |
527 | }); |
528 | } |
529 | |
530 | SBError SBPlatform::Install(SBFileSpec &src, SBFileSpec &dst) { |
531 | LLDB_INSTRUMENT_VA(this, src, dst); |
532 | return ExecuteConnected(func: [&](const lldb::PlatformSP &platform_sp) { |
533 | if (src.Exists()) |
534 | return platform_sp->Install(src: src.ref(), dst: dst.ref()); |
535 | |
536 | Status error; |
537 | error = Status::FromErrorStringWithFormat( |
538 | format: "'src' argument doesn't exist: '%s'", src.ref().GetPath().c_str()); |
539 | return error; |
540 | }); |
541 | } |
542 | |
543 | SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) { |
544 | LLDB_INSTRUMENT_VA(this, shell_command); |
545 | return ExecuteConnected( |
546 | func: [&](const lldb::PlatformSP &platform_sp) { |
547 | const char *command = shell_command.GetCommand(); |
548 | if (!command) |
549 | return Status::FromErrorString(str: "invalid shell command (empty)"); |
550 | |
551 | if (shell_command.GetWorkingDirectory() == nullptr) { |
552 | std::string platform_working_dir = |
553 | platform_sp->GetWorkingDirectory().GetPath(); |
554 | if (!platform_working_dir.empty()) |
555 | shell_command.SetWorkingDirectory(platform_working_dir.c_str()); |
556 | } |
557 | return platform_sp->RunShellCommand( |
558 | shell: shell_command.m_opaque_ptr->m_shell, command, |
559 | working_dir: FileSpec(shell_command.GetWorkingDirectory()), |
560 | status_ptr: &shell_command.m_opaque_ptr->m_status, |
561 | signo_ptr: &shell_command.m_opaque_ptr->m_signo, |
562 | command_output: &shell_command.m_opaque_ptr->m_output, |
563 | timeout: shell_command.m_opaque_ptr->m_timeout); |
564 | }); |
565 | } |
566 | |
567 | SBError SBPlatform::Launch(SBLaunchInfo &launch_info) { |
568 | LLDB_INSTRUMENT_VA(this, launch_info); |
569 | return ExecuteConnected(func: [&](const lldb::PlatformSP &platform_sp) { |
570 | ProcessLaunchInfo info = launch_info.ref(); |
571 | Status error = platform_sp->LaunchProcess(launch_info&: info); |
572 | launch_info.set_ref(info); |
573 | return error; |
574 | }); |
575 | } |
576 | |
577 | SBProcess SBPlatform::Attach(SBAttachInfo &attach_info, |
578 | const SBDebugger &debugger, SBTarget &target, |
579 | SBError &error) { |
580 | LLDB_INSTRUMENT_VA(this, attach_info, debugger, target, error); |
581 | |
582 | if (PlatformSP platform_sp = GetSP()) { |
583 | if (platform_sp->IsConnected()) { |
584 | ProcessAttachInfo &info = attach_info.ref(); |
585 | Status status; |
586 | ProcessSP process_sp = platform_sp->Attach(attach_info&: info, debugger&: debugger.ref(), |
587 | target: target.GetSP().get(), error&: status); |
588 | error.SetError(std::move(status)); |
589 | return SBProcess(process_sp); |
590 | } |
591 | |
592 | error = Status::FromErrorString(str: "not connected"); |
593 | return {}; |
594 | } |
595 | |
596 | error = Status::FromErrorString(str: "invalid platform"); |
597 | return {}; |
598 | } |
599 | |
600 | SBProcessInfoList SBPlatform::GetAllProcesses(SBError &error) { |
601 | if (PlatformSP platform_sp = GetSP()) { |
602 | if (platform_sp->IsConnected()) { |
603 | ProcessInstanceInfoList list = platform_sp->GetAllProcesses(); |
604 | return SBProcessInfoList(list); |
605 | } |
606 | error = Status::FromErrorString(str: "not connected"); |
607 | return {}; |
608 | } |
609 | |
610 | error = Status::FromErrorString(str: "invalid platform"); |
611 | return {}; |
612 | } |
613 | |
614 | SBError SBPlatform::Kill(const lldb::pid_t pid) { |
615 | LLDB_INSTRUMENT_VA(this, pid); |
616 | return ExecuteConnected(func: [&](const lldb::PlatformSP &platform_sp) { |
617 | return platform_sp->KillProcess(pid); |
618 | }); |
619 | } |
620 | |
621 | SBError SBPlatform::ExecuteConnected( |
622 | const std::function<Status(const lldb::PlatformSP &)> &func) { |
623 | SBError sb_error; |
624 | const auto platform_sp(GetSP()); |
625 | if (platform_sp) { |
626 | if (platform_sp->IsConnected()) |
627 | sb_error.ref() = func(platform_sp); |
628 | else |
629 | sb_error = Status::FromErrorString(str: "not connected"); |
630 | } else |
631 | sb_error = Status::FromErrorString(str: "invalid platform"); |
632 | |
633 | return sb_error; |
634 | } |
635 | |
636 | SBError SBPlatform::MakeDirectory(const char *path, uint32_t file_permissions) { |
637 | LLDB_INSTRUMENT_VA(this, path, file_permissions); |
638 | |
639 | SBError sb_error; |
640 | PlatformSP platform_sp(GetSP()); |
641 | if (platform_sp) { |
642 | sb_error.ref() = |
643 | platform_sp->MakeDirectory(file_spec: FileSpec(path), permissions: file_permissions); |
644 | } else { |
645 | sb_error = Status::FromErrorString(str: "invalid platform"); |
646 | } |
647 | return sb_error; |
648 | } |
649 | |
650 | uint32_t SBPlatform::GetFilePermissions(const char *path) { |
651 | LLDB_INSTRUMENT_VA(this, path); |
652 | |
653 | PlatformSP platform_sp(GetSP()); |
654 | if (platform_sp) { |
655 | uint32_t file_permissions = 0; |
656 | platform_sp->GetFilePermissions(file_spec: FileSpec(path), file_permissions); |
657 | return file_permissions; |
658 | } |
659 | return 0; |
660 | } |
661 | |
662 | SBError SBPlatform::SetFilePermissions(const char *path, |
663 | uint32_t file_permissions) { |
664 | LLDB_INSTRUMENT_VA(this, path, file_permissions); |
665 | |
666 | SBError sb_error; |
667 | PlatformSP platform_sp(GetSP()); |
668 | if (platform_sp) { |
669 | sb_error.ref() = |
670 | platform_sp->SetFilePermissions(file_spec: FileSpec(path), file_permissions); |
671 | } else { |
672 | sb_error = Status::FromErrorString(str: "invalid platform"); |
673 | } |
674 | return sb_error; |
675 | } |
676 | |
677 | SBUnixSignals SBPlatform::GetUnixSignals() const { |
678 | LLDB_INSTRUMENT_VA(this); |
679 | |
680 | if (auto platform_sp = GetSP()) |
681 | return SBUnixSignals{platform_sp}; |
682 | |
683 | return SBUnixSignals(); |
684 | } |
685 | |
686 | SBEnvironment SBPlatform::GetEnvironment() { |
687 | LLDB_INSTRUMENT_VA(this); |
688 | PlatformSP platform_sp(GetSP()); |
689 | |
690 | if (platform_sp) { |
691 | return SBEnvironment(platform_sp->GetEnvironment()); |
692 | } |
693 | |
694 | return SBEnvironment(); |
695 | } |
696 | |
697 | SBError SBPlatform::SetLocateModuleCallback( |
698 | lldb::SBPlatformLocateModuleCallback callback, void *callback_baton) { |
699 | LLDB_INSTRUMENT_VA(this, callback, callback_baton); |
700 | PlatformSP platform_sp(GetSP()); |
701 | if (!platform_sp) |
702 | return SBError("invalid platform"); |
703 | |
704 | if (!callback) { |
705 | // Clear the callback. |
706 | platform_sp->SetLocateModuleCallback(nullptr); |
707 | return SBError(); |
708 | } |
709 | |
710 | // Platform.h does not accept lldb::SBPlatformLocateModuleCallback directly |
711 | // because of the SBModuleSpec and SBFileSpec dependencies. Use a lambda to |
712 | // convert ModuleSpec/FileSpec <--> SBModuleSpec/SBFileSpec for the callback |
713 | // arguments. |
714 | platform_sp->SetLocateModuleCallback( |
715 | [callback, callback_baton](const ModuleSpec &module_spec, |
716 | FileSpec &module_file_spec, |
717 | FileSpec &symbol_file_spec) { |
718 | SBModuleSpec module_spec_sb(module_spec); |
719 | SBFileSpec module_file_spec_sb; |
720 | SBFileSpec symbol_file_spec_sb; |
721 | |
722 | SBError error = callback(callback_baton, module_spec_sb, |
723 | module_file_spec_sb, symbol_file_spec_sb); |
724 | |
725 | if (error.Success()) { |
726 | module_file_spec = module_file_spec_sb.ref(); |
727 | symbol_file_spec = symbol_file_spec_sb.ref(); |
728 | } |
729 | |
730 | return error.ref().Clone(); |
731 | }); |
732 | return SBError(); |
733 | } |
734 |
Definitions
- PlatformConnectOptions
- PlatformConnectOptions
- ~PlatformConnectOptions
- PlatformShellCommand
- PlatformShellCommand
- PlatformShellCommand
- ~PlatformShellCommand
- SBPlatformConnectOptions
- SBPlatformConnectOptions
- ~SBPlatformConnectOptions
- operator=
- GetURL
- SetURL
- GetRsyncEnabled
- EnableRsync
- DisableRsync
- GetLocalCacheDirectory
- SetLocalCacheDirectory
- SBPlatformShellCommand
- SBPlatformShellCommand
- SBPlatformShellCommand
- operator=
- ~SBPlatformShellCommand
- Clear
- GetShell
- SetShell
- GetCommand
- SetCommand
- GetWorkingDirectory
- SetWorkingDirectory
- GetTimeoutSeconds
- SetTimeoutSeconds
- GetSignal
- GetStatus
- GetOutput
- SBPlatform
- SBPlatform
- SBPlatform
- operator=
- ~SBPlatform
- GetHostPlatform
- IsValid
- operator bool
- Clear
- GetName
- GetSP
- SetSP
- GetWorkingDirectory
- SetWorkingDirectory
- ConnectRemote
- DisconnectRemote
- IsConnected
- GetTriple
- GetOSBuild
- GetOSDescription
- GetHostname
- GetOSMajorVersion
- GetOSMinorVersion
- GetOSUpdateVersion
- SetSDKRoot
- Get
- Put
- Install
- Run
- Launch
- Attach
- GetAllProcesses
- Kill
- ExecuteConnected
- MakeDirectory
- GetFilePermissions
- SetFilePermissions
- GetUnixSignals
- GetEnvironment
Improve your Profiling and Debugging skills
Find out more