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