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