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