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