1 //===-- SBPlatform.cpp ------------------------------------------*- C++ -*-===// 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 "SBReproducerPrivate.h" 11 #include "lldb/API/SBError.h" 12 #include "lldb/API/SBFileSpec.h" 13 #include "lldb/API/SBLaunchInfo.h" 14 #include "lldb/API/SBUnixSignals.h" 15 #include "lldb/Host/File.h" 16 #include "lldb/Target/Platform.h" 17 #include "lldb/Target/Target.h" 18 #include "lldb/Utility/ArchSpec.h" 19 #include "lldb/Utility/Args.h" 20 #include "lldb/Utility/Status.h" 21 22 #include "llvm/Support/FileSystem.h" 23 24 #include <functional> 25 26 using namespace lldb; 27 using namespace lldb_private; 28 29 //---------------------------------------------------------------------- 30 // PlatformConnectOptions 31 //---------------------------------------------------------------------- 32 struct PlatformConnectOptions { 33 PlatformConnectOptions(const char *url = NULL) 34 : m_url(), m_rsync_options(), m_rsync_remote_path_prefix(), 35 m_rsync_enabled(false), m_rsync_omit_hostname_from_remote_path(false), 36 m_local_cache_directory() { 37 if (url && url[0]) 38 m_url = url; 39 } 40 41 ~PlatformConnectOptions() {} 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; 47 bool m_rsync_omit_hostname_from_remote_path; 48 ConstString m_local_cache_directory; 49 }; 50 51 //---------------------------------------------------------------------- 52 // PlatformShellCommand 53 //---------------------------------------------------------------------- 54 struct PlatformShellCommand { 55 PlatformShellCommand(const char *shell_command = NULL) 56 : m_command(), m_working_dir(), m_status(0), m_signo(0) { 57 if (shell_command && shell_command[0]) 58 m_command = shell_command; 59 } 60 61 ~PlatformShellCommand() {} 62 63 std::string m_command; 64 std::string m_working_dir; 65 std::string m_output; 66 int m_status; 67 int m_signo; 68 Timeout<std::ratio<1>> m_timeout = llvm::None; 69 }; 70 //---------------------------------------------------------------------- 71 // SBPlatformConnectOptions 72 //---------------------------------------------------------------------- 73 SBPlatformConnectOptions::SBPlatformConnectOptions(const char *url) 74 : m_opaque_ptr(new PlatformConnectOptions(url)) { 75 LLDB_RECORD_CONSTRUCTOR(SBPlatformConnectOptions, (const char *), url); 76 } 77 78 SBPlatformConnectOptions::SBPlatformConnectOptions( 79 const SBPlatformConnectOptions &rhs) 80 : m_opaque_ptr(new PlatformConnectOptions()) { 81 LLDB_RECORD_CONSTRUCTOR(SBPlatformConnectOptions, 82 (const lldb::SBPlatformConnectOptions &), rhs); 83 84 *m_opaque_ptr = *rhs.m_opaque_ptr; 85 } 86 87 SBPlatformConnectOptions::~SBPlatformConnectOptions() { delete m_opaque_ptr; } 88 89 void SBPlatformConnectOptions::operator=(const SBPlatformConnectOptions &rhs) { 90 LLDB_RECORD_METHOD( 91 void, 92 SBPlatformConnectOptions, operator=,( 93 const lldb::SBPlatformConnectOptions &), 94 rhs); 95 96 *m_opaque_ptr = *rhs.m_opaque_ptr; 97 } 98 99 const char *SBPlatformConnectOptions::GetURL() { 100 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatformConnectOptions, GetURL); 101 102 if (m_opaque_ptr->m_url.empty()) 103 return NULL; 104 return m_opaque_ptr->m_url.c_str(); 105 } 106 107 void SBPlatformConnectOptions::SetURL(const char *url) { 108 LLDB_RECORD_METHOD(void, SBPlatformConnectOptions, SetURL, (const char *), 109 url); 110 111 if (url && url[0]) 112 m_opaque_ptr->m_url = url; 113 else 114 m_opaque_ptr->m_url.clear(); 115 } 116 117 bool SBPlatformConnectOptions::GetRsyncEnabled() { 118 LLDB_RECORD_METHOD_NO_ARGS(bool, SBPlatformConnectOptions, GetRsyncEnabled); 119 120 return m_opaque_ptr->m_rsync_enabled; 121 } 122 123 void SBPlatformConnectOptions::EnableRsync( 124 const char *options, const char *remote_path_prefix, 125 bool omit_hostname_from_remote_path) { 126 LLDB_RECORD_METHOD(void, SBPlatformConnectOptions, EnableRsync, 127 (const char *, const char *, bool), options, 128 remote_path_prefix, 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_RECORD_METHOD_NO_ARGS(void, SBPlatformConnectOptions, DisableRsync); 146 147 m_opaque_ptr->m_rsync_enabled = false; 148 } 149 150 const char *SBPlatformConnectOptions::GetLocalCacheDirectory() { 151 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatformConnectOptions, 152 GetLocalCacheDirectory); 153 154 return m_opaque_ptr->m_local_cache_directory.GetCString(); 155 } 156 157 void SBPlatformConnectOptions::SetLocalCacheDirectory(const char *path) { 158 LLDB_RECORD_METHOD(void, SBPlatformConnectOptions, SetLocalCacheDirectory, 159 (const char *), path); 160 161 if (path && path[0]) 162 m_opaque_ptr->m_local_cache_directory.SetCString(path); 163 else 164 m_opaque_ptr->m_local_cache_directory = ConstString(); 165 } 166 167 //---------------------------------------------------------------------- 168 // SBPlatformShellCommand 169 //---------------------------------------------------------------------- 170 SBPlatformShellCommand::SBPlatformShellCommand(const char *shell_command) 171 : m_opaque_ptr(new PlatformShellCommand(shell_command)) { 172 LLDB_RECORD_CONSTRUCTOR(SBPlatformShellCommand, (const char *), 173 shell_command); 174 } 175 176 SBPlatformShellCommand::SBPlatformShellCommand( 177 const SBPlatformShellCommand &rhs) 178 : m_opaque_ptr(new PlatformShellCommand()) { 179 LLDB_RECORD_CONSTRUCTOR(SBPlatformShellCommand, 180 (const lldb::SBPlatformShellCommand &), rhs); 181 182 *m_opaque_ptr = *rhs.m_opaque_ptr; 183 } 184 185 SBPlatformShellCommand::~SBPlatformShellCommand() { delete m_opaque_ptr; } 186 187 void SBPlatformShellCommand::Clear() { 188 LLDB_RECORD_METHOD_NO_ARGS(void, SBPlatformShellCommand, Clear); 189 190 m_opaque_ptr->m_output = std::string(); 191 m_opaque_ptr->m_status = 0; 192 m_opaque_ptr->m_signo = 0; 193 } 194 195 const char *SBPlatformShellCommand::GetCommand() { 196 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatformShellCommand, GetCommand); 197 198 if (m_opaque_ptr->m_command.empty()) 199 return NULL; 200 return m_opaque_ptr->m_command.c_str(); 201 } 202 203 void SBPlatformShellCommand::SetCommand(const char *shell_command) { 204 LLDB_RECORD_METHOD(void, SBPlatformShellCommand, SetCommand, (const char *), 205 shell_command); 206 207 if (shell_command && shell_command[0]) 208 m_opaque_ptr->m_command = shell_command; 209 else 210 m_opaque_ptr->m_command.clear(); 211 } 212 213 const char *SBPlatformShellCommand::GetWorkingDirectory() { 214 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatformShellCommand, 215 GetWorkingDirectory); 216 217 if (m_opaque_ptr->m_working_dir.empty()) 218 return NULL; 219 return m_opaque_ptr->m_working_dir.c_str(); 220 } 221 222 void SBPlatformShellCommand::SetWorkingDirectory(const char *path) { 223 LLDB_RECORD_METHOD(void, SBPlatformShellCommand, SetWorkingDirectory, 224 (const char *), path); 225 226 if (path && path[0]) 227 m_opaque_ptr->m_working_dir = path; 228 else 229 m_opaque_ptr->m_working_dir.clear(); 230 } 231 232 uint32_t SBPlatformShellCommand::GetTimeoutSeconds() { 233 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBPlatformShellCommand, 234 GetTimeoutSeconds); 235 236 if (m_opaque_ptr->m_timeout) 237 return m_opaque_ptr->m_timeout->count(); 238 return UINT32_MAX; 239 } 240 241 void SBPlatformShellCommand::SetTimeoutSeconds(uint32_t sec) { 242 LLDB_RECORD_METHOD(void, SBPlatformShellCommand, SetTimeoutSeconds, 243 (uint32_t), sec); 244 245 if (sec == UINT32_MAX) 246 m_opaque_ptr->m_timeout = llvm::None; 247 else 248 m_opaque_ptr->m_timeout = std::chrono::seconds(sec); 249 } 250 251 int SBPlatformShellCommand::GetSignal() { 252 LLDB_RECORD_METHOD_NO_ARGS(int, SBPlatformShellCommand, GetSignal); 253 254 return m_opaque_ptr->m_signo; 255 } 256 257 int SBPlatformShellCommand::GetStatus() { 258 LLDB_RECORD_METHOD_NO_ARGS(int, SBPlatformShellCommand, GetStatus); 259 260 return m_opaque_ptr->m_status; 261 } 262 263 const char *SBPlatformShellCommand::GetOutput() { 264 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatformShellCommand, GetOutput); 265 266 if (m_opaque_ptr->m_output.empty()) 267 return NULL; 268 return m_opaque_ptr->m_output.c_str(); 269 } 270 271 //---------------------------------------------------------------------- 272 // SBPlatform 273 //---------------------------------------------------------------------- 274 SBPlatform::SBPlatform() : m_opaque_sp() { 275 LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBPlatform); 276 } 277 278 SBPlatform::SBPlatform(const char *platform_name) : m_opaque_sp() { 279 LLDB_RECORD_CONSTRUCTOR(SBPlatform, (const char *), platform_name); 280 281 Status error; 282 if (platform_name && platform_name[0]) 283 m_opaque_sp = Platform::Create(ConstString(platform_name), error); 284 } 285 286 SBPlatform::~SBPlatform() {} 287 288 bool SBPlatform::IsValid() const { 289 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBPlatform, IsValid); 290 291 return m_opaque_sp.get() != NULL; 292 } 293 294 void SBPlatform::Clear() { 295 LLDB_RECORD_METHOD_NO_ARGS(void, SBPlatform, Clear); 296 297 m_opaque_sp.reset(); 298 } 299 300 const char *SBPlatform::GetName() { 301 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatform, GetName); 302 303 PlatformSP platform_sp(GetSP()); 304 if (platform_sp) 305 return platform_sp->GetName().GetCString(); 306 return NULL; 307 } 308 309 lldb::PlatformSP SBPlatform::GetSP() const { return m_opaque_sp; } 310 311 void SBPlatform::SetSP(const lldb::PlatformSP &platform_sp) { 312 m_opaque_sp = platform_sp; 313 } 314 315 const char *SBPlatform::GetWorkingDirectory() { 316 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatform, GetWorkingDirectory); 317 318 PlatformSP platform_sp(GetSP()); 319 if (platform_sp) 320 return platform_sp->GetWorkingDirectory().GetCString(); 321 return NULL; 322 } 323 324 bool SBPlatform::SetWorkingDirectory(const char *path) { 325 LLDB_RECORD_METHOD(bool, SBPlatform, SetWorkingDirectory, (const char *), 326 path); 327 328 PlatformSP platform_sp(GetSP()); 329 if (platform_sp) { 330 if (path) 331 platform_sp->SetWorkingDirectory(FileSpec(path)); 332 else 333 platform_sp->SetWorkingDirectory(FileSpec()); 334 return true; 335 } 336 return false; 337 } 338 339 SBError SBPlatform::ConnectRemote(SBPlatformConnectOptions &connect_options) { 340 LLDB_RECORD_METHOD(lldb::SBError, SBPlatform, ConnectRemote, 341 (lldb::SBPlatformConnectOptions &), connect_options); 342 343 SBError sb_error; 344 PlatformSP platform_sp(GetSP()); 345 if (platform_sp && connect_options.GetURL()) { 346 Args args; 347 args.AppendArgument( 348 llvm::StringRef::withNullAsEmpty(connect_options.GetURL())); 349 sb_error.ref() = platform_sp->ConnectRemote(args); 350 } else { 351 sb_error.SetErrorString("invalid platform"); 352 } 353 return LLDB_RECORD_RESULT(sb_error); 354 } 355 356 void SBPlatform::DisconnectRemote() { 357 LLDB_RECORD_METHOD_NO_ARGS(void, SBPlatform, DisconnectRemote); 358 359 PlatformSP platform_sp(GetSP()); 360 if (platform_sp) 361 platform_sp->DisconnectRemote(); 362 } 363 364 bool SBPlatform::IsConnected() { 365 LLDB_RECORD_METHOD_NO_ARGS(bool, SBPlatform, IsConnected); 366 367 PlatformSP platform_sp(GetSP()); 368 if (platform_sp) 369 return platform_sp->IsConnected(); 370 return false; 371 } 372 373 const char *SBPlatform::GetTriple() { 374 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatform, GetTriple); 375 376 PlatformSP platform_sp(GetSP()); 377 if (platform_sp) { 378 ArchSpec arch(platform_sp->GetSystemArchitecture()); 379 if (arch.IsValid()) { 380 // Const-ify the string so we don't need to worry about the lifetime of 381 // the string 382 return ConstString(arch.GetTriple().getTriple().c_str()).GetCString(); 383 } 384 } 385 return NULL; 386 } 387 388 const char *SBPlatform::GetOSBuild() { 389 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatform, GetOSBuild); 390 391 PlatformSP platform_sp(GetSP()); 392 if (platform_sp) { 393 std::string s; 394 if (platform_sp->GetOSBuildString(s)) { 395 if (!s.empty()) { 396 // Const-ify the string so we don't need to worry about the lifetime of 397 // the string 398 return ConstString(s.c_str()).GetCString(); 399 } 400 } 401 } 402 return NULL; 403 } 404 405 const char *SBPlatform::GetOSDescription() { 406 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatform, GetOSDescription); 407 408 PlatformSP platform_sp(GetSP()); 409 if (platform_sp) { 410 std::string s; 411 if (platform_sp->GetOSKernelDescription(s)) { 412 if (!s.empty()) { 413 // Const-ify the string so we don't need to worry about the lifetime of 414 // the string 415 return ConstString(s.c_str()).GetCString(); 416 } 417 } 418 } 419 return NULL; 420 } 421 422 const char *SBPlatform::GetHostname() { 423 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBPlatform, GetHostname); 424 425 PlatformSP platform_sp(GetSP()); 426 if (platform_sp) 427 return platform_sp->GetHostname(); 428 return NULL; 429 } 430 431 uint32_t SBPlatform::GetOSMajorVersion() { 432 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBPlatform, GetOSMajorVersion); 433 434 llvm::VersionTuple version; 435 if (PlatformSP platform_sp = GetSP()) 436 version = platform_sp->GetOSVersion(); 437 return version.empty() ? UINT32_MAX : version.getMajor(); 438 } 439 440 uint32_t SBPlatform::GetOSMinorVersion() { 441 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBPlatform, GetOSMinorVersion); 442 443 llvm::VersionTuple version; 444 if (PlatformSP platform_sp = GetSP()) 445 version = platform_sp->GetOSVersion(); 446 return version.getMinor().getValueOr(UINT32_MAX); 447 } 448 449 uint32_t SBPlatform::GetOSUpdateVersion() { 450 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBPlatform, GetOSUpdateVersion); 451 452 llvm::VersionTuple version; 453 if (PlatformSP platform_sp = GetSP()) 454 version = platform_sp->GetOSVersion(); 455 return version.getSubminor().getValueOr(UINT32_MAX); 456 } 457 458 SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &dst) { 459 LLDB_RECORD_METHOD(lldb::SBError, SBPlatform, Get, 460 (lldb::SBFileSpec &, lldb::SBFileSpec &), src, dst); 461 462 SBError sb_error; 463 PlatformSP platform_sp(GetSP()); 464 if (platform_sp) { 465 sb_error.ref() = platform_sp->GetFile(src.ref(), dst.ref()); 466 } else { 467 sb_error.SetErrorString("invalid platform"); 468 } 469 return LLDB_RECORD_RESULT(sb_error); 470 } 471 472 SBError SBPlatform::Put(SBFileSpec &src, SBFileSpec &dst) { 473 LLDB_RECORD_METHOD(lldb::SBError, SBPlatform, Put, 474 (lldb::SBFileSpec &, lldb::SBFileSpec &), src, dst); 475 return LLDB_RECORD_RESULT( 476 ExecuteConnected([&](const lldb::PlatformSP &platform_sp) { 477 if (src.Exists()) { 478 uint32_t permissions = 479 FileSystem::Instance().GetPermissions(src.ref()); 480 if (permissions == 0) { 481 if (FileSystem::Instance().IsDirectory(src.ref())) 482 permissions = eFilePermissionsDirectoryDefault; 483 else 484 permissions = eFilePermissionsFileDefault; 485 } 486 487 return platform_sp->PutFile(src.ref(), dst.ref(), permissions); 488 } 489 490 Status error; 491 error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", 492 src.ref().GetPath().c_str()); 493 return error; 494 })); 495 } 496 497 SBError SBPlatform::Install(SBFileSpec &src, SBFileSpec &dst) { 498 LLDB_RECORD_METHOD(lldb::SBError, SBPlatform, Install, 499 (lldb::SBFileSpec &, lldb::SBFileSpec &), src, dst); 500 return LLDB_RECORD_RESULT( 501 ExecuteConnected([&](const lldb::PlatformSP &platform_sp) { 502 if (src.Exists()) 503 return platform_sp->Install(src.ref(), dst.ref()); 504 505 Status error; 506 error.SetErrorStringWithFormat("'src' argument doesn't exist: '%s'", 507 src.ref().GetPath().c_str()); 508 return error; 509 })); 510 } 511 512 SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) { 513 LLDB_RECORD_METHOD(lldb::SBError, SBPlatform, Run, 514 (lldb::SBPlatformShellCommand &), shell_command); 515 return LLDB_RECORD_RESULT(ExecuteConnected([&](const lldb::PlatformSP 516 &platform_sp) { 517 const char *command = shell_command.GetCommand(); 518 if (!command) 519 return Status("invalid shell command (empty)"); 520 521 const char *working_dir = shell_command.GetWorkingDirectory(); 522 if (working_dir == NULL) { 523 working_dir = platform_sp->GetWorkingDirectory().GetCString(); 524 if (working_dir) 525 shell_command.SetWorkingDirectory(working_dir); 526 } 527 return platform_sp->RunShellCommand(command, FileSpec(working_dir), 528 &shell_command.m_opaque_ptr->m_status, 529 &shell_command.m_opaque_ptr->m_signo, 530 &shell_command.m_opaque_ptr->m_output, 531 shell_command.m_opaque_ptr->m_timeout); 532 })); 533 } 534 535 SBError SBPlatform::Launch(SBLaunchInfo &launch_info) { 536 LLDB_RECORD_METHOD(lldb::SBError, SBPlatform, Launch, (lldb::SBLaunchInfo &), 537 launch_info); 538 return LLDB_RECORD_RESULT( 539 ExecuteConnected([&](const lldb::PlatformSP &platform_sp) { 540 ProcessLaunchInfo info = launch_info.ref(); 541 Status error = platform_sp->LaunchProcess(info); 542 launch_info.set_ref(info); 543 return error; 544 })); 545 } 546 547 SBError SBPlatform::Kill(const lldb::pid_t pid) { 548 LLDB_RECORD_METHOD(lldb::SBError, SBPlatform, Kill, (const lldb::pid_t), pid); 549 return LLDB_RECORD_RESULT( 550 ExecuteConnected([&](const lldb::PlatformSP &platform_sp) { 551 return platform_sp->KillProcess(pid); 552 })); 553 } 554 555 SBError SBPlatform::ExecuteConnected( 556 const std::function<Status(const lldb::PlatformSP &)> &func) { 557 SBError sb_error; 558 const auto platform_sp(GetSP()); 559 if (platform_sp) { 560 if (platform_sp->IsConnected()) 561 sb_error.ref() = func(platform_sp); 562 else 563 sb_error.SetErrorString("not connected"); 564 } else 565 sb_error.SetErrorString("invalid platform"); 566 567 return sb_error; 568 } 569 570 SBError SBPlatform::MakeDirectory(const char *path, uint32_t file_permissions) { 571 LLDB_RECORD_METHOD(lldb::SBError, SBPlatform, MakeDirectory, 572 (const char *, uint32_t), path, file_permissions); 573 574 SBError sb_error; 575 PlatformSP platform_sp(GetSP()); 576 if (platform_sp) { 577 sb_error.ref() = 578 platform_sp->MakeDirectory(FileSpec(path), file_permissions); 579 } else { 580 sb_error.SetErrorString("invalid platform"); 581 } 582 return LLDB_RECORD_RESULT(sb_error); 583 } 584 585 uint32_t SBPlatform::GetFilePermissions(const char *path) { 586 LLDB_RECORD_METHOD(uint32_t, SBPlatform, GetFilePermissions, (const char *), 587 path); 588 589 PlatformSP platform_sp(GetSP()); 590 if (platform_sp) { 591 uint32_t file_permissions = 0; 592 platform_sp->GetFilePermissions(FileSpec(path), file_permissions); 593 return file_permissions; 594 } 595 return 0; 596 } 597 598 SBError SBPlatform::SetFilePermissions(const char *path, 599 uint32_t file_permissions) { 600 LLDB_RECORD_METHOD(lldb::SBError, SBPlatform, SetFilePermissions, 601 (const char *, uint32_t), path, file_permissions); 602 603 SBError sb_error; 604 PlatformSP platform_sp(GetSP()); 605 if (platform_sp) { 606 sb_error.ref() = 607 platform_sp->SetFilePermissions(FileSpec(path), file_permissions); 608 } else { 609 sb_error.SetErrorString("invalid platform"); 610 } 611 return LLDB_RECORD_RESULT(sb_error); 612 } 613 614 SBUnixSignals SBPlatform::GetUnixSignals() const { 615 LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::SBUnixSignals, SBPlatform, 616 GetUnixSignals); 617 618 if (auto platform_sp = GetSP()) 619 return LLDB_RECORD_RESULT(SBUnixSignals{platform_sp}); 620 621 return LLDB_RECORD_RESULT(SBUnixSignals()); 622 } 623