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 #include "lldb/API/SBDebugger.h"
11 
12 #include "lldb/lldb-private.h"
13 
14 #include "lldb/API/SBListener.h"
15 #include "lldb/API/SBBroadcaster.h"
16 #include "lldb/API/SBCommandInterpreter.h"
17 #include "lldb/API/SBCommandReturnObject.h"
18 #include "lldb/API/SBError.h"
19 #include "lldb/API/SBEvent.h"
20 #include "lldb/API/SBFrame.h"
21 #include "lldb/API/SBInputReader.h"
22 #include "lldb/API/SBProcess.h"
23 #include "lldb/API/SBSourceManager.h"
24 #include "lldb/API/SBStream.h"
25 #include "lldb/API/SBStringList.h"
26 #include "lldb/API/SBTarget.h"
27 #include "lldb/API/SBThread.h"
28 #include "lldb/Core/Debugger.h"
29 #include "lldb/Core/State.h"
30 #include "lldb/Interpreter/Args.h"
31 #include "lldb/Interpreter/CommandInterpreter.h"
32 #include "lldb/Target/Process.h"
33 #include "lldb/Target/TargetList.h"
34 
35 using namespace lldb;
36 using namespace lldb_private;
37 
38 void
39 SBDebugger::Initialize ()
40 {
41     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
42 
43     if (log)
44         log->Printf ("SBDebugger::Initialize ()");
45 
46     SBCommandInterpreter::InitializeSWIG ();
47 
48     Debugger::Initialize();
49 }
50 
51 void
52 SBDebugger::Terminate ()
53 {
54     Debugger::Terminate();
55 }
56 
57 void
58 SBDebugger::Clear ()
59 {
60     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
61 
62     if (log)
63         log->Printf ("SBDebugger(%p)::Clear ()", m_opaque_sp.get());
64 
65     if (m_opaque_sp)
66         m_opaque_sp->CleanUpInputReaders ();
67 
68     m_opaque_sp.reset();
69 }
70 
71 SBDebugger
72 SBDebugger::Create()
73 {
74     return SBDebugger::Create(false);
75 }
76 
77 SBDebugger
78 SBDebugger::Create(bool source_init_files)
79 {
80     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
81 
82     SBDebugger debugger;
83     debugger.reset(Debugger::CreateInstance());
84 
85     if (log)
86     {
87         SBStream sstr;
88         debugger.GetDescription (sstr);
89         log->Printf ("SBDebugger::Create () => SBDebugger(%p): %s", debugger.m_opaque_sp.get(), sstr.GetData());
90     }
91 
92     SBCommandInterpreter interp = debugger.GetCommandInterpreter();
93     if (source_init_files)
94     {
95         interp.get()->SkipLLDBInitFiles(false);
96         interp.get()->SkipAppInitFiles (false);
97         SBCommandReturnObject result;
98         interp.SourceInitFileInHomeDirectory(result);
99     }
100     else
101     {
102         interp.get()->SkipLLDBInitFiles(true);
103         interp.get()->SkipAppInitFiles (true);
104     }
105     return debugger;
106 }
107 
108 void
109 SBDebugger::Destroy (SBDebugger &debugger)
110 {
111     LogSP log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
112 
113     if (log)
114     {
115         SBStream sstr;
116         debugger.GetDescription (sstr);
117         log->Printf ("SBDebugger::Destroy () => SBDebugger(%p): %s", debugger.m_opaque_sp.get(), sstr.GetData());
118     }
119 
120     Debugger::Destroy (debugger.m_opaque_sp);
121 
122     if (debugger.m_opaque_sp.get() != NULL)
123         debugger.m_opaque_sp.reset();
124 }
125 
126 SBDebugger::SBDebugger () :
127     m_opaque_sp ()
128 {
129 }
130 
131 SBDebugger::SBDebugger(const lldb::DebuggerSP &debugger_sp) :
132     m_opaque_sp(debugger_sp)
133 {
134 }
135 
136 SBDebugger::SBDebugger(const SBDebugger &rhs) :
137     m_opaque_sp (rhs.m_opaque_sp)
138 {
139 }
140 
141 SBDebugger &
142 SBDebugger::operator = (const SBDebugger &rhs)
143 {
144     if (this != &rhs)
145     {
146         m_opaque_sp = rhs.m_opaque_sp;
147     }
148     return *this;
149 }
150 
151 SBDebugger::~SBDebugger ()
152 {
153 }
154 
155 bool
156 SBDebugger::IsValid() const
157 {
158     return m_opaque_sp.get() != NULL;
159 }
160 
161 
162 void
163 SBDebugger::SetAsync (bool b)
164 {
165     if (m_opaque_sp)
166         m_opaque_sp->SetAsyncExecution(b);
167 }
168 
169 void
170 SBDebugger::SkipLLDBInitFiles (bool b)
171 {
172     if (m_opaque_sp)
173         m_opaque_sp->GetCommandInterpreter().SkipLLDBInitFiles (b);
174 }
175 
176 void
177 SBDebugger::SkipAppInitFiles (bool b)
178 {
179     if (m_opaque_sp)
180         m_opaque_sp->GetCommandInterpreter().SkipAppInitFiles (b);
181 }
182 
183 // Shouldn't really be settable after initialization as this could cause lots of problems; don't want users
184 // trying to switch modes in the middle of a debugging session.
185 void
186 SBDebugger::SetInputFileHandle (FILE *fh, bool transfer_ownership)
187 {
188     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
189 
190     if (log)
191         log->Printf ("SBDebugger(%p)::SetInputFileHandle (fh=%p, transfer_ownership=%i)", m_opaque_sp.get(),
192                      fh, transfer_ownership);
193 
194     if (m_opaque_sp)
195         m_opaque_sp->SetInputFileHandle (fh, transfer_ownership);
196 }
197 
198 void
199 SBDebugger::SetOutputFileHandle (FILE *fh, bool transfer_ownership)
200 {
201     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
202 
203 
204     if (log)
205         log->Printf ("SBDebugger(%p)::SetOutputFileHandle (fh=%p, transfer_ownership=%i)", m_opaque_sp.get(),
206                      fh, transfer_ownership);
207 
208     if (m_opaque_sp)
209         m_opaque_sp->SetOutputFileHandle (fh, transfer_ownership);
210 }
211 
212 void
213 SBDebugger::SetErrorFileHandle (FILE *fh, bool transfer_ownership)
214 {
215     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
216 
217 
218     if (log)
219         log->Printf ("SBDebugger(%p)::SetErrorFileHandle (fh=%p, transfer_ownership=%i)", m_opaque_sp.get(),
220                      fh, transfer_ownership);
221 
222     if (m_opaque_sp)
223         m_opaque_sp->SetErrorFileHandle (fh, transfer_ownership);
224 }
225 
226 FILE *
227 SBDebugger::GetInputFileHandle ()
228 {
229     if (m_opaque_sp)
230         return m_opaque_sp->GetInputFile().GetStream();
231     return NULL;
232 }
233 
234 FILE *
235 SBDebugger::GetOutputFileHandle ()
236 {
237     if (m_opaque_sp)
238         return m_opaque_sp->GetOutputFile().GetStream();
239     return NULL;
240 }
241 
242 FILE *
243 SBDebugger::GetErrorFileHandle ()
244 {
245     if (m_opaque_sp)
246         return m_opaque_sp->GetErrorFile().GetStream();
247     return NULL;
248 }
249 
250 SBCommandInterpreter
251 SBDebugger::GetCommandInterpreter ()
252 {
253     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
254 
255     SBCommandInterpreter sb_interpreter;
256     if (m_opaque_sp)
257         sb_interpreter.reset (&m_opaque_sp->GetCommandInterpreter());
258 
259     if (log)
260         log->Printf ("SBDebugger(%p)::GetCommandInterpreter () => SBCommandInterpreter(%p)",
261                      m_opaque_sp.get(), sb_interpreter.get());
262 
263     return sb_interpreter;
264 }
265 
266 void
267 SBDebugger::HandleCommand (const char *command)
268 {
269     if (m_opaque_sp)
270     {
271         TargetSP target_sp (m_opaque_sp->GetSelectedTarget());
272         Mutex::Locker api_locker;
273         if (target_sp)
274             api_locker.Reset(target_sp->GetAPIMutex().GetMutex());
275 
276         SBCommandInterpreter sb_interpreter(GetCommandInterpreter ());
277         SBCommandReturnObject result;
278 
279         sb_interpreter.HandleCommand (command, result, false);
280 
281         if (GetErrorFileHandle() != NULL)
282             result.PutError (GetErrorFileHandle());
283         if (GetOutputFileHandle() != NULL)
284             result.PutOutput (GetOutputFileHandle());
285 
286         if (m_opaque_sp->GetAsyncExecution() == false)
287         {
288             SBProcess process(GetCommandInterpreter().GetProcess ());
289             if (process.IsValid())
290             {
291                 EventSP event_sp;
292                 Listener &lldb_listener = m_opaque_sp->GetListener();
293                 while (lldb_listener.GetNextEventForBroadcaster (process.get(), event_sp))
294                 {
295                     SBEvent event(event_sp);
296                     HandleProcessEvent (process, event, GetOutputFileHandle(), GetErrorFileHandle());
297                 }
298             }
299         }
300     }
301 }
302 
303 SBListener
304 SBDebugger::GetListener ()
305 {
306     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
307 
308     SBListener sb_listener;
309     if (m_opaque_sp)
310         sb_listener.reset(&m_opaque_sp->GetListener(), false);
311 
312     if (log)
313         log->Printf ("SBDebugger(%p)::GetListener () => SBListener(%p)", m_opaque_sp.get(),
314                      sb_listener.get());
315 
316     return sb_listener;
317 }
318 
319 void
320 SBDebugger::HandleProcessEvent (const SBProcess &process, const SBEvent &event, FILE *out, FILE *err)
321 {
322     if (!process.IsValid())
323         return;
324 
325     const uint32_t event_type = event.GetType();
326     char stdio_buffer[1024];
327     size_t len;
328 
329     Mutex::Locker api_locker (process.GetTarget()->GetAPIMutex());
330 
331     if (event_type & (Process::eBroadcastBitSTDOUT | Process::eBroadcastBitStateChanged))
332     {
333         // Drain stdout when we stop just in case we have any bytes
334         while ((len = process.GetSTDOUT (stdio_buffer, sizeof (stdio_buffer))) > 0)
335             if (out != NULL)
336                 ::fwrite (stdio_buffer, 1, len, out);
337     }
338 
339     if (event_type & (Process::eBroadcastBitSTDERR | Process::eBroadcastBitStateChanged))
340     {
341         // Drain stderr when we stop just in case we have any bytes
342         while ((len = process.GetSTDERR (stdio_buffer, sizeof (stdio_buffer))) > 0)
343             if (err != NULL)
344                 ::fwrite (stdio_buffer, 1, len, err);
345     }
346 
347     if (event_type & Process::eBroadcastBitStateChanged)
348     {
349         StateType event_state = SBProcess::GetStateFromEvent (event);
350 
351         if (event_state == eStateInvalid)
352             return;
353 
354         bool is_stopped = StateIsStoppedState (event_state);
355         if (!is_stopped)
356             process.ReportEventState (event, out);
357     }
358 }
359 
360 SBSourceManager &
361 SBDebugger::GetSourceManager ()
362 {
363     static SourceManager g_lldb_source_manager(NULL);
364     static SBSourceManager g_sb_source_manager (&g_lldb_source_manager);
365     return g_sb_source_manager;
366 }
367 
368 
369 bool
370 SBDebugger::GetDefaultArchitecture (char *arch_name, size_t arch_name_len)
371 {
372     if (arch_name && arch_name_len)
373     {
374         ArchSpec default_arch = Target::GetDefaultArchitecture ();
375 
376         if (default_arch.IsValid())
377         {
378             const std::string &triple_str = default_arch.GetTriple().str();
379             if (!triple_str.empty())
380                 ::snprintf (arch_name, arch_name_len, "%s", triple_str.c_str());
381             else
382                 ::snprintf (arch_name, arch_name_len, "%s", default_arch.GetArchitectureName());
383             return true;
384         }
385     }
386     if (arch_name && arch_name_len)
387         arch_name[0] = '\0';
388     return false;
389 }
390 
391 
392 bool
393 SBDebugger::SetDefaultArchitecture (const char *arch_name)
394 {
395     if (arch_name)
396     {
397         ArchSpec arch (arch_name, NULL);
398         if (arch.IsValid())
399         {
400             Target::SetDefaultArchitecture (arch);
401             return true;
402         }
403     }
404     return false;
405 }
406 
407 ScriptLanguage
408 SBDebugger::GetScriptingLanguage (const char *script_language_name)
409 {
410 
411     return Args::StringToScriptLanguage (script_language_name,
412                                          eScriptLanguageDefault,
413                                          NULL);
414 }
415 
416 const char *
417 SBDebugger::GetVersionString ()
418 {
419     return GetVersion();
420 }
421 
422 const char *
423 SBDebugger::StateAsCString (StateType state)
424 {
425     return lldb_private::StateAsCString (state);
426 }
427 
428 bool
429 SBDebugger::StateIsRunningState (StateType state)
430 {
431     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
432 
433     const bool result = lldb_private::StateIsRunningState (state);
434     if (log)
435         log->Printf ("SBDebugger::StateIsRunningState (state=%s) => %i",
436                      StateAsCString (state), result);
437 
438     return result;
439 }
440 
441 bool
442 SBDebugger::StateIsStoppedState (StateType state)
443 {
444     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
445 
446     const bool result = lldb_private::StateIsStoppedState (state);
447     if (log)
448         log->Printf ("SBDebugger::StateIsStoppedState (state=%s) => %i",
449                      StateAsCString (state), result);
450 
451     return result;
452 }
453 
454 
455 SBTarget
456 SBDebugger::CreateTargetWithFileAndTargetTriple (const char *filename,
457                                                  const char *target_triple)
458 {
459     SBTarget target;
460     if (m_opaque_sp)
461     {
462         ArchSpec arch;
463         FileSpec file_spec (filename, true);
464         arch.SetTriple (target_triple, m_opaque_sp->GetPlatformList().GetSelectedPlatform().get());
465         TargetSP target_sp;
466         Error error (m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file_spec, arch, true, target_sp));
467         target.reset (target_sp);
468     }
469 
470     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
471     if (log)
472     {
473         log->Printf ("SBDebugger(%p)::CreateTargetWithFileAndTargetTriple (filename=\"%s\", triple=%s) => SBTarget(%p)",
474                      m_opaque_sp.get(), filename, target_triple, target.get());
475     }
476 
477     return target;
478 }
479 
480 SBTarget
481 SBDebugger::CreateTargetWithFileAndArch (const char *filename, const char *arch_cstr)
482 {
483     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
484 
485     SBTarget target;
486     if (m_opaque_sp)
487     {
488         FileSpec file (filename, true);
489         ArchSpec arch;
490         TargetSP target_sp;
491         Error error;
492 
493         if (arch_cstr)
494             arch.SetTriple (arch_cstr, m_opaque_sp->GetPlatformList().GetSelectedPlatform().get());
495 
496         error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, true, target_sp);
497 
498         if (error.Success())
499         {
500             m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get());
501             target.reset(target_sp);
502         }
503     }
504 
505     if (log)
506     {
507         log->Printf ("SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", arch=%s) => SBTarget(%p)",
508                      m_opaque_sp.get(), filename, arch_cstr, target.get());
509     }
510 
511     return target;
512 }
513 
514 SBTarget
515 SBDebugger::CreateTarget (const char *filename)
516 {
517     SBTarget target;
518     if (m_opaque_sp)
519     {
520         FileSpec file (filename, true);
521         ArchSpec arch = Target::GetDefaultArchitecture ();
522         TargetSP target_sp;
523         Error error;
524 
525         error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, true, target_sp);
526 
527         if (error.Success())
528         {
529             m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get());
530             target.reset (target_sp);
531         }
532     }
533     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
534     if (log)
535     {
536         log->Printf ("SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)",
537                      m_opaque_sp.get(), filename, target.get());
538     }
539     return target;
540 }
541 
542 bool
543 SBDebugger::DeleteTarget (lldb::SBTarget &target)
544 {
545     bool result = false;
546     if (m_opaque_sp)
547     {
548         // No need to lock, the target list is thread safe
549         result = m_opaque_sp->GetTargetList().DeleteTarget (target.m_opaque_sp);
550     }
551 
552     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
553     if (log)
554     {
555         log->Printf ("SBDebugger(%p)::DeleteTarget (SBTarget(%p)) => %i", m_opaque_sp.get(), target.m_opaque_sp.get(), result);
556     }
557 
558     return result;
559 }
560 SBTarget
561 SBDebugger::GetTargetAtIndex (uint32_t idx)
562 {
563     SBTarget sb_target;
564     if (m_opaque_sp)
565     {
566         // No need to lock, the target list is thread safe
567         sb_target.reset(m_opaque_sp->GetTargetList().GetTargetAtIndex (idx));
568     }
569     return sb_target;
570 }
571 
572 SBTarget
573 SBDebugger::FindTargetWithProcessID (pid_t pid)
574 {
575     SBTarget sb_target;
576     if (m_opaque_sp)
577     {
578         // No need to lock, the target list is thread safe
579         sb_target.reset(m_opaque_sp->GetTargetList().FindTargetWithProcessID (pid));
580     }
581     return sb_target;
582 }
583 
584 SBTarget
585 SBDebugger::FindTargetWithFileAndArch (const char *filename, const char *arch_name)
586 {
587     SBTarget sb_target;
588     if (m_opaque_sp && filename && filename[0])
589     {
590         // No need to lock, the target list is thread safe
591         ArchSpec arch (arch_name, m_opaque_sp->GetPlatformList().GetSelectedPlatform().get());
592         TargetSP target_sp (m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture (FileSpec(filename, false), arch_name ? &arch : NULL));
593         sb_target.reset(target_sp);
594     }
595     return sb_target;
596 }
597 
598 SBTarget
599 SBDebugger::FindTargetWithLLDBProcess (const ProcessSP &process_sp)
600 {
601     SBTarget sb_target;
602     if (m_opaque_sp)
603     {
604         // No need to lock, the target list is thread safe
605         sb_target.reset(m_opaque_sp->GetTargetList().FindTargetWithProcess (process_sp.get()));
606     }
607     return sb_target;
608 }
609 
610 
611 uint32_t
612 SBDebugger::GetNumTargets ()
613 {
614     if (m_opaque_sp)
615     {
616         // No need to lock, the target list is thread safe
617         return m_opaque_sp->GetTargetList().GetNumTargets ();
618     }
619     return 0;
620 }
621 
622 SBTarget
623 SBDebugger::GetSelectedTarget ()
624 {
625     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
626 
627     SBTarget sb_target;
628     if (m_opaque_sp)
629     {
630         // No need to lock, the target list is thread safe
631         sb_target.reset(m_opaque_sp->GetTargetList().GetSelectedTarget ());
632     }
633 
634     if (log)
635     {
636         SBStream sstr;
637         sb_target.GetDescription (sstr, eDescriptionLevelBrief);
638         log->Printf ("SBDebugger(%p)::GetSelectedTarget () => SBTarget(%p): %s", m_opaque_sp.get(),
639                      sb_target.get(), sstr.GetData());
640     }
641 
642     return sb_target;
643 }
644 
645 void
646 SBDebugger::DispatchInput (void *baton, const void *data, size_t data_len)
647 {
648     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
649 
650     if (log)
651         log->Printf ("SBDebugger(%p)::DispatchInput (baton=%p, data=\"%.*s\", size_t=%zu)", m_opaque_sp.get(),
652                      baton, (int) data_len, (const char *) data, data_len);
653 
654     if (m_opaque_sp)
655         m_opaque_sp->DispatchInput ((const char *) data, data_len);
656 }
657 
658 void
659 SBDebugger::DispatchInputInterrupt ()
660 {
661     if (m_opaque_sp)
662         m_opaque_sp->DispatchInputInterrupt ();
663 }
664 
665 void
666 SBDebugger::DispatchInputEndOfFile ()
667 {
668     if (m_opaque_sp)
669         m_opaque_sp->DispatchInputEndOfFile ();
670 }
671 
672 bool
673 SBDebugger::InputReaderIsTopReader (const lldb::SBInputReader &reader)
674 {
675     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
676 
677     if (log)
678         log->Printf ("SBDebugger(%p)::InputReaderIsTopReader (SBInputReader(%p))", m_opaque_sp.get(), &reader);
679 
680     if (m_opaque_sp && reader.IsValid())
681     {
682         InputReaderSP reader_sp (*reader);
683         return m_opaque_sp->InputReaderIsTopReader (reader_sp);
684     }
685 
686     return false;
687 }
688 
689 
690 void
691 SBDebugger::PushInputReader (SBInputReader &reader)
692 {
693     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
694 
695     if (log)
696         log->Printf ("SBDebugger(%p)::PushInputReader (SBInputReader(%p))", m_opaque_sp.get(), &reader);
697 
698     if (m_opaque_sp && reader.IsValid())
699     {
700         TargetSP target_sp (m_opaque_sp->GetSelectedTarget());
701         Mutex::Locker api_locker;
702         if (target_sp)
703             api_locker.Reset(target_sp->GetAPIMutex().GetMutex());
704         InputReaderSP reader_sp(*reader);
705         m_opaque_sp->PushInputReader (reader_sp);
706     }
707 }
708 
709 void
710 SBDebugger::NotifyTopInputReader (InputReaderAction notification)
711 {
712     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
713 
714     if (log)
715         log->Printf ("SBDebugger(%p)::NotifyTopInputReader (%d)", m_opaque_sp.get(), notification);
716 
717     if (m_opaque_sp)
718         m_opaque_sp->NotifyTopInputReader (notification);
719 }
720 
721 void
722 SBDebugger::reset (const DebuggerSP &debugger_sp)
723 {
724     m_opaque_sp = debugger_sp;
725 }
726 
727 Debugger *
728 SBDebugger::get () const
729 {
730     return m_opaque_sp.get();
731 }
732 
733 Debugger &
734 SBDebugger::ref () const
735 {
736     assert (m_opaque_sp.get());
737     return *m_opaque_sp;
738 }
739 
740 
741 SBDebugger
742 SBDebugger::FindDebuggerWithID (int id)
743 {
744     // No need to lock, the debugger list is thread safe
745     SBDebugger sb_debugger;
746     DebuggerSP debugger_sp = Debugger::FindDebuggerWithID (id);
747     if (debugger_sp)
748         sb_debugger.reset (debugger_sp);
749     return sb_debugger;
750 }
751 
752 const char *
753 SBDebugger::GetInstanceName()
754 {
755     if (m_opaque_sp)
756         return m_opaque_sp->GetInstanceName().AsCString();
757     else
758         return NULL;
759 }
760 
761 SBError
762 SBDebugger::SetInternalVariable (const char *var_name, const char *value, const char *debugger_instance_name)
763 {
764     UserSettingsControllerSP root_settings_controller = Debugger::GetSettingsController();
765 
766     Error err = root_settings_controller->SetVariable (var_name,
767                                                        value,
768                                                        eVarSetOperationAssign,
769                                                        true,
770                                                        debugger_instance_name);
771     SBError sb_error;
772     sb_error.SetError (err);
773 
774     return sb_error;
775 }
776 
777 SBStringList
778 SBDebugger::GetInternalVariableValue (const char *var_name, const char *debugger_instance_name)
779 {
780     SBStringList ret_value;
781     SettableVariableType var_type;
782     Error err;
783 
784     UserSettingsControllerSP root_settings_controller = Debugger::GetSettingsController();
785 
786     StringList value = root_settings_controller->GetVariable (var_name, var_type, debugger_instance_name, err);
787 
788     if (err.Success())
789     {
790         for (unsigned i = 0; i != value.GetSize(); ++i)
791             ret_value.AppendString (value.GetStringAtIndex(i));
792     }
793     else
794     {
795         ret_value.AppendString (err.AsCString());
796     }
797 
798 
799     return ret_value;
800 }
801 
802 uint32_t
803 SBDebugger::GetTerminalWidth () const
804 {
805     if (m_opaque_sp)
806         return m_opaque_sp->GetTerminalWidth ();
807     return 0;
808 }
809 
810 void
811 SBDebugger::SetTerminalWidth (uint32_t term_width)
812 {
813     if (m_opaque_sp)
814         m_opaque_sp->SetTerminalWidth (term_width);
815 }
816 
817 const char *
818 SBDebugger::GetPrompt() const
819 {
820     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
821 
822     if (log)
823         log->Printf ("SBDebugger(%p)::GetPrompt () => \"%s\"", m_opaque_sp.get(),
824                      (m_opaque_sp ? m_opaque_sp->GetPrompt() : ""));
825 
826     if (m_opaque_sp)
827         return m_opaque_sp->GetPrompt ();
828     return 0;
829 }
830 
831 void
832 SBDebugger::SetPrompt (const char *prompt)
833 {
834     if (m_opaque_sp)
835         m_opaque_sp->SetPrompt (prompt);
836 }
837 
838 
839 ScriptLanguage
840 SBDebugger::GetScriptLanguage() const
841 {
842     if (m_opaque_sp)
843         return m_opaque_sp->GetScriptLanguage ();
844     return eScriptLanguageNone;
845 }
846 
847 void
848 SBDebugger::SetScriptLanguage (ScriptLanguage script_lang)
849 {
850     if (m_opaque_sp)
851     {
852         m_opaque_sp->SetScriptLanguage (script_lang);
853     }
854 }
855 
856 bool
857 SBDebugger::SetUseExternalEditor (bool value)
858 {
859     if (m_opaque_sp)
860         return m_opaque_sp->SetUseExternalEditor (value);
861     return false;
862 }
863 
864 bool
865 SBDebugger::GetUseExternalEditor ()
866 {
867     if (m_opaque_sp)
868         return m_opaque_sp->GetUseExternalEditor ();
869     return false;
870 }
871 
872 bool
873 SBDebugger::GetDescription (SBStream &description)
874 {
875     if (m_opaque_sp)
876     {
877         const char *name = m_opaque_sp->GetInstanceName().AsCString();
878         user_id_t id = m_opaque_sp->GetID();
879         description.Printf ("Debugger (instance: \"%s\", id: %d)", name, id);
880     }
881     else
882         description.Printf ("No value");
883 
884     return true;
885 }
886 
887 user_id_t
888 SBDebugger::GetID()
889 {
890     if (m_opaque_sp)
891         return m_opaque_sp->GetID();
892     return LLDB_INVALID_UID;
893 }
894 
895 
896 SBError
897 SBDebugger::SetCurrentPlatform (const char *platform_name)
898 {
899     SBError sb_error;
900     if (m_opaque_sp)
901     {
902         PlatformSP platform_sp (Platform::Create (platform_name, sb_error.ref()));
903 
904         if (platform_sp)
905         {
906             bool make_selected = true;
907             m_opaque_sp->GetPlatformList().Append (platform_sp, make_selected);
908         }
909     }
910     return sb_error;
911 }
912 
913 bool
914 SBDebugger::SetCurrentPlatformSDKRoot (const char *sysroot)
915 {
916     if (m_opaque_sp)
917     {
918         PlatformSP platform_sp (m_opaque_sp->GetPlatformList().GetSelectedPlatform());
919 
920         if (platform_sp)
921         {
922             platform_sp->SetSDKRootDirectory (ConstString (sysroot));
923             return true;
924         }
925     }
926     return false;
927 }
928 
929 bool
930 SBDebugger::GetCloseInputOnEOF () const
931 {
932     if (m_opaque_sp)
933         return m_opaque_sp->GetCloseInputOnEOF ();
934     return false;
935 }
936 
937 void
938 SBDebugger::SetCloseInputOnEOF (bool b)
939 {
940     if (m_opaque_sp)
941         m_opaque_sp->SetCloseInputOnEOF (b);
942 }
943