1 //===-- SBDebugger.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/Utility/ReproducerInstrumentation.h" 10 #include "SystemInitializerFull.h" 11 12 #include "lldb/API/SBDebugger.h" 13 14 #include "lldb/API/SBBroadcaster.h" 15 #include "lldb/API/SBCommandInterpreter.h" 16 #include "lldb/API/SBCommandInterpreterRunOptions.h" 17 #include "lldb/API/SBCommandReturnObject.h" 18 #include "lldb/API/SBError.h" 19 #include "lldb/API/SBEvent.h" 20 #include "lldb/API/SBFile.h" 21 #include "lldb/API/SBFrame.h" 22 #include "lldb/API/SBListener.h" 23 #include "lldb/API/SBProcess.h" 24 #include "lldb/API/SBSourceManager.h" 25 #include "lldb/API/SBStream.h" 26 #include "lldb/API/SBStringList.h" 27 #include "lldb/API/SBStructuredData.h" 28 #include "lldb/API/SBTarget.h" 29 #include "lldb/API/SBThread.h" 30 #include "lldb/API/SBTypeCategory.h" 31 #include "lldb/API/SBTypeFilter.h" 32 #include "lldb/API/SBTypeFormat.h" 33 #include "lldb/API/SBTypeNameSpecifier.h" 34 #include "lldb/API/SBTypeSummary.h" 35 #include "lldb/API/SBTypeSynthetic.h" 36 37 #include "lldb/Core/Debugger.h" 38 #include "lldb/Core/PluginManager.h" 39 #include "lldb/Core/Progress.h" 40 #include "lldb/Core/StreamFile.h" 41 #include "lldb/Core/StructuredDataImpl.h" 42 #include "lldb/DataFormatters/DataVisualization.h" 43 #include "lldb/Host/Config.h" 44 #include "lldb/Host/XML.h" 45 #include "lldb/Initialization/SystemLifetimeManager.h" 46 #include "lldb/Interpreter/CommandInterpreter.h" 47 #include "lldb/Interpreter/OptionArgParser.h" 48 #include "lldb/Interpreter/OptionGroupPlatform.h" 49 #include "lldb/Target/Process.h" 50 #include "lldb/Target/TargetList.h" 51 #include "lldb/Utility/Args.h" 52 #include "lldb/Utility/State.h" 53 #include "lldb/Version/Version.h" 54 55 #include "llvm/ADT/STLExtras.h" 56 #include "llvm/ADT/StringRef.h" 57 #include "llvm/Support/DynamicLibrary.h" 58 #include "llvm/Support/ManagedStatic.h" 59 60 using namespace lldb; 61 using namespace lldb_private; 62 63 static llvm::sys::DynamicLibrary LoadPlugin(const lldb::DebuggerSP &debugger_sp, 64 const FileSpec &spec, 65 Status &error) { 66 llvm::sys::DynamicLibrary dynlib = 67 llvm::sys::DynamicLibrary::getPermanentLibrary(spec.GetPath().c_str()); 68 if (dynlib.isValid()) { 69 typedef bool (*LLDBCommandPluginInit)(lldb::SBDebugger & debugger); 70 71 lldb::SBDebugger debugger_sb(debugger_sp); 72 // This calls the bool lldb::PluginInitialize(lldb::SBDebugger debugger) 73 // function. 74 // TODO: mangle this differently for your system - on OSX, the first 75 // underscore needs to be removed and the second one stays 76 LLDBCommandPluginInit init_func = 77 (LLDBCommandPluginInit)(uintptr_t)dynlib.getAddressOfSymbol( 78 "_ZN4lldb16PluginInitializeENS_10SBDebuggerE"); 79 if (init_func) { 80 if (init_func(debugger_sb)) 81 return dynlib; 82 else 83 error.SetErrorString("plug-in refused to load " 84 "(lldb::PluginInitialize(lldb::SBDebugger) " 85 "returned false)"); 86 } else { 87 error.SetErrorString("plug-in is missing the required initialization: " 88 "lldb::PluginInitialize(lldb::SBDebugger)"); 89 } 90 } else { 91 if (FileSystem::Instance().Exists(spec)) 92 error.SetErrorString("this file does not represent a loadable dylib"); 93 else 94 error.SetErrorString("no such file"); 95 } 96 return llvm::sys::DynamicLibrary(); 97 } 98 99 static llvm::ManagedStatic<SystemLifetimeManager> g_debugger_lifetime; 100 101 SBError SBInputReader::Initialize( 102 lldb::SBDebugger &sb_debugger, 103 unsigned long (*callback)(void *, lldb::SBInputReader *, 104 lldb::InputReaderAction, char const *, 105 unsigned long), 106 void *a, lldb::InputReaderGranularity b, char const *c, char const *d, 107 bool e) { 108 LLDB_RECORD_DUMMY( 109 lldb::SBError, SBInputReader, Initialize, 110 (lldb::SBDebugger &, 111 unsigned long (*)(void *, lldb::SBInputReader *, lldb::InputReaderAction, 112 const char *, unsigned long), 113 void *, lldb::InputReaderGranularity, const char *, const char *, bool), 114 sb_debugger, callback, a, b, c, d, e); 115 116 return SBError(); 117 } 118 119 void SBInputReader::SetIsDone(bool b) { 120 LLDB_RECORD_METHOD(void, SBInputReader, SetIsDone, (bool), b); 121 } 122 123 bool SBInputReader::IsActive() const { 124 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBInputReader, IsActive); 125 126 return false; 127 } 128 129 SBDebugger::SBDebugger() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBDebugger); } 130 131 SBDebugger::SBDebugger(const lldb::DebuggerSP &debugger_sp) 132 : m_opaque_sp(debugger_sp) { 133 LLDB_RECORD_CONSTRUCTOR(SBDebugger, (const lldb::DebuggerSP &), debugger_sp); 134 } 135 136 SBDebugger::SBDebugger(const SBDebugger &rhs) : m_opaque_sp(rhs.m_opaque_sp) { 137 LLDB_RECORD_CONSTRUCTOR(SBDebugger, (const lldb::SBDebugger &), rhs); 138 } 139 140 SBDebugger::~SBDebugger() = default; 141 142 SBDebugger &SBDebugger::operator=(const SBDebugger &rhs) { 143 LLDB_RECORD_METHOD(lldb::SBDebugger &, 144 SBDebugger, operator=,(const lldb::SBDebugger &), rhs); 145 146 if (this != &rhs) { 147 m_opaque_sp = rhs.m_opaque_sp; 148 } 149 return *this; 150 } 151 152 const char *SBDebugger::GetBroadcasterClass() { 153 LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBDebugger, 154 GetBroadcasterClass); 155 156 return Debugger::GetStaticBroadcasterClass().AsCString(); 157 } 158 159 const char *SBDebugger::GetProgressFromEvent(const lldb::SBEvent &event, 160 uint64_t &progress_id, 161 uint64_t &completed, 162 uint64_t &total, 163 bool &is_debugger_specific) { 164 const Debugger::ProgressEventData *progress_data = 165 Debugger::ProgressEventData::GetEventDataFromEvent(event.get()); 166 if (progress_data == nullptr) 167 return nullptr; 168 progress_id = progress_data->GetID(); 169 completed = progress_data->GetCompleted(); 170 total = progress_data->GetTotal(); 171 is_debugger_specific = progress_data->IsDebuggerSpecific(); 172 // We must record the static method _after_ the out parameters have been 173 // filled in. 174 LLDB_RECORD_STATIC_METHOD( 175 const char *, SBDebugger, GetProgressFromEvent, 176 (const lldb::SBEvent &, uint64_t &, uint64_t &, uint64_t &, bool &), 177 event, progress_id, completed, total, is_debugger_specific); 178 return progress_data->GetMessage().c_str(); 179 } 180 181 SBBroadcaster SBDebugger::GetBroadcaster() { 182 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBroadcaster, SBDebugger, GetBroadcaster); 183 SBBroadcaster broadcaster(&m_opaque_sp->GetBroadcaster(), false); 184 return broadcaster; 185 } 186 187 void SBDebugger::Initialize() { 188 LLDB_RECORD_STATIC_METHOD_NO_ARGS(void, SBDebugger, Initialize); 189 SBError ignored = SBDebugger::InitializeWithErrorHandling(); 190 } 191 192 lldb::SBError SBDebugger::InitializeWithErrorHandling() { 193 LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBError, SBDebugger, 194 InitializeWithErrorHandling); 195 196 SBError error; 197 if (auto e = g_debugger_lifetime->Initialize( 198 std::make_unique<SystemInitializerFull>(), LoadPlugin)) { 199 error.SetError(Status(std::move(e))); 200 } 201 return error; 202 } 203 204 void SBDebugger::Terminate() { 205 LLDB_RECORD_STATIC_METHOD_NO_ARGS(void, SBDebugger, Terminate); 206 207 g_debugger_lifetime->Terminate(); 208 } 209 210 void SBDebugger::Clear() { 211 LLDB_RECORD_METHOD_NO_ARGS(void, SBDebugger, Clear); 212 213 if (m_opaque_sp) 214 m_opaque_sp->ClearIOHandlers(); 215 216 m_opaque_sp.reset(); 217 } 218 219 SBDebugger SBDebugger::Create() { 220 LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBDebugger, SBDebugger, Create); 221 222 return SBDebugger::Create(false, nullptr, nullptr); 223 } 224 225 SBDebugger SBDebugger::Create(bool source_init_files) { 226 LLDB_RECORD_STATIC_METHOD(lldb::SBDebugger, SBDebugger, Create, (bool), 227 source_init_files); 228 229 return SBDebugger::Create(source_init_files, nullptr, nullptr); 230 } 231 232 SBDebugger SBDebugger::Create(bool source_init_files, 233 lldb::LogOutputCallback callback, void *baton) 234 235 { 236 LLDB_RECORD_DUMMY(lldb::SBDebugger, SBDebugger, Create, 237 (bool, lldb::LogOutputCallback, void *), source_init_files, 238 callback, baton); 239 240 SBDebugger debugger; 241 242 // Currently we have issues if this function is called simultaneously on two 243 // different threads. The issues mainly revolve around the fact that the 244 // lldb_private::FormatManager uses global collections and having two threads 245 // parsing the .lldbinit files can cause mayhem. So to get around this for 246 // now we need to use a mutex to prevent bad things from happening. 247 static std::recursive_mutex g_mutex; 248 std::lock_guard<std::recursive_mutex> guard(g_mutex); 249 250 debugger.reset(Debugger::CreateInstance(callback, baton)); 251 252 SBCommandInterpreter interp = debugger.GetCommandInterpreter(); 253 if (source_init_files) { 254 interp.get()->SkipLLDBInitFiles(false); 255 interp.get()->SkipAppInitFiles(false); 256 SBCommandReturnObject result; 257 interp.SourceInitFileInHomeDirectory(result, false); 258 } else { 259 interp.get()->SkipLLDBInitFiles(true); 260 interp.get()->SkipAppInitFiles(true); 261 } 262 return debugger; 263 } 264 265 void SBDebugger::Destroy(SBDebugger &debugger) { 266 LLDB_RECORD_STATIC_METHOD(void, SBDebugger, Destroy, (lldb::SBDebugger &), 267 debugger); 268 269 Debugger::Destroy(debugger.m_opaque_sp); 270 271 if (debugger.m_opaque_sp.get() != nullptr) 272 debugger.m_opaque_sp.reset(); 273 } 274 275 void SBDebugger::MemoryPressureDetected() { 276 LLDB_RECORD_STATIC_METHOD_NO_ARGS(void, SBDebugger, MemoryPressureDetected); 277 278 // Since this function can be call asynchronously, we allow it to be non- 279 // mandatory. We have seen deadlocks with this function when called so we 280 // need to safeguard against this until we can determine what is causing the 281 // deadlocks. 282 283 const bool mandatory = false; 284 285 ModuleList::RemoveOrphanSharedModules(mandatory); 286 } 287 288 bool SBDebugger::IsValid() const { 289 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDebugger, IsValid); 290 return this->operator bool(); 291 } 292 SBDebugger::operator bool() const { 293 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDebugger, operator bool); 294 295 return m_opaque_sp.get() != nullptr; 296 } 297 298 void SBDebugger::SetAsync(bool b) { 299 LLDB_RECORD_METHOD(void, SBDebugger, SetAsync, (bool), b); 300 301 if (m_opaque_sp) 302 m_opaque_sp->SetAsyncExecution(b); 303 } 304 305 bool SBDebugger::GetAsync() { 306 LLDB_RECORD_METHOD_NO_ARGS(bool, SBDebugger, GetAsync); 307 308 return (m_opaque_sp ? m_opaque_sp->GetAsyncExecution() : false); 309 } 310 311 void SBDebugger::SkipLLDBInitFiles(bool b) { 312 LLDB_RECORD_METHOD(void, SBDebugger, SkipLLDBInitFiles, (bool), b); 313 314 if (m_opaque_sp) 315 m_opaque_sp->GetCommandInterpreter().SkipLLDBInitFiles(b); 316 } 317 318 void SBDebugger::SkipAppInitFiles(bool b) { 319 LLDB_RECORD_METHOD(void, SBDebugger, SkipAppInitFiles, (bool), b); 320 321 if (m_opaque_sp) 322 m_opaque_sp->GetCommandInterpreter().SkipAppInitFiles(b); 323 } 324 325 void SBDebugger::SetInputFileHandle(FILE *fh, bool transfer_ownership) { 326 LLDB_RECORD_METHOD(void, SBDebugger, SetInputFileHandle, (FILE *, bool), fh, 327 transfer_ownership); 328 if (m_opaque_sp) 329 m_opaque_sp->SetInputFile( 330 (FileSP)std::make_shared<NativeFile>(fh, transfer_ownership)); 331 } 332 333 SBError SBDebugger::SetInputString(const char *data) { 334 LLDB_RECORD_METHOD(SBError, SBDebugger, SetInputString, (const char *), data); 335 SBError sb_error; 336 if (data == nullptr) { 337 sb_error.SetErrorString("String data is null"); 338 return sb_error; 339 } 340 341 size_t size = strlen(data); 342 if (size == 0) { 343 sb_error.SetErrorString("String data is empty"); 344 return sb_error; 345 } 346 347 if (!m_opaque_sp) { 348 sb_error.SetErrorString("invalid debugger"); 349 return sb_error; 350 } 351 352 sb_error.SetError(m_opaque_sp->SetInputString(data)); 353 return sb_error; 354 } 355 356 // Shouldn't really be settable after initialization as this could cause lots 357 // of problems; don't want users trying to switch modes in the middle of a 358 // debugging session. 359 SBError SBDebugger::SetInputFile(SBFile file) { 360 LLDB_RECORD_METHOD(SBError, SBDebugger, SetInputFile, (SBFile), file); 361 362 SBError error; 363 if (!m_opaque_sp) { 364 error.ref().SetErrorString("invalid debugger"); 365 return error; 366 } 367 error.SetError(m_opaque_sp->SetInputFile(file.m_opaque_sp)); 368 return error; 369 } 370 371 SBError SBDebugger::SetInputFile(FileSP file_sp) { 372 LLDB_RECORD_METHOD(SBError, SBDebugger, SetInputFile, (FileSP), file_sp); 373 return SetInputFile(SBFile(file_sp)); 374 } 375 376 SBError SBDebugger::SetOutputFile(FileSP file_sp) { 377 LLDB_RECORD_METHOD(SBError, SBDebugger, SetOutputFile, (FileSP), file_sp); 378 return SetOutputFile(SBFile(file_sp)); 379 } 380 381 void SBDebugger::SetOutputFileHandle(FILE *fh, bool transfer_ownership) { 382 LLDB_RECORD_METHOD(void, SBDebugger, SetOutputFileHandle, (FILE *, bool), fh, 383 transfer_ownership); 384 SetOutputFile((FileSP)std::make_shared<NativeFile>(fh, transfer_ownership)); 385 } 386 387 SBError SBDebugger::SetOutputFile(SBFile file) { 388 LLDB_RECORD_METHOD(SBError, SBDebugger, SetOutputFile, (SBFile file), file); 389 SBError error; 390 if (!m_opaque_sp) { 391 error.ref().SetErrorString("invalid debugger"); 392 return error; 393 } 394 if (!file) { 395 error.ref().SetErrorString("invalid file"); 396 return error; 397 } 398 m_opaque_sp->SetOutputFile(file.m_opaque_sp); 399 return error; 400 } 401 402 void SBDebugger::SetErrorFileHandle(FILE *fh, bool transfer_ownership) { 403 LLDB_RECORD_METHOD(void, SBDebugger, SetErrorFileHandle, (FILE *, bool), fh, 404 transfer_ownership); 405 SetErrorFile((FileSP)std::make_shared<NativeFile>(fh, transfer_ownership)); 406 } 407 408 SBError SBDebugger::SetErrorFile(FileSP file_sp) { 409 LLDB_RECORD_METHOD(SBError, SBDebugger, SetErrorFile, (FileSP), file_sp); 410 return SetErrorFile(SBFile(file_sp)); 411 } 412 413 SBError SBDebugger::SetErrorFile(SBFile file) { 414 LLDB_RECORD_METHOD(SBError, SBDebugger, SetErrorFile, (SBFile file), file); 415 SBError error; 416 if (!m_opaque_sp) { 417 error.ref().SetErrorString("invalid debugger"); 418 return error; 419 } 420 if (!file) { 421 error.ref().SetErrorString("invalid file"); 422 return error; 423 } 424 m_opaque_sp->SetErrorFile(file.m_opaque_sp); 425 return error; 426 } 427 428 FILE *SBDebugger::GetInputFileHandle() { 429 LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetInputFileHandle); 430 if (m_opaque_sp) { 431 File &file_sp = m_opaque_sp->GetInputFile(); 432 return file_sp.GetStream(); 433 } 434 return nullptr; 435 } 436 437 SBFile SBDebugger::GetInputFile() { 438 LLDB_RECORD_METHOD_NO_ARGS(SBFile, SBDebugger, GetInputFile); 439 if (m_opaque_sp) { 440 return SBFile(m_opaque_sp->GetInputFileSP()); 441 } 442 return SBFile(); 443 } 444 445 FILE *SBDebugger::GetOutputFileHandle() { 446 LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetOutputFileHandle); 447 if (m_opaque_sp) { 448 StreamFile &stream_file = m_opaque_sp->GetOutputStream(); 449 return stream_file.GetFile().GetStream(); 450 } 451 return nullptr; 452 } 453 454 SBFile SBDebugger::GetOutputFile() { 455 LLDB_RECORD_METHOD_NO_ARGS(SBFile, SBDebugger, GetOutputFile); 456 if (m_opaque_sp) { 457 SBFile file(m_opaque_sp->GetOutputStream().GetFileSP()); 458 return file; 459 } 460 return SBFile(); 461 } 462 463 FILE *SBDebugger::GetErrorFileHandle() { 464 LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetErrorFileHandle); 465 466 if (m_opaque_sp) { 467 StreamFile &stream_file = m_opaque_sp->GetErrorStream(); 468 return stream_file.GetFile().GetStream(); 469 } 470 return nullptr; 471 } 472 473 SBFile SBDebugger::GetErrorFile() { 474 LLDB_RECORD_METHOD_NO_ARGS(SBFile, SBDebugger, GetErrorFile); 475 SBFile file; 476 if (m_opaque_sp) { 477 SBFile file(m_opaque_sp->GetErrorStream().GetFileSP()); 478 return file; 479 } 480 return SBFile(); 481 } 482 483 void SBDebugger::SaveInputTerminalState() { 484 LLDB_RECORD_DUMMY_NO_ARGS(void, SBDebugger, SaveInputTerminalState); 485 486 if (m_opaque_sp) 487 m_opaque_sp->SaveInputTerminalState(); 488 } 489 490 void SBDebugger::RestoreInputTerminalState() { 491 LLDB_RECORD_DUMMY_NO_ARGS(void, SBDebugger, RestoreInputTerminalState); 492 493 if (m_opaque_sp) 494 m_opaque_sp->RestoreInputTerminalState(); 495 } 496 SBCommandInterpreter SBDebugger::GetCommandInterpreter() { 497 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBCommandInterpreter, SBDebugger, 498 GetCommandInterpreter); 499 500 SBCommandInterpreter sb_interpreter; 501 if (m_opaque_sp) 502 sb_interpreter.reset(&m_opaque_sp->GetCommandInterpreter()); 503 504 return sb_interpreter; 505 } 506 507 void SBDebugger::HandleCommand(const char *command) { 508 LLDB_RECORD_METHOD(void, SBDebugger, HandleCommand, (const char *), command); 509 510 if (m_opaque_sp) { 511 TargetSP target_sp(m_opaque_sp->GetSelectedTarget()); 512 std::unique_lock<std::recursive_mutex> lock; 513 if (target_sp) 514 lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); 515 516 SBCommandInterpreter sb_interpreter(GetCommandInterpreter()); 517 SBCommandReturnObject result; 518 519 sb_interpreter.HandleCommand(command, result, false); 520 521 result.PutError(m_opaque_sp->GetErrorStream().GetFileSP()); 522 result.PutOutput(m_opaque_sp->GetOutputStream().GetFileSP()); 523 524 if (!m_opaque_sp->GetAsyncExecution()) { 525 SBProcess process(GetCommandInterpreter().GetProcess()); 526 ProcessSP process_sp(process.GetSP()); 527 if (process_sp) { 528 EventSP event_sp; 529 ListenerSP lldb_listener_sp = m_opaque_sp->GetListener(); 530 while (lldb_listener_sp->GetEventForBroadcaster( 531 process_sp.get(), event_sp, std::chrono::seconds(0))) { 532 SBEvent event(event_sp); 533 HandleProcessEvent(process, event, GetOutputFile(), GetErrorFile()); 534 } 535 } 536 } 537 } 538 } 539 540 SBListener SBDebugger::GetListener() { 541 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBListener, SBDebugger, GetListener); 542 543 SBListener sb_listener; 544 if (m_opaque_sp) 545 sb_listener.reset(m_opaque_sp->GetListener()); 546 547 return sb_listener; 548 } 549 550 void SBDebugger::HandleProcessEvent(const SBProcess &process, 551 const SBEvent &event, SBFile out, 552 SBFile err) { 553 LLDB_RECORD_METHOD( 554 void, SBDebugger, HandleProcessEvent, 555 (const lldb::SBProcess &, const lldb::SBEvent &, SBFile, SBFile), process, 556 event, out, err); 557 558 return HandleProcessEvent(process, event, out.m_opaque_sp, err.m_opaque_sp); 559 } 560 561 void SBDebugger::HandleProcessEvent(const SBProcess &process, 562 const SBEvent &event, FILE *out, 563 FILE *err) { 564 LLDB_RECORD_METHOD( 565 void, SBDebugger, HandleProcessEvent, 566 (const lldb::SBProcess &, const lldb::SBEvent &, FILE *, FILE *), process, 567 event, out, err); 568 569 FileSP outfile = std::make_shared<NativeFile>(out, false); 570 FileSP errfile = std::make_shared<NativeFile>(err, false); 571 return HandleProcessEvent(process, event, outfile, errfile); 572 } 573 574 void SBDebugger::HandleProcessEvent(const SBProcess &process, 575 const SBEvent &event, FileSP out_sp, 576 FileSP err_sp) { 577 578 LLDB_RECORD_METHOD( 579 void, SBDebugger, HandleProcessEvent, 580 (const lldb::SBProcess &, const lldb::SBEvent &, FileSP, FileSP), process, 581 event, out_sp, err_sp); 582 583 if (!process.IsValid()) 584 return; 585 586 TargetSP target_sp(process.GetTarget().GetSP()); 587 if (!target_sp) 588 return; 589 590 const uint32_t event_type = event.GetType(); 591 char stdio_buffer[1024]; 592 size_t len; 593 594 std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex()); 595 596 if (event_type & 597 (Process::eBroadcastBitSTDOUT | Process::eBroadcastBitStateChanged)) { 598 // Drain stdout when we stop just in case we have any bytes 599 while ((len = process.GetSTDOUT(stdio_buffer, sizeof(stdio_buffer))) > 0) 600 if (out_sp) 601 out_sp->Write(stdio_buffer, len); 602 } 603 604 if (event_type & 605 (Process::eBroadcastBitSTDERR | Process::eBroadcastBitStateChanged)) { 606 // Drain stderr when we stop just in case we have any bytes 607 while ((len = process.GetSTDERR(stdio_buffer, sizeof(stdio_buffer))) > 0) 608 if (err_sp) 609 err_sp->Write(stdio_buffer, len); 610 } 611 612 if (event_type & Process::eBroadcastBitStateChanged) { 613 StateType event_state = SBProcess::GetStateFromEvent(event); 614 615 if (event_state == eStateInvalid) 616 return; 617 618 bool is_stopped = StateIsStoppedState(event_state); 619 if (!is_stopped) 620 process.ReportEventState(event, out_sp); 621 } 622 } 623 624 SBSourceManager SBDebugger::GetSourceManager() { 625 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBSourceManager, SBDebugger, 626 GetSourceManager); 627 628 SBSourceManager sb_source_manager(*this); 629 return sb_source_manager; 630 } 631 632 bool SBDebugger::GetDefaultArchitecture(char *arch_name, size_t arch_name_len) { 633 LLDB_RECORD_CHAR_PTR_STATIC_METHOD(bool, SBDebugger, GetDefaultArchitecture, 634 (char *, size_t), arch_name, "", 635 arch_name_len); 636 637 if (arch_name && arch_name_len) { 638 ArchSpec default_arch = Target::GetDefaultArchitecture(); 639 640 if (default_arch.IsValid()) { 641 const std::string &triple_str = default_arch.GetTriple().str(); 642 if (!triple_str.empty()) 643 ::snprintf(arch_name, arch_name_len, "%s", triple_str.c_str()); 644 else 645 ::snprintf(arch_name, arch_name_len, "%s", 646 default_arch.GetArchitectureName()); 647 return true; 648 } 649 } 650 if (arch_name && arch_name_len) 651 arch_name[0] = '\0'; 652 return false; 653 } 654 655 bool SBDebugger::SetDefaultArchitecture(const char *arch_name) { 656 LLDB_RECORD_STATIC_METHOD(bool, SBDebugger, SetDefaultArchitecture, 657 (const char *), arch_name); 658 659 if (arch_name) { 660 ArchSpec arch(arch_name); 661 if (arch.IsValid()) { 662 Target::SetDefaultArchitecture(arch); 663 return true; 664 } 665 } 666 return false; 667 } 668 669 ScriptLanguage 670 SBDebugger::GetScriptingLanguage(const char *script_language_name) { 671 LLDB_RECORD_METHOD(lldb::ScriptLanguage, SBDebugger, GetScriptingLanguage, 672 (const char *), script_language_name); 673 674 if (!script_language_name) 675 return eScriptLanguageDefault; 676 return OptionArgParser::ToScriptLanguage( 677 llvm::StringRef(script_language_name), eScriptLanguageDefault, nullptr); 678 } 679 680 SBStructuredData 681 SBDebugger::GetScriptInterpreterInfo(lldb::ScriptLanguage language) { 682 LLDB_RECORD_METHOD(SBStructuredData, SBDebugger, GetScriptInterpreterInfo, 683 (lldb::ScriptLanguage), language); 684 SBStructuredData data; 685 if (m_opaque_sp) { 686 lldb_private::ScriptInterpreter *interp = 687 m_opaque_sp->GetScriptInterpreter(language); 688 if (interp) { 689 data.m_impl_up->SetObjectSP(interp->GetInterpreterInfo()); 690 } 691 } 692 return data; 693 } 694 695 const char *SBDebugger::GetVersionString() { 696 LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBDebugger, GetVersionString); 697 698 return lldb_private::GetVersion(); 699 } 700 701 const char *SBDebugger::StateAsCString(StateType state) { 702 LLDB_RECORD_STATIC_METHOD(const char *, SBDebugger, StateAsCString, 703 (lldb::StateType), state); 704 705 return lldb_private::StateAsCString(state); 706 } 707 708 static void AddBoolConfigEntry(StructuredData::Dictionary &dict, 709 llvm::StringRef name, bool value, 710 llvm::StringRef description) { 711 auto entry_up = std::make_unique<StructuredData::Dictionary>(); 712 entry_up->AddBooleanItem("value", value); 713 entry_up->AddStringItem("description", description); 714 dict.AddItem(name, std::move(entry_up)); 715 } 716 717 static void AddLLVMTargets(StructuredData::Dictionary &dict) { 718 auto array_up = std::make_unique<StructuredData::Array>(); 719 #define LLVM_TARGET(target) \ 720 array_up->AddItem(std::make_unique<StructuredData::String>(#target)); 721 #include "llvm/Config/Targets.def" 722 auto entry_up = std::make_unique<StructuredData::Dictionary>(); 723 entry_up->AddItem("value", std::move(array_up)); 724 entry_up->AddStringItem("description", "A list of configured LLVM targets."); 725 dict.AddItem("targets", std::move(entry_up)); 726 } 727 728 SBStructuredData SBDebugger::GetBuildConfiguration() { 729 LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBStructuredData, SBDebugger, 730 GetBuildConfiguration); 731 732 auto config_up = std::make_unique<StructuredData::Dictionary>(); 733 AddBoolConfigEntry( 734 *config_up, "xml", XMLDocument::XMLEnabled(), 735 "A boolean value that indicates if XML support is enabled in LLDB"); 736 AddBoolConfigEntry( 737 *config_up, "curses", LLDB_ENABLE_CURSES, 738 "A boolean value that indicates if curses support is enabled in LLDB"); 739 AddBoolConfigEntry( 740 *config_up, "editline", LLDB_ENABLE_LIBEDIT, 741 "A boolean value that indicates if editline support is enabled in LLDB"); 742 AddBoolConfigEntry( 743 *config_up, "lzma", LLDB_ENABLE_LZMA, 744 "A boolean value that indicates if lzma support is enabled in LLDB"); 745 AddBoolConfigEntry( 746 *config_up, "python", LLDB_ENABLE_PYTHON, 747 "A boolean value that indicates if python support is enabled in LLDB"); 748 AddBoolConfigEntry( 749 *config_up, "lua", LLDB_ENABLE_LUA, 750 "A boolean value that indicates if lua support is enabled in LLDB"); 751 AddBoolConfigEntry(*config_up, "fbsdvmcore", LLDB_ENABLE_FBSDVMCORE, 752 "A boolean value that indicates if fbsdvmcore support is " 753 "enabled in LLDB"); 754 AddLLVMTargets(*config_up); 755 756 SBStructuredData data; 757 data.m_impl_up->SetObjectSP(std::move(config_up)); 758 return data; 759 } 760 761 bool SBDebugger::StateIsRunningState(StateType state) { 762 LLDB_RECORD_STATIC_METHOD(bool, SBDebugger, StateIsRunningState, 763 (lldb::StateType), state); 764 765 const bool result = lldb_private::StateIsRunningState(state); 766 767 return result; 768 } 769 770 bool SBDebugger::StateIsStoppedState(StateType state) { 771 LLDB_RECORD_STATIC_METHOD(bool, SBDebugger, StateIsStoppedState, 772 (lldb::StateType), state); 773 774 const bool result = lldb_private::StateIsStoppedState(state, false); 775 776 return result; 777 } 778 779 lldb::SBTarget SBDebugger::CreateTarget(const char *filename, 780 const char *target_triple, 781 const char *platform_name, 782 bool add_dependent_modules, 783 lldb::SBError &sb_error) { 784 LLDB_RECORD_METHOD( 785 lldb::SBTarget, SBDebugger, CreateTarget, 786 (const char *, const char *, const char *, bool, lldb::SBError &), 787 filename, target_triple, platform_name, add_dependent_modules, sb_error); 788 789 SBTarget sb_target; 790 TargetSP target_sp; 791 if (m_opaque_sp) { 792 sb_error.Clear(); 793 OptionGroupPlatform platform_options(false); 794 platform_options.SetPlatformName(platform_name); 795 796 sb_error.ref() = m_opaque_sp->GetTargetList().CreateTarget( 797 *m_opaque_sp, filename, target_triple, 798 add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, 799 &platform_options, target_sp); 800 801 if (sb_error.Success()) 802 sb_target.SetSP(target_sp); 803 } else { 804 sb_error.SetErrorString("invalid debugger"); 805 } 806 807 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 808 LLDB_LOGF(log, 809 "SBDebugger(%p)::CreateTarget (filename=\"%s\", triple=%s, " 810 "platform_name=%s, add_dependent_modules=%u, error=%s) => " 811 "SBTarget(%p)", 812 static_cast<void *>(m_opaque_sp.get()), filename, target_triple, 813 platform_name, add_dependent_modules, sb_error.GetCString(), 814 static_cast<void *>(target_sp.get())); 815 816 return sb_target; 817 } 818 819 SBTarget 820 SBDebugger::CreateTargetWithFileAndTargetTriple(const char *filename, 821 const char *target_triple) { 822 LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, 823 CreateTargetWithFileAndTargetTriple, 824 (const char *, const char *), filename, target_triple); 825 826 SBTarget sb_target; 827 TargetSP target_sp; 828 if (m_opaque_sp) { 829 const bool add_dependent_modules = true; 830 Status error(m_opaque_sp->GetTargetList().CreateTarget( 831 *m_opaque_sp, filename, target_triple, 832 add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr, 833 target_sp)); 834 sb_target.SetSP(target_sp); 835 } 836 837 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 838 LLDB_LOGF(log, 839 "SBDebugger(%p)::CreateTargetWithFileAndTargetTriple " 840 "(filename=\"%s\", triple=%s) => SBTarget(%p)", 841 static_cast<void *>(m_opaque_sp.get()), filename, target_triple, 842 static_cast<void *>(target_sp.get())); 843 844 return sb_target; 845 } 846 847 SBTarget SBDebugger::CreateTargetWithFileAndArch(const char *filename, 848 const char *arch_cstr) { 849 LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, CreateTargetWithFileAndArch, 850 (const char *, const char *), filename, arch_cstr); 851 852 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 853 854 SBTarget sb_target; 855 TargetSP target_sp; 856 if (m_opaque_sp) { 857 Status error; 858 if (arch_cstr == nullptr) { 859 // The version of CreateTarget that takes an ArchSpec won't accept an 860 // empty ArchSpec, so when the arch hasn't been specified, we need to 861 // call the target triple version. 862 error = m_opaque_sp->GetTargetList().CreateTarget(*m_opaque_sp, filename, 863 arch_cstr, eLoadDependentsYes, nullptr, target_sp); 864 } else { 865 PlatformSP platform_sp = m_opaque_sp->GetPlatformList() 866 .GetSelectedPlatform(); 867 ArchSpec arch = Platform::GetAugmentedArchSpec(platform_sp.get(), 868 arch_cstr); 869 if (arch.IsValid()) 870 error = m_opaque_sp->GetTargetList().CreateTarget(*m_opaque_sp, filename, 871 arch, eLoadDependentsYes, platform_sp, target_sp); 872 else 873 error.SetErrorStringWithFormat("invalid arch_cstr: %s", arch_cstr); 874 } 875 if (error.Success()) 876 sb_target.SetSP(target_sp); 877 } 878 879 LLDB_LOGF(log, 880 "SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", " 881 "arch=%s) => SBTarget(%p)", 882 static_cast<void *>(m_opaque_sp.get()), 883 filename ? filename : "<unspecified>", 884 arch_cstr ? arch_cstr : "<unspecified>", 885 static_cast<void *>(target_sp.get())); 886 887 return sb_target; 888 } 889 890 SBTarget SBDebugger::CreateTarget(const char *filename) { 891 LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, CreateTarget, (const char *), 892 filename); 893 894 SBTarget sb_target; 895 TargetSP target_sp; 896 if (m_opaque_sp) { 897 Status error; 898 const bool add_dependent_modules = true; 899 error = m_opaque_sp->GetTargetList().CreateTarget( 900 *m_opaque_sp, filename, "", 901 add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr, 902 target_sp); 903 904 if (error.Success()) 905 sb_target.SetSP(target_sp); 906 } 907 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 908 LLDB_LOGF(log, 909 "SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)", 910 static_cast<void *>(m_opaque_sp.get()), filename, 911 static_cast<void *>(target_sp.get())); 912 return sb_target; 913 } 914 915 SBTarget SBDebugger::GetDummyTarget() { 916 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBTarget, SBDebugger, GetDummyTarget); 917 918 SBTarget sb_target; 919 if (m_opaque_sp) { 920 sb_target.SetSP(m_opaque_sp->GetDummyTarget().shared_from_this()); 921 } 922 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 923 LLDB_LOGF(log, "SBDebugger(%p)::GetDummyTarget() => SBTarget(%p)", 924 static_cast<void *>(m_opaque_sp.get()), 925 static_cast<void *>(sb_target.GetSP().get())); 926 return sb_target; 927 } 928 929 bool SBDebugger::DeleteTarget(lldb::SBTarget &target) { 930 LLDB_RECORD_METHOD(bool, SBDebugger, DeleteTarget, (lldb::SBTarget &), 931 target); 932 933 bool result = false; 934 if (m_opaque_sp) { 935 TargetSP target_sp(target.GetSP()); 936 if (target_sp) { 937 // No need to lock, the target list is thread safe 938 result = m_opaque_sp->GetTargetList().DeleteTarget(target_sp); 939 target_sp->Destroy(); 940 target.Clear(); 941 } 942 } 943 944 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 945 LLDB_LOGF(log, "SBDebugger(%p)::DeleteTarget (SBTarget(%p)) => %i", 946 static_cast<void *>(m_opaque_sp.get()), 947 static_cast<void *>(target.m_opaque_sp.get()), result); 948 949 return result; 950 } 951 952 SBTarget SBDebugger::GetTargetAtIndex(uint32_t idx) { 953 LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, GetTargetAtIndex, (uint32_t), 954 idx); 955 956 SBTarget sb_target; 957 if (m_opaque_sp) { 958 // No need to lock, the target list is thread safe 959 sb_target.SetSP(m_opaque_sp->GetTargetList().GetTargetAtIndex(idx)); 960 } 961 return sb_target; 962 } 963 964 uint32_t SBDebugger::GetIndexOfTarget(lldb::SBTarget target) { 965 LLDB_RECORD_METHOD(uint32_t, SBDebugger, GetIndexOfTarget, (lldb::SBTarget), 966 target); 967 968 lldb::TargetSP target_sp = target.GetSP(); 969 if (!target_sp) 970 return UINT32_MAX; 971 972 if (!m_opaque_sp) 973 return UINT32_MAX; 974 975 return m_opaque_sp->GetTargetList().GetIndexOfTarget(target.GetSP()); 976 } 977 978 SBTarget SBDebugger::FindTargetWithProcessID(lldb::pid_t pid) { 979 LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, FindTargetWithProcessID, 980 (lldb::pid_t), pid); 981 982 SBTarget sb_target; 983 if (m_opaque_sp) { 984 // No need to lock, the target list is thread safe 985 sb_target.SetSP(m_opaque_sp->GetTargetList().FindTargetWithProcessID(pid)); 986 } 987 return sb_target; 988 } 989 990 SBTarget SBDebugger::FindTargetWithFileAndArch(const char *filename, 991 const char *arch_name) { 992 LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, FindTargetWithFileAndArch, 993 (const char *, const char *), filename, arch_name); 994 995 SBTarget sb_target; 996 if (m_opaque_sp && filename && filename[0]) { 997 // No need to lock, the target list is thread safe 998 ArchSpec arch = Platform::GetAugmentedArchSpec( 999 m_opaque_sp->GetPlatformList().GetSelectedPlatform().get(), arch_name); 1000 TargetSP target_sp( 1001 m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture( 1002 FileSpec(filename), arch_name ? &arch : nullptr)); 1003 sb_target.SetSP(target_sp); 1004 } 1005 return sb_target; 1006 } 1007 1008 SBTarget SBDebugger::FindTargetWithLLDBProcess(const ProcessSP &process_sp) { 1009 SBTarget sb_target; 1010 if (m_opaque_sp) { 1011 // No need to lock, the target list is thread safe 1012 sb_target.SetSP( 1013 m_opaque_sp->GetTargetList().FindTargetWithProcess(process_sp.get())); 1014 } 1015 return sb_target; 1016 } 1017 1018 uint32_t SBDebugger::GetNumTargets() { 1019 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBDebugger, GetNumTargets); 1020 1021 if (m_opaque_sp) { 1022 // No need to lock, the target list is thread safe 1023 return m_opaque_sp->GetTargetList().GetNumTargets(); 1024 } 1025 return 0; 1026 } 1027 1028 SBTarget SBDebugger::GetSelectedTarget() { 1029 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBTarget, SBDebugger, GetSelectedTarget); 1030 1031 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1032 1033 SBTarget sb_target; 1034 TargetSP target_sp; 1035 if (m_opaque_sp) { 1036 // No need to lock, the target list is thread safe 1037 target_sp = m_opaque_sp->GetTargetList().GetSelectedTarget(); 1038 sb_target.SetSP(target_sp); 1039 } 1040 1041 if (log) { 1042 SBStream sstr; 1043 sb_target.GetDescription(sstr, eDescriptionLevelBrief); 1044 LLDB_LOGF(log, "SBDebugger(%p)::GetSelectedTarget () => SBTarget(%p): %s", 1045 static_cast<void *>(m_opaque_sp.get()), 1046 static_cast<void *>(target_sp.get()), sstr.GetData()); 1047 } 1048 1049 return sb_target; 1050 } 1051 1052 void SBDebugger::SetSelectedTarget(SBTarget &sb_target) { 1053 LLDB_RECORD_METHOD(void, SBDebugger, SetSelectedTarget, (lldb::SBTarget &), 1054 sb_target); 1055 1056 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1057 1058 TargetSP target_sp(sb_target.GetSP()); 1059 if (m_opaque_sp) { 1060 m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp); 1061 } 1062 if (log) { 1063 SBStream sstr; 1064 sb_target.GetDescription(sstr, eDescriptionLevelBrief); 1065 LLDB_LOGF(log, "SBDebugger(%p)::SetSelectedTarget () => SBTarget(%p): %s", 1066 static_cast<void *>(m_opaque_sp.get()), 1067 static_cast<void *>(target_sp.get()), sstr.GetData()); 1068 } 1069 } 1070 1071 SBPlatform SBDebugger::GetSelectedPlatform() { 1072 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBPlatform, SBDebugger, GetSelectedPlatform); 1073 1074 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1075 1076 SBPlatform sb_platform; 1077 DebuggerSP debugger_sp(m_opaque_sp); 1078 if (debugger_sp) { 1079 sb_platform.SetSP(debugger_sp->GetPlatformList().GetSelectedPlatform()); 1080 } 1081 LLDB_LOGF(log, "SBDebugger(%p)::GetSelectedPlatform () => SBPlatform(%p): %s", 1082 static_cast<void *>(m_opaque_sp.get()), 1083 static_cast<void *>(sb_platform.GetSP().get()), 1084 sb_platform.GetName()); 1085 return sb_platform; 1086 } 1087 1088 void SBDebugger::SetSelectedPlatform(SBPlatform &sb_platform) { 1089 LLDB_RECORD_METHOD(void, SBDebugger, SetSelectedPlatform, 1090 (lldb::SBPlatform &), sb_platform); 1091 1092 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1093 1094 DebuggerSP debugger_sp(m_opaque_sp); 1095 if (debugger_sp) { 1096 debugger_sp->GetPlatformList().SetSelectedPlatform(sb_platform.GetSP()); 1097 } 1098 1099 LLDB_LOGF(log, "SBDebugger(%p)::SetSelectedPlatform (SBPlatform(%p) %s)", 1100 static_cast<void *>(m_opaque_sp.get()), 1101 static_cast<void *>(sb_platform.GetSP().get()), 1102 sb_platform.GetName()); 1103 } 1104 1105 uint32_t SBDebugger::GetNumPlatforms() { 1106 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBDebugger, GetNumPlatforms); 1107 1108 if (m_opaque_sp) { 1109 // No need to lock, the platform list is thread safe 1110 return m_opaque_sp->GetPlatformList().GetSize(); 1111 } 1112 return 0; 1113 } 1114 1115 SBPlatform SBDebugger::GetPlatformAtIndex(uint32_t idx) { 1116 LLDB_RECORD_METHOD(lldb::SBPlatform, SBDebugger, GetPlatformAtIndex, 1117 (uint32_t), idx); 1118 1119 SBPlatform sb_platform; 1120 if (m_opaque_sp) { 1121 // No need to lock, the platform list is thread safe 1122 sb_platform.SetSP(m_opaque_sp->GetPlatformList().GetAtIndex(idx)); 1123 } 1124 return sb_platform; 1125 } 1126 1127 uint32_t SBDebugger::GetNumAvailablePlatforms() { 1128 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBDebugger, GetNumAvailablePlatforms); 1129 1130 uint32_t idx = 0; 1131 while (true) { 1132 if (PluginManager::GetPlatformPluginNameAtIndex(idx).empty()) { 1133 break; 1134 } 1135 ++idx; 1136 } 1137 // +1 for the host platform, which should always appear first in the list. 1138 return idx + 1; 1139 } 1140 1141 SBStructuredData SBDebugger::GetAvailablePlatformInfoAtIndex(uint32_t idx) { 1142 LLDB_RECORD_METHOD(lldb::SBStructuredData, SBDebugger, 1143 GetAvailablePlatformInfoAtIndex, (uint32_t), idx); 1144 1145 SBStructuredData data; 1146 auto platform_dict = std::make_unique<StructuredData::Dictionary>(); 1147 llvm::StringRef name_str("name"), desc_str("description"); 1148 1149 if (idx == 0) { 1150 PlatformSP host_platform_sp(Platform::GetHostPlatform()); 1151 platform_dict->AddStringItem(name_str, host_platform_sp->GetPluginName()); 1152 platform_dict->AddStringItem( 1153 desc_str, llvm::StringRef(host_platform_sp->GetDescription())); 1154 } else if (idx > 0) { 1155 llvm::StringRef plugin_name = 1156 PluginManager::GetPlatformPluginNameAtIndex(idx - 1); 1157 if (plugin_name.empty()) { 1158 return data; 1159 } 1160 platform_dict->AddStringItem(name_str, llvm::StringRef(plugin_name)); 1161 1162 llvm::StringRef plugin_desc = 1163 PluginManager::GetPlatformPluginDescriptionAtIndex(idx - 1); 1164 platform_dict->AddStringItem(desc_str, llvm::StringRef(plugin_desc)); 1165 } 1166 1167 data.m_impl_up->SetObjectSP( 1168 StructuredData::ObjectSP(platform_dict.release())); 1169 return data; 1170 } 1171 1172 void SBDebugger::DispatchInput(void *baton, const void *data, size_t data_len) { 1173 LLDB_RECORD_DUMMY(void, SBDebugger, DispatchInput, 1174 (void *, const void *, size_t), baton, data, data_len); 1175 1176 DispatchInput(data, data_len); 1177 } 1178 1179 void SBDebugger::DispatchInput(const void *data, size_t data_len) { 1180 LLDB_RECORD_DUMMY(void, SBDebugger, DispatchInput, (const void *, size_t), 1181 data, data_len); 1182 1183 // Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 1184 // 1185 // if (log) 1186 // LLDB_LOGF(log, "SBDebugger(%p)::DispatchInput (data=\"%.*s\", 1187 // size_t=%" PRIu64 ")", 1188 // m_opaque_sp.get(), 1189 // (int) data_len, 1190 // (const char *) data, 1191 // (uint64_t)data_len); 1192 // 1193 // if (m_opaque_sp) 1194 // m_opaque_sp->DispatchInput ((const char *) data, data_len); 1195 } 1196 1197 void SBDebugger::DispatchInputInterrupt() { 1198 LLDB_RECORD_DUMMY_NO_ARGS(void, SBDebugger, DispatchInputInterrupt); 1199 1200 if (m_opaque_sp) 1201 m_opaque_sp->DispatchInputInterrupt(); 1202 } 1203 1204 void SBDebugger::DispatchInputEndOfFile() { 1205 LLDB_RECORD_METHOD_NO_ARGS(void, SBDebugger, DispatchInputEndOfFile); 1206 1207 if (m_opaque_sp) 1208 m_opaque_sp->DispatchInputEndOfFile(); 1209 } 1210 1211 void SBDebugger::PushInputReader(SBInputReader &reader) { 1212 LLDB_RECORD_METHOD(void, SBDebugger, PushInputReader, (lldb::SBInputReader &), 1213 reader); 1214 } 1215 1216 void SBDebugger::RunCommandInterpreter(bool auto_handle_events, 1217 bool spawn_thread) { 1218 LLDB_RECORD_METHOD(void, SBDebugger, RunCommandInterpreter, (bool, bool), 1219 auto_handle_events, spawn_thread); 1220 1221 if (m_opaque_sp) { 1222 CommandInterpreterRunOptions options; 1223 options.SetAutoHandleEvents(auto_handle_events); 1224 options.SetSpawnThread(spawn_thread); 1225 m_opaque_sp->GetCommandInterpreter().RunCommandInterpreter(options); 1226 } 1227 } 1228 1229 void SBDebugger::RunCommandInterpreter(bool auto_handle_events, 1230 bool spawn_thread, 1231 SBCommandInterpreterRunOptions &options, 1232 int &num_errors, bool &quit_requested, 1233 bool &stopped_for_crash) 1234 1235 { 1236 LLDB_RECORD_METHOD(void, SBDebugger, RunCommandInterpreter, 1237 (bool, bool, lldb::SBCommandInterpreterRunOptions &, int &, 1238 bool &, bool &), 1239 auto_handle_events, spawn_thread, options, num_errors, 1240 quit_requested, stopped_for_crash); 1241 1242 if (m_opaque_sp) { 1243 options.SetAutoHandleEvents(auto_handle_events); 1244 options.SetSpawnThread(spawn_thread); 1245 CommandInterpreter &interp = m_opaque_sp->GetCommandInterpreter(); 1246 CommandInterpreterRunResult result = 1247 interp.RunCommandInterpreter(options.ref()); 1248 num_errors = result.GetNumErrors(); 1249 quit_requested = 1250 result.IsResult(lldb::eCommandInterpreterResultQuitRequested); 1251 stopped_for_crash = 1252 result.IsResult(lldb::eCommandInterpreterResultInferiorCrash); 1253 } 1254 } 1255 1256 SBCommandInterpreterRunResult SBDebugger::RunCommandInterpreter( 1257 const SBCommandInterpreterRunOptions &options) { 1258 LLDB_RECORD_METHOD(lldb::SBCommandInterpreterRunResult, SBDebugger, 1259 RunCommandInterpreter, 1260 (const lldb::SBCommandInterpreterRunOptions &), options); 1261 1262 if (!m_opaque_sp) 1263 return SBCommandInterpreterRunResult(); 1264 1265 CommandInterpreter &interp = m_opaque_sp->GetCommandInterpreter(); 1266 CommandInterpreterRunResult result = 1267 interp.RunCommandInterpreter(options.ref()); 1268 1269 return SBCommandInterpreterRunResult(result); 1270 } 1271 1272 SBError SBDebugger::RunREPL(lldb::LanguageType language, 1273 const char *repl_options) { 1274 LLDB_RECORD_METHOD(lldb::SBError, SBDebugger, RunREPL, 1275 (lldb::LanguageType, const char *), language, 1276 repl_options); 1277 1278 SBError error; 1279 if (m_opaque_sp) 1280 error.ref() = m_opaque_sp->RunREPL(language, repl_options); 1281 else 1282 error.SetErrorString("invalid debugger"); 1283 return error; 1284 } 1285 1286 void SBDebugger::reset(const DebuggerSP &debugger_sp) { 1287 m_opaque_sp = debugger_sp; 1288 } 1289 1290 Debugger *SBDebugger::get() const { return m_opaque_sp.get(); } 1291 1292 Debugger &SBDebugger::ref() const { 1293 assert(m_opaque_sp.get()); 1294 return *m_opaque_sp; 1295 } 1296 1297 const lldb::DebuggerSP &SBDebugger::get_sp() const { return m_opaque_sp; } 1298 1299 SBDebugger SBDebugger::FindDebuggerWithID(int id) { 1300 LLDB_RECORD_STATIC_METHOD(lldb::SBDebugger, SBDebugger, FindDebuggerWithID, 1301 (int), id); 1302 1303 // No need to lock, the debugger list is thread safe 1304 SBDebugger sb_debugger; 1305 DebuggerSP debugger_sp = Debugger::FindDebuggerWithID(id); 1306 if (debugger_sp) 1307 sb_debugger.reset(debugger_sp); 1308 return sb_debugger; 1309 } 1310 1311 const char *SBDebugger::GetInstanceName() { 1312 LLDB_RECORD_METHOD_NO_ARGS(const char *, SBDebugger, GetInstanceName); 1313 1314 return (m_opaque_sp ? m_opaque_sp->GetInstanceName().AsCString() : nullptr); 1315 } 1316 1317 SBError SBDebugger::SetInternalVariable(const char *var_name, const char *value, 1318 const char *debugger_instance_name) { 1319 LLDB_RECORD_STATIC_METHOD(lldb::SBError, SBDebugger, SetInternalVariable, 1320 (const char *, const char *, const char *), 1321 var_name, value, debugger_instance_name); 1322 1323 SBError sb_error; 1324 DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName( 1325 ConstString(debugger_instance_name))); 1326 Status error; 1327 if (debugger_sp) { 1328 ExecutionContext exe_ctx( 1329 debugger_sp->GetCommandInterpreter().GetExecutionContext()); 1330 error = debugger_sp->SetPropertyValue(&exe_ctx, eVarSetOperationAssign, 1331 var_name, value); 1332 } else { 1333 error.SetErrorStringWithFormat("invalid debugger instance name '%s'", 1334 debugger_instance_name); 1335 } 1336 if (error.Fail()) 1337 sb_error.SetError(error); 1338 return sb_error; 1339 } 1340 1341 SBStringList 1342 SBDebugger::GetInternalVariableValue(const char *var_name, 1343 const char *debugger_instance_name) { 1344 LLDB_RECORD_STATIC_METHOD( 1345 lldb::SBStringList, SBDebugger, GetInternalVariableValue, 1346 (const char *, const char *), var_name, debugger_instance_name); 1347 1348 DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName( 1349 ConstString(debugger_instance_name))); 1350 Status error; 1351 if (debugger_sp) { 1352 ExecutionContext exe_ctx( 1353 debugger_sp->GetCommandInterpreter().GetExecutionContext()); 1354 lldb::OptionValueSP value_sp( 1355 debugger_sp->GetPropertyValue(&exe_ctx, var_name, false, error)); 1356 if (value_sp) { 1357 StreamString value_strm; 1358 value_sp->DumpValue(&exe_ctx, value_strm, OptionValue::eDumpOptionValue); 1359 const std::string &value_str = std::string(value_strm.GetString()); 1360 if (!value_str.empty()) { 1361 StringList string_list; 1362 string_list.SplitIntoLines(value_str); 1363 return SBStringList(&string_list); 1364 } 1365 } 1366 } 1367 return SBStringList(); 1368 } 1369 1370 uint32_t SBDebugger::GetTerminalWidth() const { 1371 LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBDebugger, GetTerminalWidth); 1372 1373 return (m_opaque_sp ? m_opaque_sp->GetTerminalWidth() : 0); 1374 } 1375 1376 void SBDebugger::SetTerminalWidth(uint32_t term_width) { 1377 LLDB_RECORD_DUMMY(void, SBDebugger, SetTerminalWidth, (uint32_t), term_width); 1378 1379 if (m_opaque_sp) 1380 m_opaque_sp->SetTerminalWidth(term_width); 1381 } 1382 1383 const char *SBDebugger::GetPrompt() const { 1384 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBDebugger, GetPrompt); 1385 1386 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1387 1388 LLDB_LOGF(log, "SBDebugger(%p)::GetPrompt () => \"%s\"", 1389 static_cast<void *>(m_opaque_sp.get()), 1390 (m_opaque_sp ? m_opaque_sp->GetPrompt().str().c_str() : "")); 1391 1392 return (m_opaque_sp ? ConstString(m_opaque_sp->GetPrompt()).GetCString() 1393 : nullptr); 1394 } 1395 1396 void SBDebugger::SetPrompt(const char *prompt) { 1397 LLDB_RECORD_METHOD(void, SBDebugger, SetPrompt, (const char *), prompt); 1398 1399 if (m_opaque_sp) 1400 m_opaque_sp->SetPrompt(llvm::StringRef(prompt)); 1401 } 1402 1403 const char *SBDebugger::GetReproducerPath() const { 1404 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBDebugger, GetReproducerPath); 1405 1406 return (m_opaque_sp 1407 ? ConstString(m_opaque_sp->GetReproducerPath()).GetCString() 1408 : nullptr); 1409 } 1410 1411 ScriptLanguage SBDebugger::GetScriptLanguage() const { 1412 LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::ScriptLanguage, SBDebugger, 1413 GetScriptLanguage); 1414 1415 return (m_opaque_sp ? m_opaque_sp->GetScriptLanguage() : eScriptLanguageNone); 1416 } 1417 1418 void SBDebugger::SetScriptLanguage(ScriptLanguage script_lang) { 1419 LLDB_RECORD_METHOD(void, SBDebugger, SetScriptLanguage, 1420 (lldb::ScriptLanguage), script_lang); 1421 1422 if (m_opaque_sp) { 1423 m_opaque_sp->SetScriptLanguage(script_lang); 1424 } 1425 } 1426 1427 LanguageType SBDebugger::GetREPLLanguage() const { 1428 LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::LanguageType, SBDebugger, 1429 GetREPLLanguage); 1430 1431 return (m_opaque_sp ? m_opaque_sp->GetREPLLanguage() : eLanguageTypeUnknown); 1432 } 1433 1434 void SBDebugger::SetREPLLanguage(LanguageType repl_lang) { 1435 LLDB_RECORD_METHOD(void, SBDebugger, SetREPLLanguage, (lldb::LanguageType), 1436 repl_lang); 1437 1438 if (m_opaque_sp) { 1439 m_opaque_sp->SetREPLLanguage(repl_lang); 1440 } 1441 } 1442 1443 bool SBDebugger::SetUseExternalEditor(bool value) { 1444 LLDB_RECORD_METHOD(bool, SBDebugger, SetUseExternalEditor, (bool), value); 1445 1446 return (m_opaque_sp ? m_opaque_sp->SetUseExternalEditor(value) : false); 1447 } 1448 1449 bool SBDebugger::GetUseExternalEditor() { 1450 LLDB_RECORD_METHOD_NO_ARGS(bool, SBDebugger, GetUseExternalEditor); 1451 1452 return (m_opaque_sp ? m_opaque_sp->GetUseExternalEditor() : false); 1453 } 1454 1455 bool SBDebugger::SetUseColor(bool value) { 1456 LLDB_RECORD_METHOD(bool, SBDebugger, SetUseColor, (bool), value); 1457 1458 return (m_opaque_sp ? m_opaque_sp->SetUseColor(value) : false); 1459 } 1460 1461 bool SBDebugger::GetUseColor() const { 1462 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDebugger, GetUseColor); 1463 1464 return (m_opaque_sp ? m_opaque_sp->GetUseColor() : false); 1465 } 1466 1467 bool SBDebugger::SetUseSourceCache(bool value) { 1468 LLDB_RECORD_METHOD(bool, SBDebugger, SetUseSourceCache, (bool), value); 1469 1470 return (m_opaque_sp ? m_opaque_sp->SetUseSourceCache(value) : false); 1471 } 1472 1473 bool SBDebugger::GetUseSourceCache() const { 1474 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDebugger, GetUseSourceCache); 1475 1476 return (m_opaque_sp ? m_opaque_sp->GetUseSourceCache() : false); 1477 } 1478 1479 bool SBDebugger::GetDescription(SBStream &description) { 1480 LLDB_RECORD_METHOD(bool, SBDebugger, GetDescription, (lldb::SBStream &), 1481 description); 1482 1483 Stream &strm = description.ref(); 1484 1485 if (m_opaque_sp) { 1486 const char *name = m_opaque_sp->GetInstanceName().AsCString(); 1487 user_id_t id = m_opaque_sp->GetID(); 1488 strm.Printf("Debugger (instance: \"%s\", id: %" PRIu64 ")", name, id); 1489 } else 1490 strm.PutCString("No value"); 1491 1492 return true; 1493 } 1494 1495 user_id_t SBDebugger::GetID() { 1496 LLDB_RECORD_METHOD_NO_ARGS(lldb::user_id_t, SBDebugger, GetID); 1497 1498 return (m_opaque_sp ? m_opaque_sp->GetID() : LLDB_INVALID_UID); 1499 } 1500 1501 SBError SBDebugger::SetCurrentPlatform(const char *platform_name_cstr) { 1502 LLDB_RECORD_METHOD(lldb::SBError, SBDebugger, SetCurrentPlatform, 1503 (const char *), platform_name_cstr); 1504 1505 SBError sb_error; 1506 if (m_opaque_sp) { 1507 if (platform_name_cstr && platform_name_cstr[0]) { 1508 ConstString platform_name(platform_name_cstr); 1509 PlatformSP platform_sp(Platform::Find(platform_name)); 1510 1511 if (platform_sp) { 1512 // Already have a platform with this name, just select it 1513 m_opaque_sp->GetPlatformList().SetSelectedPlatform(platform_sp); 1514 } else { 1515 // We don't have a platform by this name yet, create one 1516 platform_sp = Platform::Create(platform_name, sb_error.ref()); 1517 if (platform_sp) { 1518 // We created the platform, now append and select it 1519 bool make_selected = true; 1520 m_opaque_sp->GetPlatformList().Append(platform_sp, make_selected); 1521 } 1522 } 1523 } else { 1524 sb_error.ref().SetErrorString("invalid platform name"); 1525 } 1526 } else { 1527 sb_error.ref().SetErrorString("invalid debugger"); 1528 } 1529 return sb_error; 1530 } 1531 1532 bool SBDebugger::SetCurrentPlatformSDKRoot(const char *sysroot) { 1533 LLDB_RECORD_METHOD(bool, SBDebugger, SetCurrentPlatformSDKRoot, 1534 (const char *), sysroot); 1535 1536 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1537 if (m_opaque_sp) { 1538 PlatformSP platform_sp( 1539 m_opaque_sp->GetPlatformList().GetSelectedPlatform()); 1540 1541 if (platform_sp) { 1542 if (log && sysroot) 1543 LLDB_LOGF(log, "SBDebugger::SetCurrentPlatformSDKRoot (\"%s\")", 1544 sysroot); 1545 platform_sp->SetSDKRootDirectory(ConstString(sysroot)); 1546 return true; 1547 } 1548 } 1549 return false; 1550 } 1551 1552 bool SBDebugger::GetCloseInputOnEOF() const { 1553 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDebugger, GetCloseInputOnEOF); 1554 1555 return (m_opaque_sp ? m_opaque_sp->GetCloseInputOnEOF() : false); 1556 } 1557 1558 void SBDebugger::SetCloseInputOnEOF(bool b) { 1559 LLDB_RECORD_METHOD(void, SBDebugger, SetCloseInputOnEOF, (bool), b); 1560 1561 if (m_opaque_sp) 1562 m_opaque_sp->SetCloseInputOnEOF(b); 1563 } 1564 1565 SBTypeCategory SBDebugger::GetCategory(const char *category_name) { 1566 LLDB_RECORD_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategory, 1567 (const char *), category_name); 1568 1569 if (!category_name || *category_name == 0) 1570 return SBTypeCategory(); 1571 1572 TypeCategoryImplSP category_sp; 1573 1574 if (DataVisualization::Categories::GetCategory(ConstString(category_name), 1575 category_sp, false)) { 1576 return SBTypeCategory(category_sp); 1577 } else { 1578 return SBTypeCategory(); 1579 } 1580 } 1581 1582 SBTypeCategory SBDebugger::GetCategory(lldb::LanguageType lang_type) { 1583 LLDB_RECORD_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategory, 1584 (lldb::LanguageType), lang_type); 1585 1586 TypeCategoryImplSP category_sp; 1587 if (DataVisualization::Categories::GetCategory(lang_type, category_sp)) { 1588 return SBTypeCategory(category_sp); 1589 } else { 1590 return SBTypeCategory(); 1591 } 1592 } 1593 1594 SBTypeCategory SBDebugger::CreateCategory(const char *category_name) { 1595 LLDB_RECORD_METHOD(lldb::SBTypeCategory, SBDebugger, CreateCategory, 1596 (const char *), category_name); 1597 1598 if (!category_name || *category_name == 0) 1599 return SBTypeCategory(); 1600 1601 TypeCategoryImplSP category_sp; 1602 1603 if (DataVisualization::Categories::GetCategory(ConstString(category_name), 1604 category_sp, true)) { 1605 return SBTypeCategory(category_sp); 1606 } else { 1607 return SBTypeCategory(); 1608 } 1609 } 1610 1611 bool SBDebugger::DeleteCategory(const char *category_name) { 1612 LLDB_RECORD_METHOD(bool, SBDebugger, DeleteCategory, (const char *), 1613 category_name); 1614 1615 if (!category_name || *category_name == 0) 1616 return false; 1617 1618 return DataVisualization::Categories::Delete(ConstString(category_name)); 1619 } 1620 1621 uint32_t SBDebugger::GetNumCategories() { 1622 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBDebugger, GetNumCategories); 1623 1624 return DataVisualization::Categories::GetCount(); 1625 } 1626 1627 SBTypeCategory SBDebugger::GetCategoryAtIndex(uint32_t index) { 1628 LLDB_RECORD_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategoryAtIndex, 1629 (uint32_t), index); 1630 1631 return SBTypeCategory( 1632 DataVisualization::Categories::GetCategoryAtIndex(index)); 1633 } 1634 1635 SBTypeCategory SBDebugger::GetDefaultCategory() { 1636 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBTypeCategory, SBDebugger, 1637 GetDefaultCategory); 1638 1639 return GetCategory("default"); 1640 } 1641 1642 SBTypeFormat SBDebugger::GetFormatForType(SBTypeNameSpecifier type_name) { 1643 LLDB_RECORD_METHOD(lldb::SBTypeFormat, SBDebugger, GetFormatForType, 1644 (lldb::SBTypeNameSpecifier), type_name); 1645 1646 SBTypeCategory default_category_sb = GetDefaultCategory(); 1647 if (default_category_sb.GetEnabled()) 1648 return default_category_sb.GetFormatForType(type_name); 1649 return SBTypeFormat(); 1650 } 1651 1652 SBTypeSummary SBDebugger::GetSummaryForType(SBTypeNameSpecifier type_name) { 1653 LLDB_RECORD_METHOD(lldb::SBTypeSummary, SBDebugger, GetSummaryForType, 1654 (lldb::SBTypeNameSpecifier), type_name); 1655 1656 if (!type_name.IsValid()) 1657 return SBTypeSummary(); 1658 return SBTypeSummary(DataVisualization::GetSummaryForType(type_name.GetSP())); 1659 } 1660 1661 SBTypeFilter SBDebugger::GetFilterForType(SBTypeNameSpecifier type_name) { 1662 LLDB_RECORD_METHOD(lldb::SBTypeFilter, SBDebugger, GetFilterForType, 1663 (lldb::SBTypeNameSpecifier), type_name); 1664 1665 if (!type_name.IsValid()) 1666 return SBTypeFilter(); 1667 return SBTypeFilter(DataVisualization::GetFilterForType(type_name.GetSP())); 1668 } 1669 1670 SBTypeSynthetic SBDebugger::GetSyntheticForType(SBTypeNameSpecifier type_name) { 1671 LLDB_RECORD_METHOD(lldb::SBTypeSynthetic, SBDebugger, GetSyntheticForType, 1672 (lldb::SBTypeNameSpecifier), type_name); 1673 1674 if (!type_name.IsValid()) 1675 return SBTypeSynthetic(); 1676 return SBTypeSynthetic( 1677 DataVisualization::GetSyntheticForType(type_name.GetSP())); 1678 } 1679 1680 static llvm::ArrayRef<const char *> GetCategoryArray(const char **categories) { 1681 if (categories == nullptr) 1682 return {}; 1683 size_t len = 0; 1684 while (categories[len] != nullptr) 1685 ++len; 1686 return llvm::makeArrayRef(categories, len); 1687 } 1688 1689 bool SBDebugger::EnableLog(const char *channel, const char **categories) { 1690 LLDB_RECORD_METHOD(bool, SBDebugger, EnableLog, (const char *, const char **), 1691 channel, categories); 1692 1693 if (m_opaque_sp) { 1694 uint32_t log_options = 1695 LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 1696 std::string error; 1697 llvm::raw_string_ostream error_stream(error); 1698 return m_opaque_sp->EnableLog(channel, GetCategoryArray(categories), "", 1699 log_options, error_stream); 1700 } else 1701 return false; 1702 } 1703 1704 void SBDebugger::SetLoggingCallback(lldb::LogOutputCallback log_callback, 1705 void *baton) { 1706 LLDB_RECORD_DUMMY(void, SBDebugger, SetLoggingCallback, 1707 (lldb::LogOutputCallback, void *), log_callback, baton); 1708 1709 if (m_opaque_sp) { 1710 return m_opaque_sp->SetLoggingCallback(log_callback, baton); 1711 } 1712 } 1713