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