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     SBSourceManager sb_source_manager (*this);
364     return sb_source_manager;
365 }
366 
367 
368 bool
369 SBDebugger::GetDefaultArchitecture (char *arch_name, size_t arch_name_len)
370 {
371     if (arch_name && arch_name_len)
372     {
373         ArchSpec default_arch = Target::GetDefaultArchitecture ();
374 
375         if (default_arch.IsValid())
376         {
377             const std::string &triple_str = default_arch.GetTriple().str();
378             if (!triple_str.empty())
379                 ::snprintf (arch_name, arch_name_len, "%s", triple_str.c_str());
380             else
381                 ::snprintf (arch_name, arch_name_len, "%s", default_arch.GetArchitectureName());
382             return true;
383         }
384     }
385     if (arch_name && arch_name_len)
386         arch_name[0] = '\0';
387     return false;
388 }
389 
390 
391 bool
392 SBDebugger::SetDefaultArchitecture (const char *arch_name)
393 {
394     if (arch_name)
395     {
396         ArchSpec arch (arch_name, NULL);
397         if (arch.IsValid())
398         {
399             Target::SetDefaultArchitecture (arch);
400             return true;
401         }
402     }
403     return false;
404 }
405 
406 ScriptLanguage
407 SBDebugger::GetScriptingLanguage (const char *script_language_name)
408 {
409 
410     return Args::StringToScriptLanguage (script_language_name,
411                                          eScriptLanguageDefault,
412                                          NULL);
413 }
414 
415 const char *
416 SBDebugger::GetVersionString ()
417 {
418     return GetVersion();
419 }
420 
421 const char *
422 SBDebugger::StateAsCString (StateType state)
423 {
424     return lldb_private::StateAsCString (state);
425 }
426 
427 bool
428 SBDebugger::StateIsRunningState (StateType state)
429 {
430     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
431 
432     const bool result = lldb_private::StateIsRunningState (state);
433     if (log)
434         log->Printf ("SBDebugger::StateIsRunningState (state=%s) => %i",
435                      StateAsCString (state), result);
436 
437     return result;
438 }
439 
440 bool
441 SBDebugger::StateIsStoppedState (StateType state)
442 {
443     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
444 
445     const bool result = lldb_private::StateIsStoppedState (state);
446     if (log)
447         log->Printf ("SBDebugger::StateIsStoppedState (state=%s) => %i",
448                      StateAsCString (state), result);
449 
450     return result;
451 }
452 
453 
454 SBTarget
455 SBDebugger::CreateTargetWithFileAndTargetTriple (const char *filename,
456                                                  const char *target_triple)
457 {
458     SBTarget target;
459     if (m_opaque_sp)
460     {
461         ArchSpec arch;
462         FileSpec file_spec (filename, true);
463         arch.SetTriple (target_triple, m_opaque_sp->GetPlatformList().GetSelectedPlatform().get());
464         TargetSP target_sp;
465         Error error (m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file_spec, arch, true, target_sp));
466         target.reset (target_sp);
467     }
468 
469     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
470     if (log)
471     {
472         log->Printf ("SBDebugger(%p)::CreateTargetWithFileAndTargetTriple (filename=\"%s\", triple=%s) => SBTarget(%p)",
473                      m_opaque_sp.get(), filename, target_triple, target.get());
474     }
475 
476     return target;
477 }
478 
479 SBTarget
480 SBDebugger::CreateTargetWithFileAndArch (const char *filename, const char *arch_cstr)
481 {
482     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
483 
484     SBTarget target;
485     if (m_opaque_sp)
486     {
487         FileSpec file (filename, true);
488         ArchSpec arch;
489         TargetSP target_sp;
490         Error error;
491 
492         if (arch_cstr)
493             arch.SetTriple (arch_cstr, m_opaque_sp->GetPlatformList().GetSelectedPlatform().get());
494 
495         error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, true, target_sp);
496 
497         if (error.Success())
498         {
499             m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get());
500             target.reset(target_sp);
501         }
502     }
503 
504     if (log)
505     {
506         log->Printf ("SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", arch=%s) => SBTarget(%p)",
507                      m_opaque_sp.get(), filename, arch_cstr, target.get());
508     }
509 
510     return target;
511 }
512 
513 SBTarget
514 SBDebugger::CreateTarget (const char *filename)
515 {
516     SBTarget target;
517     if (m_opaque_sp)
518     {
519         FileSpec file (filename, true);
520         ArchSpec arch = Target::GetDefaultArchitecture ();
521         TargetSP target_sp;
522         Error error;
523 
524         error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, true, target_sp);
525 
526         if (error.Success())
527         {
528             m_opaque_sp->GetTargetList().SetSelectedTarget (target_sp.get());
529             target.reset (target_sp);
530         }
531     }
532     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
533     if (log)
534     {
535         log->Printf ("SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)",
536                      m_opaque_sp.get(), filename, target.get());
537     }
538     return target;
539 }
540 
541 bool
542 SBDebugger::DeleteTarget (lldb::SBTarget &target)
543 {
544     bool result = false;
545     if (m_opaque_sp)
546     {
547         // No need to lock, the target list is thread safe
548         result = m_opaque_sp->GetTargetList().DeleteTarget (target.m_opaque_sp);
549     }
550 
551     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
552     if (log)
553     {
554         log->Printf ("SBDebugger(%p)::DeleteTarget (SBTarget(%p)) => %i", m_opaque_sp.get(), target.m_opaque_sp.get(), result);
555     }
556 
557     return result;
558 }
559 SBTarget
560 SBDebugger::GetTargetAtIndex (uint32_t idx)
561 {
562     SBTarget sb_target;
563     if (m_opaque_sp)
564     {
565         // No need to lock, the target list is thread safe
566         sb_target.reset(m_opaque_sp->GetTargetList().GetTargetAtIndex (idx));
567     }
568     return sb_target;
569 }
570 
571 SBTarget
572 SBDebugger::FindTargetWithProcessID (pid_t pid)
573 {
574     SBTarget sb_target;
575     if (m_opaque_sp)
576     {
577         // No need to lock, the target list is thread safe
578         sb_target.reset(m_opaque_sp->GetTargetList().FindTargetWithProcessID (pid));
579     }
580     return sb_target;
581 }
582 
583 SBTarget
584 SBDebugger::FindTargetWithFileAndArch (const char *filename, const char *arch_name)
585 {
586     SBTarget sb_target;
587     if (m_opaque_sp && filename && filename[0])
588     {
589         // No need to lock, the target list is thread safe
590         ArchSpec arch (arch_name, m_opaque_sp->GetPlatformList().GetSelectedPlatform().get());
591         TargetSP target_sp (m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture (FileSpec(filename, false), arch_name ? &arch : NULL));
592         sb_target.reset(target_sp);
593     }
594     return sb_target;
595 }
596 
597 SBTarget
598 SBDebugger::FindTargetWithLLDBProcess (const ProcessSP &process_sp)
599 {
600     SBTarget sb_target;
601     if (m_opaque_sp)
602     {
603         // No need to lock, the target list is thread safe
604         sb_target.reset(m_opaque_sp->GetTargetList().FindTargetWithProcess (process_sp.get()));
605     }
606     return sb_target;
607 }
608 
609 
610 uint32_t
611 SBDebugger::GetNumTargets ()
612 {
613     if (m_opaque_sp)
614     {
615         // No need to lock, the target list is thread safe
616         return m_opaque_sp->GetTargetList().GetNumTargets ();
617     }
618     return 0;
619 }
620 
621 SBTarget
622 SBDebugger::GetSelectedTarget ()
623 {
624     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
625 
626     SBTarget sb_target;
627     if (m_opaque_sp)
628     {
629         // No need to lock, the target list is thread safe
630         sb_target.reset(m_opaque_sp->GetTargetList().GetSelectedTarget ());
631     }
632 
633     if (log)
634     {
635         SBStream sstr;
636         sb_target.GetDescription (sstr, eDescriptionLevelBrief);
637         log->Printf ("SBDebugger(%p)::GetSelectedTarget () => SBTarget(%p): %s", m_opaque_sp.get(),
638                      sb_target.get(), sstr.GetData());
639     }
640 
641     return sb_target;
642 }
643 
644 void
645 SBDebugger::DispatchInput (void *baton, const void *data, size_t data_len)
646 {
647     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
648 
649     if (log)
650         log->Printf ("SBDebugger(%p)::DispatchInput (baton=%p, data=\"%.*s\", size_t=%zu)", m_opaque_sp.get(),
651                      baton, (int) data_len, (const char *) data, data_len);
652 
653     if (m_opaque_sp)
654         m_opaque_sp->DispatchInput ((const char *) data, data_len);
655 }
656 
657 void
658 SBDebugger::DispatchInputInterrupt ()
659 {
660     if (m_opaque_sp)
661         m_opaque_sp->DispatchInputInterrupt ();
662 }
663 
664 void
665 SBDebugger::DispatchInputEndOfFile ()
666 {
667     if (m_opaque_sp)
668         m_opaque_sp->DispatchInputEndOfFile ();
669 }
670 
671 bool
672 SBDebugger::InputReaderIsTopReader (const lldb::SBInputReader &reader)
673 {
674     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
675 
676     if (log)
677         log->Printf ("SBDebugger(%p)::InputReaderIsTopReader (SBInputReader(%p))", m_opaque_sp.get(), &reader);
678 
679     if (m_opaque_sp && reader.IsValid())
680     {
681         InputReaderSP reader_sp (*reader);
682         return m_opaque_sp->InputReaderIsTopReader (reader_sp);
683     }
684 
685     return false;
686 }
687 
688 
689 void
690 SBDebugger::PushInputReader (SBInputReader &reader)
691 {
692     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
693 
694     if (log)
695         log->Printf ("SBDebugger(%p)::PushInputReader (SBInputReader(%p))", m_opaque_sp.get(), &reader);
696 
697     if (m_opaque_sp && reader.IsValid())
698     {
699         TargetSP target_sp (m_opaque_sp->GetSelectedTarget());
700         Mutex::Locker api_locker;
701         if (target_sp)
702             api_locker.Reset(target_sp->GetAPIMutex().GetMutex());
703         InputReaderSP reader_sp(*reader);
704         m_opaque_sp->PushInputReader (reader_sp);
705     }
706 }
707 
708 void
709 SBDebugger::NotifyTopInputReader (InputReaderAction notification)
710 {
711     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
712 
713     if (log)
714         log->Printf ("SBDebugger(%p)::NotifyTopInputReader (%d)", m_opaque_sp.get(), notification);
715 
716     if (m_opaque_sp)
717         m_opaque_sp->NotifyTopInputReader (notification);
718 }
719 
720 void
721 SBDebugger::reset (const DebuggerSP &debugger_sp)
722 {
723     m_opaque_sp = debugger_sp;
724 }
725 
726 Debugger *
727 SBDebugger::get () const
728 {
729     return m_opaque_sp.get();
730 }
731 
732 Debugger &
733 SBDebugger::ref () const
734 {
735     assert (m_opaque_sp.get());
736     return *m_opaque_sp;
737 }
738 
739 
740 SBDebugger
741 SBDebugger::FindDebuggerWithID (int id)
742 {
743     // No need to lock, the debugger list is thread safe
744     SBDebugger sb_debugger;
745     DebuggerSP debugger_sp = Debugger::FindDebuggerWithID (id);
746     if (debugger_sp)
747         sb_debugger.reset (debugger_sp);
748     return sb_debugger;
749 }
750 
751 const char *
752 SBDebugger::GetInstanceName()
753 {
754     if (m_opaque_sp)
755         return m_opaque_sp->GetInstanceName().AsCString();
756     else
757         return NULL;
758 }
759 
760 SBError
761 SBDebugger::SetInternalVariable (const char *var_name, const char *value, const char *debugger_instance_name)
762 {
763     UserSettingsControllerSP root_settings_controller = Debugger::GetSettingsController();
764 
765     Error err = root_settings_controller->SetVariable (var_name,
766                                                        value,
767                                                        eVarSetOperationAssign,
768                                                        true,
769                                                        debugger_instance_name);
770     SBError sb_error;
771     sb_error.SetError (err);
772 
773     return sb_error;
774 }
775 
776 SBStringList
777 SBDebugger::GetInternalVariableValue (const char *var_name, const char *debugger_instance_name)
778 {
779     SBStringList ret_value;
780     SettableVariableType var_type;
781     Error err;
782 
783     UserSettingsControllerSP root_settings_controller = Debugger::GetSettingsController();
784 
785     StringList value = root_settings_controller->GetVariable (var_name, var_type, debugger_instance_name, err);
786 
787     if (err.Success())
788     {
789         for (unsigned i = 0; i != value.GetSize(); ++i)
790             ret_value.AppendString (value.GetStringAtIndex(i));
791     }
792     else
793     {
794         ret_value.AppendString (err.AsCString());
795     }
796 
797 
798     return ret_value;
799 }
800 
801 uint32_t
802 SBDebugger::GetTerminalWidth () const
803 {
804     if (m_opaque_sp)
805         return m_opaque_sp->GetTerminalWidth ();
806     return 0;
807 }
808 
809 void
810 SBDebugger::SetTerminalWidth (uint32_t term_width)
811 {
812     if (m_opaque_sp)
813         m_opaque_sp->SetTerminalWidth (term_width);
814 }
815 
816 const char *
817 SBDebugger::GetPrompt() const
818 {
819     LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
820 
821     if (log)
822         log->Printf ("SBDebugger(%p)::GetPrompt () => \"%s\"", m_opaque_sp.get(),
823                      (m_opaque_sp ? m_opaque_sp->GetPrompt() : ""));
824 
825     if (m_opaque_sp)
826         return m_opaque_sp->GetPrompt ();
827     return 0;
828 }
829 
830 void
831 SBDebugger::SetPrompt (const char *prompt)
832 {
833     if (m_opaque_sp)
834         m_opaque_sp->SetPrompt (prompt);
835 }
836 
837 
838 ScriptLanguage
839 SBDebugger::GetScriptLanguage() const
840 {
841     if (m_opaque_sp)
842         return m_opaque_sp->GetScriptLanguage ();
843     return eScriptLanguageNone;
844 }
845 
846 void
847 SBDebugger::SetScriptLanguage (ScriptLanguage script_lang)
848 {
849     if (m_opaque_sp)
850     {
851         m_opaque_sp->SetScriptLanguage (script_lang);
852     }
853 }
854 
855 bool
856 SBDebugger::SetUseExternalEditor (bool value)
857 {
858     if (m_opaque_sp)
859         return m_opaque_sp->SetUseExternalEditor (value);
860     return false;
861 }
862 
863 bool
864 SBDebugger::GetUseExternalEditor ()
865 {
866     if (m_opaque_sp)
867         return m_opaque_sp->GetUseExternalEditor ();
868     return false;
869 }
870 
871 bool
872 SBDebugger::GetDescription (SBStream &description)
873 {
874     if (m_opaque_sp)
875     {
876         const char *name = m_opaque_sp->GetInstanceName().AsCString();
877         user_id_t id = m_opaque_sp->GetID();
878         description.Printf ("Debugger (instance: \"%s\", id: %d)", name, id);
879     }
880     else
881         description.Printf ("No value");
882 
883     return true;
884 }
885 
886 user_id_t
887 SBDebugger::GetID()
888 {
889     if (m_opaque_sp)
890         return m_opaque_sp->GetID();
891     return LLDB_INVALID_UID;
892 }
893 
894 
895 SBError
896 SBDebugger::SetCurrentPlatform (const char *platform_name)
897 {
898     SBError sb_error;
899     if (m_opaque_sp)
900     {
901         PlatformSP platform_sp (Platform::Create (platform_name, sb_error.ref()));
902 
903         if (platform_sp)
904         {
905             bool make_selected = true;
906             m_opaque_sp->GetPlatformList().Append (platform_sp, make_selected);
907         }
908     }
909     return sb_error;
910 }
911 
912 bool
913 SBDebugger::SetCurrentPlatformSDKRoot (const char *sysroot)
914 {
915     if (m_opaque_sp)
916     {
917         PlatformSP platform_sp (m_opaque_sp->GetPlatformList().GetSelectedPlatform());
918 
919         if (platform_sp)
920         {
921             platform_sp->SetSDKRootDirectory (ConstString (sysroot));
922             return true;
923         }
924     }
925     return false;
926 }
927 
928 bool
929 SBDebugger::GetCloseInputOnEOF () const
930 {
931     if (m_opaque_sp)
932         return m_opaque_sp->GetCloseInputOnEOF ();
933     return false;
934 }
935 
936 void
937 SBDebugger::SetCloseInputOnEOF (bool b)
938 {
939     if (m_opaque_sp)
940         m_opaque_sp->SetCloseInputOnEOF (b);
941 }
942