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