1 //===-- SBDebugger.cpp ------------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 11 #include "SystemInitializerFull.h" 12 13 #include "lldb/API/SBDebugger.h" 14 15 #include "lldb/lldb-private.h" 16 17 #include "lldb/API/SBBroadcaster.h" 18 #include "lldb/API/SBCommandInterpreter.h" 19 #include "lldb/API/SBCommandReturnObject.h" 20 #include "lldb/API/SBError.h" 21 #include "lldb/API/SBEvent.h" 22 #include "lldb/API/SBFrame.h" 23 #include "lldb/API/SBListener.h" 24 #include "lldb/API/SBProcess.h" 25 #include "lldb/API/SBSourceManager.h" 26 #include "lldb/API/SBStream.h" 27 #include "lldb/API/SBStringList.h" 28 #include "lldb/API/SBStructuredData.h" 29 #include "lldb/API/SBTarget.h" 30 #include "lldb/API/SBThread.h" 31 #include "lldb/API/SBTypeCategory.h" 32 #include "lldb/API/SBTypeFilter.h" 33 #include "lldb/API/SBTypeFormat.h" 34 #include "lldb/API/SBTypeNameSpecifier.h" 35 #include "lldb/API/SBTypeSummary.h" 36 #include "lldb/API/SBTypeSynthetic.h" 37 38 #include "lldb/Core/Debugger.h" 39 #include "lldb/Core/PluginManager.h" 40 #include "lldb/Core/StreamFile.h" 41 #include "lldb/Core/StructuredDataImpl.h" 42 #include "lldb/DataFormatters/DataVisualization.h" 43 #include "lldb/Host/XML.h" 44 #include "lldb/Initialization/SystemLifetimeManager.h" 45 #include "lldb/Interpreter/CommandInterpreter.h" 46 #include "lldb/Interpreter/OptionArgParser.h" 47 #include "lldb/Interpreter/OptionGroupPlatform.h" 48 #include "lldb/Target/Process.h" 49 #include "lldb/Target/TargetList.h" 50 #include "lldb/Utility/Args.h" 51 #include "lldb/Utility/State.h" 52 53 #include "llvm/ADT/STLExtras.h" 54 #include "llvm/ADT/StringRef.h" 55 #include "llvm/Support/DynamicLibrary.h" 56 #include "llvm/Support/ManagedStatic.h" 57 58 using namespace lldb; 59 using namespace lldb_private; 60 61 static llvm::sys::DynamicLibrary LoadPlugin(const lldb::DebuggerSP &debugger_sp, 62 const FileSpec &spec, 63 Status &error) { 64 llvm::sys::DynamicLibrary dynlib = 65 llvm::sys::DynamicLibrary::getPermanentLibrary(spec.GetPath().c_str()); 66 if (dynlib.isValid()) { 67 typedef bool (*LLDBCommandPluginInit)(lldb::SBDebugger & debugger); 68 69 lldb::SBDebugger debugger_sb(debugger_sp); 70 // This calls the bool lldb::PluginInitialize(lldb::SBDebugger debugger) 71 // function. 72 // TODO: mangle this differently for your system - on OSX, the first 73 // underscore needs to be removed and the second one stays 74 LLDBCommandPluginInit init_func = 75 (LLDBCommandPluginInit)(uintptr_t)dynlib.getAddressOfSymbol( 76 "_ZN4lldb16PluginInitializeENS_10SBDebuggerE"); 77 if (init_func) { 78 if (init_func(debugger_sb)) 79 return dynlib; 80 else 81 error.SetErrorString("plug-in refused to load " 82 "(lldb::PluginInitialize(lldb::SBDebugger) " 83 "returned false)"); 84 } else { 85 error.SetErrorString("plug-in is missing the required initialization: " 86 "lldb::PluginInitialize(lldb::SBDebugger)"); 87 } 88 } else { 89 if (FileSystem::Instance().Exists(spec)) 90 error.SetErrorString("this file does not represent a loadable dylib"); 91 else 92 error.SetErrorString("no such file"); 93 } 94 return llvm::sys::DynamicLibrary(); 95 } 96 97 static llvm::ManagedStatic<SystemLifetimeManager> g_debugger_lifetime; 98 99 SBError SBInputReader::Initialize( 100 lldb::SBDebugger &sb_debugger, 101 unsigned long (*)(void *, lldb::SBInputReader *, lldb::InputReaderAction, 102 char const *, unsigned long), 103 void *, lldb::InputReaderGranularity, char const *, char const *, bool) { 104 return SBError(); 105 } 106 107 void SBInputReader::SetIsDone(bool) {} 108 109 bool SBInputReader::IsActive() const { return false; } 110 111 SBDebugger::SBDebugger() = default; 112 113 SBDebugger::SBDebugger(const lldb::DebuggerSP &debugger_sp) 114 : m_opaque_sp(debugger_sp) {} 115 116 SBDebugger::SBDebugger(const SBDebugger &rhs) : m_opaque_sp(rhs.m_opaque_sp) {} 117 118 SBDebugger::~SBDebugger() = default; 119 120 SBDebugger &SBDebugger::operator=(const SBDebugger &rhs) { 121 if (this != &rhs) { 122 m_opaque_sp = rhs.m_opaque_sp; 123 } 124 return *this; 125 } 126 127 void SBDebugger::Initialize() { 128 SBInitializerOptions options; 129 SBDebugger::Initialize(options); 130 } 131 132 lldb::SBError SBDebugger::Initialize(SBInitializerOptions &options) { 133 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 134 135 if (log) 136 log->Printf("SBDebugger::Initialize ()"); 137 138 SBError error; 139 if (auto e = g_debugger_lifetime->Initialize( 140 llvm::make_unique<SystemInitializerFull>(), *options.m_opaque_up, 141 LoadPlugin)) { 142 error.SetError(Status(std::move(e))); 143 } 144 return error; 145 } 146 147 void SBDebugger::Terminate() { g_debugger_lifetime->Terminate(); } 148 149 void SBDebugger::Clear() { 150 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 151 152 if (log) 153 log->Printf("SBDebugger(%p)::Clear ()", 154 static_cast<void *>(m_opaque_sp.get())); 155 156 if (m_opaque_sp) 157 m_opaque_sp->ClearIOHandlers(); 158 159 m_opaque_sp.reset(); 160 } 161 162 SBDebugger SBDebugger::Create() { 163 return SBDebugger::Create(false, nullptr, nullptr); 164 } 165 166 SBDebugger SBDebugger::Create(bool source_init_files) { 167 return SBDebugger::Create(source_init_files, nullptr, nullptr); 168 } 169 170 SBDebugger SBDebugger::Create(bool source_init_files, 171 lldb::LogOutputCallback callback, void *baton) 172 173 { 174 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 175 176 SBDebugger debugger; 177 178 // Currently we have issues if this function is called simultaneously on two 179 // different threads. The issues mainly revolve around the fact that the 180 // lldb_private::FormatManager uses global collections and having two threads 181 // parsing the .lldbinit files can cause mayhem. So to get around this for 182 // now we need to use a mutex to prevent bad things from happening. 183 static std::recursive_mutex g_mutex; 184 std::lock_guard<std::recursive_mutex> guard(g_mutex); 185 186 debugger.reset(Debugger::CreateInstance(callback, baton)); 187 188 if (log) { 189 SBStream sstr; 190 debugger.GetDescription(sstr); 191 log->Printf("SBDebugger::Create () => SBDebugger(%p): %s", 192 static_cast<void *>(debugger.m_opaque_sp.get()), 193 sstr.GetData()); 194 } 195 196 SBCommandInterpreter interp = debugger.GetCommandInterpreter(); 197 if (source_init_files) { 198 interp.get()->SkipLLDBInitFiles(false); 199 interp.get()->SkipAppInitFiles(false); 200 SBCommandReturnObject result; 201 interp.SourceInitFileInHomeDirectory(result); 202 } else { 203 interp.get()->SkipLLDBInitFiles(true); 204 interp.get()->SkipAppInitFiles(true); 205 } 206 return debugger; 207 } 208 209 void SBDebugger::Destroy(SBDebugger &debugger) { 210 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 211 212 if (log) { 213 SBStream sstr; 214 debugger.GetDescription(sstr); 215 log->Printf("SBDebugger::Destroy () => SBDebugger(%p): %s", 216 static_cast<void *>(debugger.m_opaque_sp.get()), 217 sstr.GetData()); 218 } 219 220 Debugger::Destroy(debugger.m_opaque_sp); 221 222 if (debugger.m_opaque_sp.get() != nullptr) 223 debugger.m_opaque_sp.reset(); 224 } 225 226 void SBDebugger::MemoryPressureDetected() { 227 // Since this function can be call asynchronously, we allow it to be non- 228 // mandatory. We have seen deadlocks with this function when called so we 229 // need to safeguard against this until we can determine what is causing the 230 // deadlocks. 231 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 232 233 const bool mandatory = false; 234 if (log) { 235 log->Printf("SBDebugger::MemoryPressureDetected (), mandatory = %d", 236 mandatory); 237 } 238 239 ModuleList::RemoveOrphanSharedModules(mandatory); 240 } 241 242 bool SBDebugger::IsValid() const { return m_opaque_sp.get() != nullptr; } 243 244 void SBDebugger::SetAsync(bool b) { 245 if (m_opaque_sp) 246 m_opaque_sp->SetAsyncExecution(b); 247 } 248 249 bool SBDebugger::GetAsync() { 250 return (m_opaque_sp ? m_opaque_sp->GetAsyncExecution() : false); 251 } 252 253 void SBDebugger::SkipLLDBInitFiles(bool b) { 254 if (m_opaque_sp) 255 m_opaque_sp->GetCommandInterpreter().SkipLLDBInitFiles(b); 256 } 257 258 void SBDebugger::SkipAppInitFiles(bool b) { 259 if (m_opaque_sp) 260 m_opaque_sp->GetCommandInterpreter().SkipAppInitFiles(b); 261 } 262 263 // Shouldn't really be settable after initialization as this could cause lots 264 // of problems; don't want users trying to switch modes in the middle of a 265 // debugging session. 266 void SBDebugger::SetInputFileHandle(FILE *fh, bool transfer_ownership) { 267 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 268 269 if (log) 270 log->Printf( 271 "SBDebugger(%p)::SetInputFileHandle (fh=%p, transfer_ownership=%i)", 272 static_cast<void *>(m_opaque_sp.get()), static_cast<void *>(fh), 273 transfer_ownership); 274 275 if (m_opaque_sp) 276 m_opaque_sp->SetInputFileHandle(fh, transfer_ownership); 277 } 278 279 void SBDebugger::SetOutputFileHandle(FILE *fh, bool transfer_ownership) { 280 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 281 282 if (log) 283 log->Printf( 284 "SBDebugger(%p)::SetOutputFileHandle (fh=%p, transfer_ownership=%i)", 285 static_cast<void *>(m_opaque_sp.get()), static_cast<void *>(fh), 286 transfer_ownership); 287 288 if (m_opaque_sp) 289 m_opaque_sp->SetOutputFileHandle(fh, transfer_ownership); 290 } 291 292 void SBDebugger::SetErrorFileHandle(FILE *fh, bool transfer_ownership) { 293 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 294 295 if (log) 296 log->Printf( 297 "SBDebugger(%p)::SetErrorFileHandle (fh=%p, transfer_ownership=%i)", 298 static_cast<void *>(m_opaque_sp.get()), static_cast<void *>(fh), 299 transfer_ownership); 300 301 if (m_opaque_sp) 302 m_opaque_sp->SetErrorFileHandle(fh, transfer_ownership); 303 } 304 305 FILE *SBDebugger::GetInputFileHandle() { 306 if (m_opaque_sp) { 307 StreamFileSP stream_file_sp(m_opaque_sp->GetInputFile()); 308 if (stream_file_sp) 309 return stream_file_sp->GetFile().GetStream(); 310 } 311 return nullptr; 312 } 313 314 FILE *SBDebugger::GetOutputFileHandle() { 315 if (m_opaque_sp) { 316 StreamFileSP stream_file_sp(m_opaque_sp->GetOutputFile()); 317 if (stream_file_sp) 318 return stream_file_sp->GetFile().GetStream(); 319 } 320 return nullptr; 321 } 322 323 FILE *SBDebugger::GetErrorFileHandle() { 324 if (m_opaque_sp) { 325 StreamFileSP stream_file_sp(m_opaque_sp->GetErrorFile()); 326 if (stream_file_sp) 327 return stream_file_sp->GetFile().GetStream(); 328 } 329 return nullptr; 330 } 331 332 void SBDebugger::SaveInputTerminalState() { 333 if (m_opaque_sp) 334 m_opaque_sp->SaveInputTerminalState(); 335 } 336 337 void SBDebugger::RestoreInputTerminalState() { 338 if (m_opaque_sp) 339 m_opaque_sp->RestoreInputTerminalState(); 340 } 341 SBCommandInterpreter SBDebugger::GetCommandInterpreter() { 342 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 343 344 SBCommandInterpreter sb_interpreter; 345 if (m_opaque_sp) 346 sb_interpreter.reset(&m_opaque_sp->GetCommandInterpreter()); 347 348 if (log) 349 log->Printf( 350 "SBDebugger(%p)::GetCommandInterpreter () => SBCommandInterpreter(%p)", 351 static_cast<void *>(m_opaque_sp.get()), 352 static_cast<void *>(sb_interpreter.get())); 353 354 return sb_interpreter; 355 } 356 357 void SBDebugger::HandleCommand(const char *command) { 358 if (m_opaque_sp) { 359 TargetSP target_sp(m_opaque_sp->GetSelectedTarget()); 360 std::unique_lock<std::recursive_mutex> lock; 361 if (target_sp) 362 lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); 363 364 SBCommandInterpreter sb_interpreter(GetCommandInterpreter()); 365 SBCommandReturnObject result; 366 367 sb_interpreter.HandleCommand(command, result, false); 368 369 if (GetErrorFileHandle() != nullptr) 370 result.PutError(GetErrorFileHandle()); 371 if (GetOutputFileHandle() != nullptr) 372 result.PutOutput(GetOutputFileHandle()); 373 374 if (!m_opaque_sp->GetAsyncExecution()) { 375 SBProcess process(GetCommandInterpreter().GetProcess()); 376 ProcessSP process_sp(process.GetSP()); 377 if (process_sp) { 378 EventSP event_sp; 379 ListenerSP lldb_listener_sp = m_opaque_sp->GetListener(); 380 while (lldb_listener_sp->GetEventForBroadcaster( 381 process_sp.get(), event_sp, std::chrono::seconds(0))) { 382 SBEvent event(event_sp); 383 HandleProcessEvent(process, event, GetOutputFileHandle(), 384 GetErrorFileHandle()); 385 } 386 } 387 } 388 } 389 } 390 391 SBListener SBDebugger::GetListener() { 392 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 393 394 SBListener sb_listener; 395 if (m_opaque_sp) 396 sb_listener.reset(m_opaque_sp->GetListener()); 397 398 if (log) 399 log->Printf("SBDebugger(%p)::GetListener () => SBListener(%p)", 400 static_cast<void *>(m_opaque_sp.get()), 401 static_cast<void *>(sb_listener.get())); 402 403 return sb_listener; 404 } 405 406 void SBDebugger::HandleProcessEvent(const SBProcess &process, 407 const SBEvent &event, FILE *out, 408 FILE *err) { 409 if (!process.IsValid()) 410 return; 411 412 TargetSP target_sp(process.GetTarget().GetSP()); 413 if (!target_sp) 414 return; 415 416 const uint32_t event_type = event.GetType(); 417 char stdio_buffer[1024]; 418 size_t len; 419 420 std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex()); 421 422 if (event_type & 423 (Process::eBroadcastBitSTDOUT | Process::eBroadcastBitStateChanged)) { 424 // Drain stdout when we stop just in case we have any bytes 425 while ((len = process.GetSTDOUT(stdio_buffer, sizeof(stdio_buffer))) > 0) 426 if (out != nullptr) 427 ::fwrite(stdio_buffer, 1, len, out); 428 } 429 430 if (event_type & 431 (Process::eBroadcastBitSTDERR | Process::eBroadcastBitStateChanged)) { 432 // Drain stderr when we stop just in case we have any bytes 433 while ((len = process.GetSTDERR(stdio_buffer, sizeof(stdio_buffer))) > 0) 434 if (err != nullptr) 435 ::fwrite(stdio_buffer, 1, len, err); 436 } 437 438 if (event_type & Process::eBroadcastBitStateChanged) { 439 StateType event_state = SBProcess::GetStateFromEvent(event); 440 441 if (event_state == eStateInvalid) 442 return; 443 444 bool is_stopped = StateIsStoppedState(event_state); 445 if (!is_stopped) 446 process.ReportEventState(event, out); 447 } 448 } 449 450 SBSourceManager SBDebugger::GetSourceManager() { 451 SBSourceManager sb_source_manager(*this); 452 return sb_source_manager; 453 } 454 455 bool SBDebugger::GetDefaultArchitecture(char *arch_name, size_t arch_name_len) { 456 if (arch_name && arch_name_len) { 457 ArchSpec default_arch = Target::GetDefaultArchitecture(); 458 459 if (default_arch.IsValid()) { 460 const std::string &triple_str = default_arch.GetTriple().str(); 461 if (!triple_str.empty()) 462 ::snprintf(arch_name, arch_name_len, "%s", triple_str.c_str()); 463 else 464 ::snprintf(arch_name, arch_name_len, "%s", 465 default_arch.GetArchitectureName()); 466 return true; 467 } 468 } 469 if (arch_name && arch_name_len) 470 arch_name[0] = '\0'; 471 return false; 472 } 473 474 bool SBDebugger::SetDefaultArchitecture(const char *arch_name) { 475 if (arch_name) { 476 ArchSpec arch(arch_name); 477 if (arch.IsValid()) { 478 Target::SetDefaultArchitecture(arch); 479 return true; 480 } 481 } 482 return false; 483 } 484 485 ScriptLanguage 486 SBDebugger::GetScriptingLanguage(const char *script_language_name) { 487 if (!script_language_name) return eScriptLanguageDefault; 488 return OptionArgParser::ToScriptLanguage( 489 llvm::StringRef(script_language_name), eScriptLanguageDefault, nullptr); 490 } 491 492 const char *SBDebugger::GetVersionString() { 493 return lldb_private::GetVersion(); 494 } 495 496 const char *SBDebugger::StateAsCString(StateType state) { 497 return lldb_private::StateAsCString(state); 498 } 499 500 static void AddBoolConfigEntry(StructuredData::Dictionary &dict, 501 llvm::StringRef name, bool value, 502 llvm::StringRef description) { 503 auto entry_up = llvm::make_unique<StructuredData::Dictionary>(); 504 entry_up->AddBooleanItem("value", value); 505 entry_up->AddStringItem("description", description); 506 dict.AddItem(name, std::move(entry_up)); 507 } 508 509 static void AddLLVMTargets(StructuredData::Dictionary &dict) { 510 auto array_up = llvm::make_unique<StructuredData::Array>(); 511 #define LLVM_TARGET(target) \ 512 array_up->AddItem(llvm::make_unique<StructuredData::String>(#target)); 513 #include "llvm/Config/Targets.def" 514 auto entry_up = llvm::make_unique<StructuredData::Dictionary>(); 515 entry_up->AddItem("value", std::move(array_up)); 516 entry_up->AddStringItem("description", "A list of configured LLVM targets."); 517 dict.AddItem("targets", std::move(entry_up)); 518 } 519 520 SBStructuredData SBDebugger::GetBuildConfiguration() { 521 auto config_up = llvm::make_unique<StructuredData::Dictionary>(); 522 AddBoolConfigEntry( 523 *config_up, "xml", XMLDocument::XMLEnabled(), 524 "A boolean value that indicates if XML support is enabled in LLDB"); 525 AddLLVMTargets(*config_up); 526 527 SBStructuredData data; 528 data.m_impl_up->SetObjectSP(std::move(config_up)); 529 return data; 530 } 531 532 bool SBDebugger::StateIsRunningState(StateType state) { 533 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 534 535 const bool result = lldb_private::StateIsRunningState(state); 536 if (log) 537 log->Printf("SBDebugger::StateIsRunningState (state=%s) => %i", 538 StateAsCString(state), result); 539 540 return result; 541 } 542 543 bool SBDebugger::StateIsStoppedState(StateType state) { 544 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 545 546 const bool result = lldb_private::StateIsStoppedState(state, false); 547 if (log) 548 log->Printf("SBDebugger::StateIsStoppedState (state=%s) => %i", 549 StateAsCString(state), result); 550 551 return result; 552 } 553 554 lldb::SBTarget SBDebugger::CreateTarget(const char *filename, 555 const char *target_triple, 556 const char *platform_name, 557 bool add_dependent_modules, 558 lldb::SBError &sb_error) { 559 SBTarget sb_target; 560 TargetSP target_sp; 561 if (m_opaque_sp) { 562 sb_error.Clear(); 563 OptionGroupPlatform platform_options(false); 564 platform_options.SetPlatformName(platform_name); 565 566 sb_error.ref() = m_opaque_sp->GetTargetList().CreateTarget( 567 *m_opaque_sp, filename, target_triple, 568 add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, 569 &platform_options, target_sp); 570 571 if (sb_error.Success()) 572 sb_target.SetSP(target_sp); 573 } else { 574 sb_error.SetErrorString("invalid debugger"); 575 } 576 577 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 578 if (log) 579 log->Printf("SBDebugger(%p)::CreateTarget (filename=\"%s\", triple=%s, " 580 "platform_name=%s, add_dependent_modules=%u, error=%s) => " 581 "SBTarget(%p)", 582 static_cast<void *>(m_opaque_sp.get()), filename, target_triple, 583 platform_name, add_dependent_modules, sb_error.GetCString(), 584 static_cast<void *>(target_sp.get())); 585 586 return sb_target; 587 } 588 589 SBTarget 590 SBDebugger::CreateTargetWithFileAndTargetTriple(const char *filename, 591 const char *target_triple) { 592 SBTarget sb_target; 593 TargetSP target_sp; 594 if (m_opaque_sp) { 595 const bool add_dependent_modules = true; 596 Status error(m_opaque_sp->GetTargetList().CreateTarget( 597 *m_opaque_sp, filename, target_triple, 598 add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr, 599 target_sp)); 600 sb_target.SetSP(target_sp); 601 } 602 603 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 604 if (log) 605 log->Printf("SBDebugger(%p)::CreateTargetWithFileAndTargetTriple " 606 "(filename=\"%s\", triple=%s) => SBTarget(%p)", 607 static_cast<void *>(m_opaque_sp.get()), filename, target_triple, 608 static_cast<void *>(target_sp.get())); 609 610 return sb_target; 611 } 612 613 SBTarget SBDebugger::CreateTargetWithFileAndArch(const char *filename, 614 const char *arch_cstr) { 615 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 616 617 SBTarget sb_target; 618 TargetSP target_sp; 619 if (m_opaque_sp) { 620 Status error; 621 const bool add_dependent_modules = true; 622 623 error = m_opaque_sp->GetTargetList().CreateTarget( 624 *m_opaque_sp, filename, arch_cstr, 625 add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr, 626 target_sp); 627 628 if (error.Success()) { 629 m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp.get()); 630 sb_target.SetSP(target_sp); 631 } 632 } 633 634 if (log) 635 log->Printf("SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", " 636 "arch=%s) => SBTarget(%p)", 637 static_cast<void *>(m_opaque_sp.get()), filename, arch_cstr, 638 static_cast<void *>(target_sp.get())); 639 640 return sb_target; 641 } 642 643 SBTarget SBDebugger::CreateTarget(const char *filename) { 644 SBTarget sb_target; 645 TargetSP target_sp; 646 if (m_opaque_sp) { 647 Status error; 648 const bool add_dependent_modules = true; 649 error = m_opaque_sp->GetTargetList().CreateTarget( 650 *m_opaque_sp, filename, "", 651 add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr, 652 target_sp); 653 654 if (error.Success()) { 655 m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp.get()); 656 sb_target.SetSP(target_sp); 657 } 658 } 659 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 660 if (log) 661 log->Printf( 662 "SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)", 663 static_cast<void *>(m_opaque_sp.get()), filename, 664 static_cast<void *>(target_sp.get())); 665 return sb_target; 666 } 667 668 SBTarget SBDebugger::GetDummyTarget() { 669 SBTarget sb_target; 670 if (m_opaque_sp) { 671 sb_target.SetSP(m_opaque_sp->GetDummyTarget()->shared_from_this()); 672 } 673 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 674 if (log) 675 log->Printf( 676 "SBDebugger(%p)::GetDummyTarget() => SBTarget(%p)", 677 static_cast<void *>(m_opaque_sp.get()), 678 static_cast<void *>(sb_target.GetSP().get())); 679 return sb_target; 680 } 681 682 bool SBDebugger::DeleteTarget(lldb::SBTarget &target) { 683 bool result = false; 684 if (m_opaque_sp) { 685 TargetSP target_sp(target.GetSP()); 686 if (target_sp) { 687 // No need to lock, the target list is thread safe 688 result = m_opaque_sp->GetTargetList().DeleteTarget(target_sp); 689 target_sp->Destroy(); 690 target.Clear(); 691 const bool mandatory = true; 692 ModuleList::RemoveOrphanSharedModules(mandatory); 693 } 694 } 695 696 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 697 if (log) 698 log->Printf("SBDebugger(%p)::DeleteTarget (SBTarget(%p)) => %i", 699 static_cast<void *>(m_opaque_sp.get()), 700 static_cast<void *>(target.m_opaque_sp.get()), result); 701 702 return result; 703 } 704 705 SBTarget SBDebugger::GetTargetAtIndex(uint32_t idx) { 706 SBTarget sb_target; 707 if (m_opaque_sp) { 708 // No need to lock, the target list is thread safe 709 sb_target.SetSP(m_opaque_sp->GetTargetList().GetTargetAtIndex(idx)); 710 } 711 return sb_target; 712 } 713 714 uint32_t SBDebugger::GetIndexOfTarget(lldb::SBTarget target) { 715 716 lldb::TargetSP target_sp = target.GetSP(); 717 if (!target_sp) 718 return UINT32_MAX; 719 720 if (!m_opaque_sp) 721 return UINT32_MAX; 722 723 return m_opaque_sp->GetTargetList().GetIndexOfTarget(target.GetSP()); 724 } 725 726 SBTarget SBDebugger::FindTargetWithProcessID(lldb::pid_t pid) { 727 SBTarget sb_target; 728 if (m_opaque_sp) { 729 // No need to lock, the target list is thread safe 730 sb_target.SetSP(m_opaque_sp->GetTargetList().FindTargetWithProcessID(pid)); 731 } 732 return sb_target; 733 } 734 735 SBTarget SBDebugger::FindTargetWithFileAndArch(const char *filename, 736 const char *arch_name) { 737 SBTarget sb_target; 738 if (m_opaque_sp && filename && filename[0]) { 739 // No need to lock, the target list is thread safe 740 ArchSpec arch = Platform::GetAugmentedArchSpec( 741 m_opaque_sp->GetPlatformList().GetSelectedPlatform().get(), arch_name); 742 TargetSP target_sp( 743 m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture( 744 FileSpec(filename), arch_name ? &arch : nullptr)); 745 sb_target.SetSP(target_sp); 746 } 747 return sb_target; 748 } 749 750 SBTarget SBDebugger::FindTargetWithLLDBProcess(const ProcessSP &process_sp) { 751 SBTarget sb_target; 752 if (m_opaque_sp) { 753 // No need to lock, the target list is thread safe 754 sb_target.SetSP( 755 m_opaque_sp->GetTargetList().FindTargetWithProcess(process_sp.get())); 756 } 757 return sb_target; 758 } 759 760 uint32_t SBDebugger::GetNumTargets() { 761 if (m_opaque_sp) { 762 // No need to lock, the target list is thread safe 763 return m_opaque_sp->GetTargetList().GetNumTargets(); 764 } 765 return 0; 766 } 767 768 SBTarget SBDebugger::GetSelectedTarget() { 769 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 770 771 SBTarget sb_target; 772 TargetSP target_sp; 773 if (m_opaque_sp) { 774 // No need to lock, the target list is thread safe 775 target_sp = m_opaque_sp->GetTargetList().GetSelectedTarget(); 776 sb_target.SetSP(target_sp); 777 } 778 779 if (log) { 780 SBStream sstr; 781 sb_target.GetDescription(sstr, eDescriptionLevelBrief); 782 log->Printf("SBDebugger(%p)::GetSelectedTarget () => SBTarget(%p): %s", 783 static_cast<void *>(m_opaque_sp.get()), 784 static_cast<void *>(target_sp.get()), sstr.GetData()); 785 } 786 787 return sb_target; 788 } 789 790 void SBDebugger::SetSelectedTarget(SBTarget &sb_target) { 791 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 792 793 TargetSP target_sp(sb_target.GetSP()); 794 if (m_opaque_sp) { 795 m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp.get()); 796 } 797 if (log) { 798 SBStream sstr; 799 sb_target.GetDescription(sstr, eDescriptionLevelBrief); 800 log->Printf("SBDebugger(%p)::SetSelectedTarget () => SBTarget(%p): %s", 801 static_cast<void *>(m_opaque_sp.get()), 802 static_cast<void *>(target_sp.get()), sstr.GetData()); 803 } 804 } 805 806 SBPlatform SBDebugger::GetSelectedPlatform() { 807 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 808 809 SBPlatform sb_platform; 810 DebuggerSP debugger_sp(m_opaque_sp); 811 if (debugger_sp) { 812 sb_platform.SetSP(debugger_sp->GetPlatformList().GetSelectedPlatform()); 813 } 814 if (log) 815 log->Printf("SBDebugger(%p)::GetSelectedPlatform () => SBPlatform(%p): %s", 816 static_cast<void *>(m_opaque_sp.get()), 817 static_cast<void *>(sb_platform.GetSP().get()), 818 sb_platform.GetName()); 819 return sb_platform; 820 } 821 822 void SBDebugger::SetSelectedPlatform(SBPlatform &sb_platform) { 823 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 824 825 DebuggerSP debugger_sp(m_opaque_sp); 826 if (debugger_sp) { 827 debugger_sp->GetPlatformList().SetSelectedPlatform(sb_platform.GetSP()); 828 } 829 830 if (log) 831 log->Printf("SBDebugger(%p)::SetSelectedPlatform (SBPlatform(%p) %s)", 832 static_cast<void *>(m_opaque_sp.get()), 833 static_cast<void *>(sb_platform.GetSP().get()), 834 sb_platform.GetName()); 835 } 836 837 uint32_t SBDebugger::GetNumPlatforms() { 838 if (m_opaque_sp) { 839 // No need to lock, the platform list is thread safe 840 return m_opaque_sp->GetPlatformList().GetSize(); 841 } 842 return 0; 843 } 844 845 SBPlatform SBDebugger::GetPlatformAtIndex(uint32_t idx) { 846 SBPlatform sb_platform; 847 if (m_opaque_sp) { 848 // No need to lock, the platform list is thread safe 849 sb_platform.SetSP(m_opaque_sp->GetPlatformList().GetAtIndex(idx)); 850 } 851 return sb_platform; 852 } 853 854 uint32_t SBDebugger::GetNumAvailablePlatforms() { 855 uint32_t idx = 0; 856 while (true) { 857 if (!PluginManager::GetPlatformPluginNameAtIndex(idx)) { 858 break; 859 } 860 ++idx; 861 } 862 // +1 for the host platform, which should always appear first in the list. 863 return idx + 1; 864 } 865 866 SBStructuredData SBDebugger::GetAvailablePlatformInfoAtIndex(uint32_t idx) { 867 SBStructuredData data; 868 auto platform_dict = llvm::make_unique<StructuredData::Dictionary>(); 869 llvm::StringRef name_str("name"), desc_str("description"); 870 871 if (idx == 0) { 872 PlatformSP host_platform_sp(Platform::GetHostPlatform()); 873 platform_dict->AddStringItem( 874 name_str, host_platform_sp->GetPluginName().GetStringRef()); 875 platform_dict->AddStringItem( 876 desc_str, llvm::StringRef(host_platform_sp->GetDescription())); 877 } else if (idx > 0) { 878 const char *plugin_name = 879 PluginManager::GetPlatformPluginNameAtIndex(idx - 1); 880 if (!plugin_name) { 881 return data; 882 } 883 platform_dict->AddStringItem(name_str, llvm::StringRef(plugin_name)); 884 885 const char *plugin_desc = 886 PluginManager::GetPlatformPluginDescriptionAtIndex(idx - 1); 887 if (!plugin_desc) { 888 return data; 889 } 890 platform_dict->AddStringItem(desc_str, llvm::StringRef(plugin_desc)); 891 } 892 893 data.m_impl_up->SetObjectSP( 894 StructuredData::ObjectSP(platform_dict.release())); 895 return data; 896 } 897 898 void SBDebugger::DispatchInput(void *baton, const void *data, size_t data_len) { 899 DispatchInput(data, data_len); 900 } 901 902 void SBDebugger::DispatchInput(const void *data, size_t data_len) { 903 // Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 904 // 905 // if (log) 906 // log->Printf ("SBDebugger(%p)::DispatchInput (data=\"%.*s\", 907 // size_t=%" PRIu64 ")", 908 // m_opaque_sp.get(), 909 // (int) data_len, 910 // (const char *) data, 911 // (uint64_t)data_len); 912 // 913 // if (m_opaque_sp) 914 // m_opaque_sp->DispatchInput ((const char *) data, data_len); 915 } 916 917 void SBDebugger::DispatchInputInterrupt() { 918 if (m_opaque_sp) 919 m_opaque_sp->DispatchInputInterrupt(); 920 } 921 922 void SBDebugger::DispatchInputEndOfFile() { 923 if (m_opaque_sp) 924 m_opaque_sp->DispatchInputEndOfFile(); 925 } 926 927 void SBDebugger::PushInputReader(SBInputReader &reader) {} 928 929 void SBDebugger::RunCommandInterpreter(bool auto_handle_events, 930 bool spawn_thread) { 931 if (m_opaque_sp) { 932 CommandInterpreterRunOptions options; 933 934 m_opaque_sp->GetCommandInterpreter().RunCommandInterpreter( 935 auto_handle_events, spawn_thread, options); 936 } 937 } 938 939 void SBDebugger::RunCommandInterpreter(bool auto_handle_events, 940 bool spawn_thread, 941 SBCommandInterpreterRunOptions &options, 942 int &num_errors, bool &quit_requested, 943 bool &stopped_for_crash) 944 945 { 946 if (m_opaque_sp) { 947 CommandInterpreter &interp = m_opaque_sp->GetCommandInterpreter(); 948 interp.RunCommandInterpreter(auto_handle_events, spawn_thread, 949 options.ref()); 950 num_errors = interp.GetNumErrors(); 951 quit_requested = interp.GetQuitRequested(); 952 stopped_for_crash = interp.GetStoppedForCrash(); 953 } 954 } 955 956 SBError SBDebugger::RunREPL(lldb::LanguageType language, 957 const char *repl_options) { 958 SBError error; 959 if (m_opaque_sp) 960 error.ref() = m_opaque_sp->RunREPL(language, repl_options); 961 else 962 error.SetErrorString("invalid debugger"); 963 return error; 964 } 965 966 void SBDebugger::reset(const DebuggerSP &debugger_sp) { 967 m_opaque_sp = debugger_sp; 968 } 969 970 Debugger *SBDebugger::get() const { return m_opaque_sp.get(); } 971 972 Debugger &SBDebugger::ref() const { 973 assert(m_opaque_sp.get()); 974 return *m_opaque_sp; 975 } 976 977 const lldb::DebuggerSP &SBDebugger::get_sp() const { return m_opaque_sp; } 978 979 SBDebugger SBDebugger::FindDebuggerWithID(int id) { 980 // No need to lock, the debugger list is thread safe 981 SBDebugger sb_debugger; 982 DebuggerSP debugger_sp = Debugger::FindDebuggerWithID(id); 983 if (debugger_sp) 984 sb_debugger.reset(debugger_sp); 985 return sb_debugger; 986 } 987 988 const char *SBDebugger::GetInstanceName() { 989 return (m_opaque_sp ? m_opaque_sp->GetInstanceName().AsCString() : nullptr); 990 } 991 992 SBError SBDebugger::SetInternalVariable(const char *var_name, const char *value, 993 const char *debugger_instance_name) { 994 SBError sb_error; 995 DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName( 996 ConstString(debugger_instance_name))); 997 Status error; 998 if (debugger_sp) { 999 ExecutionContext exe_ctx( 1000 debugger_sp->GetCommandInterpreter().GetExecutionContext()); 1001 error = debugger_sp->SetPropertyValue(&exe_ctx, eVarSetOperationAssign, 1002 var_name, value); 1003 } else { 1004 error.SetErrorStringWithFormat("invalid debugger instance name '%s'", 1005 debugger_instance_name); 1006 } 1007 if (error.Fail()) 1008 sb_error.SetError(error); 1009 return sb_error; 1010 } 1011 1012 SBStringList 1013 SBDebugger::GetInternalVariableValue(const char *var_name, 1014 const char *debugger_instance_name) { 1015 SBStringList ret_value; 1016 DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName( 1017 ConstString(debugger_instance_name))); 1018 Status error; 1019 if (debugger_sp) { 1020 ExecutionContext exe_ctx( 1021 debugger_sp->GetCommandInterpreter().GetExecutionContext()); 1022 lldb::OptionValueSP value_sp( 1023 debugger_sp->GetPropertyValue(&exe_ctx, var_name, false, error)); 1024 if (value_sp) { 1025 StreamString value_strm; 1026 value_sp->DumpValue(&exe_ctx, value_strm, OptionValue::eDumpOptionValue); 1027 const std::string &value_str = value_strm.GetString(); 1028 if (!value_str.empty()) { 1029 StringList string_list; 1030 string_list.SplitIntoLines(value_str); 1031 return SBStringList(&string_list); 1032 } 1033 } 1034 } 1035 return SBStringList(); 1036 } 1037 1038 uint32_t SBDebugger::GetTerminalWidth() const { 1039 return (m_opaque_sp ? m_opaque_sp->GetTerminalWidth() : 0); 1040 } 1041 1042 void SBDebugger::SetTerminalWidth(uint32_t term_width) { 1043 if (m_opaque_sp) 1044 m_opaque_sp->SetTerminalWidth(term_width); 1045 } 1046 1047 const char *SBDebugger::GetPrompt() const { 1048 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1049 1050 if (log) 1051 log->Printf("SBDebugger(%p)::GetPrompt () => \"%s\"", 1052 static_cast<void *>(m_opaque_sp.get()), 1053 (m_opaque_sp ? m_opaque_sp->GetPrompt().str().c_str() : "")); 1054 1055 return (m_opaque_sp ? ConstString(m_opaque_sp->GetPrompt()).GetCString() 1056 : nullptr); 1057 } 1058 1059 void SBDebugger::SetPrompt(const char *prompt) { 1060 if (m_opaque_sp) 1061 m_opaque_sp->SetPrompt(llvm::StringRef::withNullAsEmpty(prompt)); 1062 } 1063 1064 const char *SBDebugger::GetReproducerPath() const { 1065 return (m_opaque_sp 1066 ? ConstString(m_opaque_sp->GetReproducerPath()).GetCString() 1067 : nullptr); 1068 } 1069 1070 ScriptLanguage SBDebugger::GetScriptLanguage() const { 1071 return (m_opaque_sp ? m_opaque_sp->GetScriptLanguage() : eScriptLanguageNone); 1072 } 1073 1074 void SBDebugger::SetScriptLanguage(ScriptLanguage script_lang) { 1075 if (m_opaque_sp) { 1076 m_opaque_sp->SetScriptLanguage(script_lang); 1077 } 1078 } 1079 1080 bool SBDebugger::SetUseExternalEditor(bool value) { 1081 return (m_opaque_sp ? m_opaque_sp->SetUseExternalEditor(value) : false); 1082 } 1083 1084 bool SBDebugger::GetUseExternalEditor() { 1085 return (m_opaque_sp ? m_opaque_sp->GetUseExternalEditor() : false); 1086 } 1087 1088 bool SBDebugger::SetUseColor(bool value) { 1089 return (m_opaque_sp ? m_opaque_sp->SetUseColor(value) : false); 1090 } 1091 1092 bool SBDebugger::GetUseColor() const { 1093 return (m_opaque_sp ? m_opaque_sp->GetUseColor() : false); 1094 } 1095 1096 bool SBDebugger::GetDescription(SBStream &description) { 1097 Stream &strm = description.ref(); 1098 1099 if (m_opaque_sp) { 1100 const char *name = m_opaque_sp->GetInstanceName().AsCString(); 1101 user_id_t id = m_opaque_sp->GetID(); 1102 strm.Printf("Debugger (instance: \"%s\", id: %" PRIu64 ")", name, id); 1103 } else 1104 strm.PutCString("No value"); 1105 1106 return true; 1107 } 1108 1109 user_id_t SBDebugger::GetID() { 1110 return (m_opaque_sp ? m_opaque_sp->GetID() : LLDB_INVALID_UID); 1111 } 1112 1113 SBError SBDebugger::SetCurrentPlatform(const char *platform_name_cstr) { 1114 SBError sb_error; 1115 if (m_opaque_sp) { 1116 if (platform_name_cstr && platform_name_cstr[0]) { 1117 ConstString platform_name(platform_name_cstr); 1118 PlatformSP platform_sp(Platform::Find(platform_name)); 1119 1120 if (platform_sp) { 1121 // Already have a platform with this name, just select it 1122 m_opaque_sp->GetPlatformList().SetSelectedPlatform(platform_sp); 1123 } else { 1124 // We don't have a platform by this name yet, create one 1125 platform_sp = Platform::Create(platform_name, sb_error.ref()); 1126 if (platform_sp) { 1127 // We created the platform, now append and select it 1128 bool make_selected = true; 1129 m_opaque_sp->GetPlatformList().Append(platform_sp, make_selected); 1130 } 1131 } 1132 } else { 1133 sb_error.ref().SetErrorString("invalid platform name"); 1134 } 1135 } else { 1136 sb_error.ref().SetErrorString("invalid debugger"); 1137 } 1138 return sb_error; 1139 } 1140 1141 bool SBDebugger::SetCurrentPlatformSDKRoot(const char *sysroot) { 1142 Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1143 if (m_opaque_sp) { 1144 PlatformSP platform_sp( 1145 m_opaque_sp->GetPlatformList().GetSelectedPlatform()); 1146 1147 if (platform_sp) { 1148 if (log && sysroot) 1149 log->Printf("SBDebugger::SetCurrentPlatformSDKRoot (\"%s\")", sysroot); 1150 platform_sp->SetSDKRootDirectory(ConstString(sysroot)); 1151 return true; 1152 } 1153 } 1154 return false; 1155 } 1156 1157 bool SBDebugger::GetCloseInputOnEOF() const { 1158 return (m_opaque_sp ? m_opaque_sp->GetCloseInputOnEOF() : false); 1159 } 1160 1161 void SBDebugger::SetCloseInputOnEOF(bool b) { 1162 if (m_opaque_sp) 1163 m_opaque_sp->SetCloseInputOnEOF(b); 1164 } 1165 1166 SBTypeCategory SBDebugger::GetCategory(const char *category_name) { 1167 if (!category_name || *category_name == 0) 1168 return SBTypeCategory(); 1169 1170 TypeCategoryImplSP category_sp; 1171 1172 if (DataVisualization::Categories::GetCategory(ConstString(category_name), 1173 category_sp, false)) 1174 return SBTypeCategory(category_sp); 1175 else 1176 return SBTypeCategory(); 1177 } 1178 1179 SBTypeCategory SBDebugger::GetCategory(lldb::LanguageType lang_type) { 1180 TypeCategoryImplSP category_sp; 1181 if (DataVisualization::Categories::GetCategory(lang_type, category_sp)) 1182 return SBTypeCategory(category_sp); 1183 else 1184 return SBTypeCategory(); 1185 } 1186 1187 SBTypeCategory SBDebugger::CreateCategory(const char *category_name) { 1188 if (!category_name || *category_name == 0) 1189 return SBTypeCategory(); 1190 1191 TypeCategoryImplSP category_sp; 1192 1193 if (DataVisualization::Categories::GetCategory(ConstString(category_name), 1194 category_sp, true)) 1195 return SBTypeCategory(category_sp); 1196 else 1197 return SBTypeCategory(); 1198 } 1199 1200 bool SBDebugger::DeleteCategory(const char *category_name) { 1201 if (!category_name || *category_name == 0) 1202 return false; 1203 1204 return DataVisualization::Categories::Delete(ConstString(category_name)); 1205 } 1206 1207 uint32_t SBDebugger::GetNumCategories() { 1208 return DataVisualization::Categories::GetCount(); 1209 } 1210 1211 SBTypeCategory SBDebugger::GetCategoryAtIndex(uint32_t index) { 1212 return SBTypeCategory( 1213 DataVisualization::Categories::GetCategoryAtIndex(index)); 1214 } 1215 1216 SBTypeCategory SBDebugger::GetDefaultCategory() { 1217 return GetCategory("default"); 1218 } 1219 1220 SBTypeFormat SBDebugger::GetFormatForType(SBTypeNameSpecifier type_name) { 1221 SBTypeCategory default_category_sb = GetDefaultCategory(); 1222 if (default_category_sb.GetEnabled()) 1223 return default_category_sb.GetFormatForType(type_name); 1224 return SBTypeFormat(); 1225 } 1226 1227 #ifndef LLDB_DISABLE_PYTHON 1228 SBTypeSummary SBDebugger::GetSummaryForType(SBTypeNameSpecifier type_name) { 1229 if (!type_name.IsValid()) 1230 return SBTypeSummary(); 1231 return SBTypeSummary(DataVisualization::GetSummaryForType(type_name.GetSP())); 1232 } 1233 #endif // LLDB_DISABLE_PYTHON 1234 1235 SBTypeFilter SBDebugger::GetFilterForType(SBTypeNameSpecifier type_name) { 1236 if (!type_name.IsValid()) 1237 return SBTypeFilter(); 1238 return SBTypeFilter(DataVisualization::GetFilterForType(type_name.GetSP())); 1239 } 1240 1241 #ifndef LLDB_DISABLE_PYTHON 1242 SBTypeSynthetic SBDebugger::GetSyntheticForType(SBTypeNameSpecifier type_name) { 1243 if (!type_name.IsValid()) 1244 return SBTypeSynthetic(); 1245 return SBTypeSynthetic( 1246 DataVisualization::GetSyntheticForType(type_name.GetSP())); 1247 } 1248 #endif // LLDB_DISABLE_PYTHON 1249 1250 static llvm::ArrayRef<const char *> GetCategoryArray(const char **categories) { 1251 if (categories == nullptr) 1252 return {}; 1253 size_t len = 0; 1254 while (categories[len] != nullptr) 1255 ++len; 1256 return llvm::makeArrayRef(categories, len); 1257 } 1258 1259 bool SBDebugger::EnableLog(const char *channel, const char **categories) { 1260 if (m_opaque_sp) { 1261 uint32_t log_options = 1262 LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME; 1263 std::string error; 1264 llvm::raw_string_ostream error_stream(error); 1265 return m_opaque_sp->EnableLog(channel, GetCategoryArray(categories), "", 1266 log_options, error_stream); 1267 } else 1268 return false; 1269 } 1270 1271 void SBDebugger::SetLoggingCallback(lldb::LogOutputCallback log_callback, 1272 void *baton) { 1273 if (m_opaque_sp) { 1274 return m_opaque_sp->SetLoggingCallback(log_callback, baton); 1275 } 1276 } 1277