1 //===-- Debugger.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/lldb-private.h"
11 #include "lldb/Core/ConnectionFileDescriptor.h"
12 #include "lldb/Core/Debugger.h"
13 #include "lldb/Core/InputReader.h"
14 #include "lldb/Core/State.h"
15 #include "lldb/Core/StreamString.h"
16 #include "lldb/Core/Timer.h"
17 #include "lldb/Host/Terminal.h"
18 #include "lldb/Interpreter/CommandInterpreter.h"
19 #include "lldb/Target/TargetList.h"
20 #include "lldb/Target/Process.h"
21 #include "lldb/Target/RegisterContext.h"
22 #include "lldb/Target/StopInfo.h"
23 #include "lldb/Target/Thread.h"
24 
25 
26 using namespace lldb;
27 using namespace lldb_private;
28 
29 
30 static uint32_t g_shared_debugger_refcount = 0;
31 static lldb::user_id_t g_unique_id = 1;
32 
33 #pragma mark Static Functions
34 
35 static Mutex &
36 GetDebuggerListMutex ()
37 {
38     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
39     return g_mutex;
40 }
41 
42 typedef std::vector<DebuggerSP> DebuggerList;
43 
44 static DebuggerList &
45 GetDebuggerList()
46 {
47     // hide the static debugger list inside a singleton accessor to avoid
48     // global init contructors
49     static DebuggerList g_list;
50     return g_list;
51 }
52 
53 
54 #pragma mark Debugger
55 
56 UserSettingsControllerSP &
57 Debugger::GetSettingsController ()
58 {
59     static UserSettingsControllerSP g_settings_controller;
60     return g_settings_controller;
61 }
62 
63 int
64 Debugger::TestDebuggerRefCount ()
65 {
66     return g_shared_debugger_refcount;
67 }
68 
69 void
70 Debugger::Initialize ()
71 {
72     if (g_shared_debugger_refcount == 0)
73     {
74         lldb_private::Initialize();
75     }
76     g_shared_debugger_refcount++;
77 
78 }
79 
80 void
81 Debugger::Terminate ()
82 {
83     if (g_shared_debugger_refcount > 0)
84     {
85         g_shared_debugger_refcount--;
86         if (g_shared_debugger_refcount == 0)
87         {
88             lldb_private::WillTerminate();
89             lldb_private::Terminate();
90 
91             // Clear our master list of debugger objects
92             Mutex::Locker locker (GetDebuggerListMutex ());
93             GetDebuggerList().clear();
94         }
95     }
96 }
97 
98 void
99 Debugger::SettingsInitialize ()
100 {
101     static bool g_initialized = false;
102 
103     if (!g_initialized)
104     {
105         g_initialized = true;
106         UserSettingsControllerSP &usc = GetSettingsController();
107         usc.reset (new SettingsController);
108         UserSettingsController::InitializeSettingsController (usc,
109                                                               SettingsController::global_settings_table,
110                                                               SettingsController::instance_settings_table);
111         // Now call SettingsInitialize for each settings 'child' of Debugger
112         Target::SettingsInitialize ();
113     }
114 }
115 
116 void
117 Debugger::SettingsTerminate ()
118 {
119 
120     // Must call SettingsTerminate() for each settings 'child' of Debugger, before terminating the Debugger's
121     // Settings.
122 
123     Target::SettingsTerminate ();
124 
125     // Now terminate the Debugger Settings.
126 
127     UserSettingsControllerSP &usc = GetSettingsController();
128     UserSettingsController::FinalizeSettingsController (usc);
129     usc.reset();
130 }
131 
132 DebuggerSP
133 Debugger::CreateInstance ()
134 {
135     DebuggerSP debugger_sp (new Debugger);
136     // Scope for locker
137     {
138         Mutex::Locker locker (GetDebuggerListMutex ());
139         GetDebuggerList().push_back(debugger_sp);
140     }
141     return debugger_sp;
142 }
143 
144 void
145 Debugger::Destroy (lldb::DebuggerSP &debugger_sp)
146 {
147     if (debugger_sp.get() == NULL)
148         return;
149 
150     Mutex::Locker locker (GetDebuggerListMutex ());
151     DebuggerList &debugger_list = GetDebuggerList ();
152     DebuggerList::iterator pos, end = debugger_list.end();
153     for (pos = debugger_list.begin (); pos != end; ++pos)
154     {
155         if ((*pos).get() == debugger_sp.get())
156         {
157             debugger_list.erase (pos);
158             return;
159         }
160     }
161 
162 }
163 
164 lldb::DebuggerSP
165 Debugger::GetSP ()
166 {
167     lldb::DebuggerSP debugger_sp;
168 
169     Mutex::Locker locker (GetDebuggerListMutex ());
170     DebuggerList &debugger_list = GetDebuggerList();
171     DebuggerList::iterator pos, end = debugger_list.end();
172     for (pos = debugger_list.begin(); pos != end; ++pos)
173     {
174         if ((*pos).get() == this)
175         {
176             debugger_sp = *pos;
177             break;
178         }
179     }
180     return debugger_sp;
181 }
182 
183 lldb::DebuggerSP
184 Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
185 {
186     lldb::DebuggerSP debugger_sp;
187 
188     Mutex::Locker locker (GetDebuggerListMutex ());
189     DebuggerList &debugger_list = GetDebuggerList();
190     DebuggerList::iterator pos, end = debugger_list.end();
191 
192     for (pos = debugger_list.begin(); pos != end; ++pos)
193     {
194         if ((*pos).get()->m_instance_name == instance_name)
195         {
196             debugger_sp = *pos;
197             break;
198         }
199     }
200     return debugger_sp;
201 }
202 
203 TargetSP
204 Debugger::FindTargetWithProcessID (lldb::pid_t pid)
205 {
206     lldb::TargetSP target_sp;
207     Mutex::Locker locker (GetDebuggerListMutex ());
208     DebuggerList &debugger_list = GetDebuggerList();
209     DebuggerList::iterator pos, end = debugger_list.end();
210     for (pos = debugger_list.begin(); pos != end; ++pos)
211     {
212         target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
213         if (target_sp)
214             break;
215     }
216     return target_sp;
217 }
218 
219 
220 Debugger::Debugger () :
221     UserID (g_unique_id++),
222     DebuggerInstanceSettings (*GetSettingsController()),
223     m_input_comm("debugger.input"),
224     m_input_file (),
225     m_output_file (),
226     m_error_file (),
227     m_target_list (),
228     m_platform_list (),
229     m_listener ("lldb.Debugger"),
230     m_source_manager (),
231     m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
232     m_input_readers (),
233     m_input_reader_data ()
234 {
235     m_input_comm.SetCloseOnEOF(false);
236     m_command_interpreter_ap->Initialize ();
237     // Always add our default platform to the platform list
238     PlatformSP default_platform_sp (Platform::GetDefaultPlatform());
239     assert (default_platform_sp.get());
240     m_platform_list.Append (default_platform_sp, true);
241 }
242 
243 Debugger::~Debugger ()
244 {
245     CleanUpInputReaders();
246     int num_targets = m_target_list.GetNumTargets();
247     for (int i = 0; i < num_targets; i++)
248     {
249         ProcessSP process_sp (m_target_list.GetTargetAtIndex (i)->GetProcessSP());
250         if (process_sp)
251             process_sp->Destroy();
252     }
253     DisconnectInput();
254 }
255 
256 
257 bool
258 Debugger::GetAsyncExecution ()
259 {
260     return !m_command_interpreter_ap->GetSynchronous();
261 }
262 
263 void
264 Debugger::SetAsyncExecution (bool async_execution)
265 {
266     m_command_interpreter_ap->SetSynchronous (!async_execution);
267 }
268 
269 
270 void
271 Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
272 {
273     File &in_file = GetInputFile();
274     in_file.SetStream (fh, tranfer_ownership);
275     if (in_file.IsValid() == false)
276         in_file.SetStream (stdin, true);
277 
278     // Disconnect from any old connection if we had one
279     m_input_comm.Disconnect ();
280     m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), true));
281     m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this);
282 
283     Error error;
284     if (m_input_comm.StartReadThread (&error) == false)
285     {
286         File &err_file = GetErrorFile();
287 
288         err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error");
289         exit(1);
290     }
291 }
292 
293 void
294 Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
295 {
296     File &out_file = GetOutputFile();
297     out_file.SetStream (fh, tranfer_ownership);
298     if (out_file.IsValid() == false)
299         out_file.SetStream (stdout, false);
300 
301     GetCommandInterpreter().GetScriptInterpreter()->ResetOutputFileHandle (fh);
302 }
303 
304 void
305 Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
306 {
307     File &err_file = GetErrorFile();
308     err_file.SetStream (fh, tranfer_ownership);
309     if (err_file.IsValid() == false)
310         err_file.SetStream (stderr, false);
311 }
312 
313 ExecutionContext
314 Debugger::GetSelectedExecutionContext ()
315 {
316     ExecutionContext exe_ctx;
317     exe_ctx.Clear();
318 
319     lldb::TargetSP target_sp = GetSelectedTarget();
320     exe_ctx.target = target_sp.get();
321 
322     if (target_sp)
323     {
324         exe_ctx.process = target_sp->GetProcessSP().get();
325         if (exe_ctx.process && exe_ctx.process->IsRunning() == false)
326         {
327             exe_ctx.thread = exe_ctx.process->GetThreadList().GetSelectedThread().get();
328             if (exe_ctx.thread == NULL)
329                 exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
330             if (exe_ctx.thread)
331             {
332                 exe_ctx.frame = exe_ctx.thread->GetSelectedFrame().get();
333                 if (exe_ctx.frame == NULL)
334                     exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex (0).get();
335             }
336         }
337     }
338     return exe_ctx;
339 
340 }
341 
342 InputReaderSP
343 Debugger::GetCurrentInputReader ()
344 {
345     InputReaderSP reader_sp;
346 
347     if (!m_input_readers.empty())
348     {
349         // Clear any finished readers from the stack
350         while (CheckIfTopInputReaderIsDone()) ;
351 
352         if (!m_input_readers.empty())
353             reader_sp = m_input_readers.top();
354     }
355 
356     return reader_sp;
357 }
358 
359 void
360 Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len)
361 {
362     if (bytes_len > 0)
363         ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
364     else
365         ((Debugger *)baton)->DispatchInputEndOfFile ();
366 }
367 
368 
369 void
370 Debugger::DispatchInput (const char *bytes, size_t bytes_len)
371 {
372     if (bytes == NULL || bytes_len == 0)
373         return;
374 
375     WriteToDefaultReader (bytes, bytes_len);
376 }
377 
378 void
379 Debugger::DispatchInputInterrupt ()
380 {
381     m_input_reader_data.clear();
382 
383     InputReaderSP reader_sp (GetCurrentInputReader ());
384     if (reader_sp)
385     {
386         reader_sp->Notify (eInputReaderInterrupt);
387 
388         // If notifying the reader of the interrupt finished the reader, we should pop it off the stack.
389         while (CheckIfTopInputReaderIsDone ()) ;
390     }
391 }
392 
393 void
394 Debugger::DispatchInputEndOfFile ()
395 {
396     m_input_reader_data.clear();
397 
398     InputReaderSP reader_sp (GetCurrentInputReader ());
399     if (reader_sp)
400     {
401         reader_sp->Notify (eInputReaderEndOfFile);
402 
403         // If notifying the reader of the end-of-file finished the reader, we should pop it off the stack.
404         while (CheckIfTopInputReaderIsDone ()) ;
405     }
406 }
407 
408 void
409 Debugger::CleanUpInputReaders ()
410 {
411     m_input_reader_data.clear();
412 
413     // The bottom input reader should be the main debugger input reader.  We do not want to close that one here.
414     while (m_input_readers.size() > 1)
415     {
416         InputReaderSP reader_sp (GetCurrentInputReader ());
417         if (reader_sp)
418         {
419             reader_sp->Notify (eInputReaderEndOfFile);
420             reader_sp->SetIsDone (true);
421         }
422     }
423 }
424 
425 void
426 Debugger::NotifyTopInputReader (InputReaderAction notification)
427 {
428     InputReaderSP reader_sp (GetCurrentInputReader());
429     if (reader_sp)
430 	{
431         reader_sp->Notify (notification);
432 
433         // Flush out any input readers that are done.
434         while (CheckIfTopInputReaderIsDone ())
435             /* Do nothing. */;
436     }
437 }
438 
439 void
440 Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
441 {
442     if (bytes && bytes_len)
443         m_input_reader_data.append (bytes, bytes_len);
444 
445     if (m_input_reader_data.empty())
446         return;
447 
448     while (!m_input_readers.empty() && !m_input_reader_data.empty())
449     {
450         // Get the input reader from the top of the stack
451         InputReaderSP reader_sp (GetCurrentInputReader ());
452         if (!reader_sp)
453             break;
454 
455         size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(),
456                                                           m_input_reader_data.size());
457         if (bytes_handled)
458         {
459             m_input_reader_data.erase (0, bytes_handled);
460         }
461         else
462         {
463             // No bytes were handled, we might not have reached our
464             // granularity, just return and wait for more data
465             break;
466         }
467     }
468 
469     // Flush out any input readers that are done.
470     while (CheckIfTopInputReaderIsDone ())
471         /* Do nothing. */;
472 
473 }
474 
475 void
476 Debugger::PushInputReader (const InputReaderSP& reader_sp)
477 {
478     if (!reader_sp)
479         return;
480 
481     // Deactivate the old top reader
482     InputReaderSP top_reader_sp (GetCurrentInputReader ());
483 
484     if (top_reader_sp)
485         top_reader_sp->Notify (eInputReaderDeactivate);
486 
487     m_input_readers.push (reader_sp);
488     reader_sp->Notify (eInputReaderActivate);
489     ActivateInputReader (reader_sp);
490 }
491 
492 bool
493 Debugger::PopInputReader (const lldb::InputReaderSP& pop_reader_sp)
494 {
495     bool result = false;
496 
497     // The reader on the stop of the stack is done, so let the next
498     // read on the stack referesh its prompt and if there is one...
499     if (!m_input_readers.empty())
500     {
501         // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
502         InputReaderSP reader_sp(m_input_readers.top());
503 
504         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
505         {
506             m_input_readers.pop ();
507             reader_sp->Notify (eInputReaderDeactivate);
508             reader_sp->Notify (eInputReaderDone);
509             result = true;
510 
511             if (!m_input_readers.empty())
512             {
513                 reader_sp = m_input_readers.top();
514                 if (reader_sp)
515                 {
516                     ActivateInputReader (reader_sp);
517                     reader_sp->Notify (eInputReaderReactivate);
518                 }
519             }
520         }
521     }
522     return result;
523 }
524 
525 bool
526 Debugger::CheckIfTopInputReaderIsDone ()
527 {
528     bool result = false;
529     if (!m_input_readers.empty())
530     {
531         // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
532         InputReaderSP reader_sp(m_input_readers.top());
533 
534         if (reader_sp && reader_sp->IsDone())
535         {
536             result = true;
537             PopInputReader (reader_sp);
538         }
539     }
540     return result;
541 }
542 
543 void
544 Debugger::ActivateInputReader (const InputReaderSP &reader_sp)
545 {
546     int input_fd = m_input_file.GetFile().GetDescriptor();
547 
548     if (input_fd >= 0)
549     {
550         Terminal tty(input_fd);
551 
552         tty.SetEcho(reader_sp->GetEcho());
553 
554         switch (reader_sp->GetGranularity())
555         {
556         case eInputReaderGranularityByte:
557         case eInputReaderGranularityWord:
558             tty.SetCanonical (false);
559             break;
560 
561         case eInputReaderGranularityLine:
562         case eInputReaderGranularityAll:
563             tty.SetCanonical (true);
564             break;
565 
566         default:
567             break;
568         }
569     }
570 }
571 
572 DebuggerSP
573 Debugger::FindDebuggerWithID (lldb::user_id_t id)
574 {
575     lldb::DebuggerSP debugger_sp;
576 
577     Mutex::Locker locker (GetDebuggerListMutex ());
578     DebuggerList &debugger_list = GetDebuggerList();
579     DebuggerList::iterator pos, end = debugger_list.end();
580     for (pos = debugger_list.begin(); pos != end; ++pos)
581     {
582         if ((*pos).get()->GetID() == id)
583         {
584             debugger_sp = *pos;
585             break;
586         }
587     }
588     return debugger_sp;
589 }
590 
591 static void
592 TestPromptFormats (StackFrame *frame)
593 {
594     if (frame == NULL)
595         return;
596 
597     StreamString s;
598     const char *prompt_format =
599     "{addr = '${addr}'\n}"
600     "{process.id = '${process.id}'\n}"
601     "{process.name = '${process.name}'\n}"
602     "{process.file.basename = '${process.file.basename}'\n}"
603     "{process.file.fullpath = '${process.file.fullpath}'\n}"
604     "{thread.id = '${thread.id}'\n}"
605     "{thread.index = '${thread.index}'\n}"
606     "{thread.name = '${thread.name}'\n}"
607     "{thread.queue = '${thread.queue}'\n}"
608     "{thread.stop-reason = '${thread.stop-reason}'\n}"
609     "{target.arch = '${target.arch}'\n}"
610     "{module.file.basename = '${module.file.basename}'\n}"
611     "{module.file.fullpath = '${module.file.fullpath}'\n}"
612     "{file.basename = '${file.basename}'\n}"
613     "{file.fullpath = '${file.fullpath}'\n}"
614     "{frame.index = '${frame.index}'\n}"
615     "{frame.pc = '${frame.pc}'\n}"
616     "{frame.sp = '${frame.sp}'\n}"
617     "{frame.fp = '${frame.fp}'\n}"
618     "{frame.flags = '${frame.flags}'\n}"
619     "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
620     "{frame.reg.rip = '${frame.reg.rip}'\n}"
621     "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
622     "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
623     "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
624     "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
625     "{frame.reg.carp = '${frame.reg.carp}'\n}"
626     "{function.id = '${function.id}'\n}"
627     "{function.name = '${function.name}'\n}"
628     "{function.addr-offset = '${function.addr-offset}'\n}"
629     "{function.line-offset = '${function.line-offset}'\n}"
630     "{function.pc-offset = '${function.pc-offset}'\n}"
631     "{line.file.basename = '${line.file.basename}'\n}"
632     "{line.file.fullpath = '${line.file.fullpath}'\n}"
633     "{line.number = '${line.number}'\n}"
634     "{line.start-addr = '${line.start-addr}'\n}"
635     "{line.end-addr = '${line.end-addr}'\n}"
636 ;
637 
638     SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
639     ExecutionContext exe_ctx;
640     frame->CalculateExecutionContext(exe_ctx);
641     const char *end = NULL;
642     if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, &end))
643     {
644         printf("%s\n", s.GetData());
645     }
646     else
647     {
648         printf ("error: at '%s'\n", end);
649         printf ("what we got: %s\n", s.GetData());
650     }
651 }
652 
653 bool
654 Debugger::FormatPrompt
655 (
656     const char *format,
657     const SymbolContext *sc,
658     const ExecutionContext *exe_ctx,
659     const Address *addr,
660     Stream &s,
661     const char **end
662 )
663 {
664     bool success = true;
665     const char *p;
666     for (p = format; *p != '\0'; ++p)
667     {
668         size_t non_special_chars = ::strcspn (p, "${}\\");
669         if (non_special_chars > 0)
670         {
671             if (success)
672                 s.Write (p, non_special_chars);
673             p += non_special_chars;
674         }
675 
676         if (*p == '\0')
677         {
678             break;
679         }
680         else if (*p == '{')
681         {
682             // Start a new scope that must have everything it needs if it is to
683             // to make it into the final output stream "s". If you want to make
684             // a format that only prints out the function or symbol name if there
685             // is one in the symbol context you can use:
686             //      "{function =${function.name}}"
687             // The first '{' starts a new scope that end with the matching '}' at
688             // the end of the string. The contents "function =${function.name}"
689             // will then be evaluated and only be output if there is a function
690             // or symbol with a valid name.
691             StreamString sub_strm;
692 
693             ++p;  // Skip the '{'
694 
695             if (FormatPrompt (p, sc, exe_ctx, addr, sub_strm, &p))
696             {
697                 // The stream had all it needed
698                 s.Write(sub_strm.GetData(), sub_strm.GetSize());
699             }
700             if (*p != '}')
701             {
702                 success = false;
703                 break;
704             }
705         }
706         else if (*p == '}')
707         {
708             // End of a enclosing scope
709             break;
710         }
711         else if (*p == '$')
712         {
713             // We have a prompt variable to print
714             ++p;
715             if (*p == '{')
716             {
717                 ++p;
718                 const char *var_name_begin = p;
719                 const char *var_name_end = ::strchr (p, '}');
720 
721                 if (var_name_end && var_name_begin < var_name_end)
722                 {
723                     // if we have already failed to parse, skip this variable
724                     if (success)
725                     {
726                         const char *cstr = NULL;
727                         Address format_addr;
728                         bool calculate_format_addr_function_offset = false;
729                         // Set reg_kind and reg_num to invalid values
730                         RegisterKind reg_kind = kNumRegisterKinds;
731                         uint32_t reg_num = LLDB_INVALID_REGNUM;
732                         FileSpec format_file_spec;
733                         const RegisterInfo *reg_info = NULL;
734                         RegisterContext *reg_ctx = NULL;
735 
736                         // Each variable must set success to true below...
737                         bool var_success = false;
738                         switch (var_name_begin[0])
739                         {
740                         case 'a':
741                             if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0)
742                             {
743                                 if (addr && addr->IsValid())
744                                 {
745                                     var_success = true;
746                                     format_addr = *addr;
747                                 }
748                             }
749                             break;
750 
751                         case 'p':
752                             if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0)
753                             {
754                                 if (exe_ctx && exe_ctx->process != NULL)
755                                 {
756                                     var_name_begin += ::strlen ("process.");
757                                     if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
758                                     {
759                                         s.Printf("%i", exe_ctx->process->GetID());
760                                         var_success = true;
761                                     }
762                                     else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) ||
763                                              (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) ||
764                                              (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0))
765                                     {
766                                         ModuleSP exe_module_sp (exe_ctx->process->GetTarget().GetExecutableModule());
767                                         if (exe_module_sp)
768                                         {
769                                             if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
770                                             {
771                                                 format_file_spec.GetFilename() = exe_module_sp->GetFileSpec().GetFilename();
772                                                 var_success = format_file_spec;
773                                             }
774                                             else
775                                             {
776                                                 format_file_spec = exe_module_sp->GetFileSpec();
777                                                 var_success = format_file_spec;
778                                             }
779                                         }
780                                     }
781                                 }
782                             }
783                             break;
784 
785                         case 't':
786                             if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0)
787                             {
788                                 if (exe_ctx && exe_ctx->thread)
789                                 {
790                                     var_name_begin += ::strlen ("thread.");
791                                     if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
792                                     {
793                                         s.Printf("0x%4.4x", exe_ctx->thread->GetID());
794                                         var_success = true;
795                                     }
796                                     else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
797                                     {
798                                         s.Printf("%u", exe_ctx->thread->GetIndexID());
799                                         var_success = true;
800                                     }
801                                     else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
802                                     {
803                                         cstr = exe_ctx->thread->GetName();
804                                         var_success = cstr && cstr[0];
805                                         if (var_success)
806                                             s.PutCString(cstr);
807                                     }
808                                     else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0)
809                                     {
810                                         cstr = exe_ctx->thread->GetQueueName();
811                                         var_success = cstr && cstr[0];
812                                         if (var_success)
813                                             s.PutCString(cstr);
814                                     }
815                                     else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0)
816                                     {
817                                         StopInfoSP stop_info_sp = exe_ctx->thread->GetStopInfo ();
818                                         if (stop_info_sp)
819                                         {
820                                             cstr = stop_info_sp->GetDescription();
821                                             if (cstr && cstr[0])
822                                             {
823                                                 s.PutCString(cstr);
824                                                 var_success = true;
825                                             }
826                                         }
827                                     }
828                                 }
829                             }
830                             else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0)
831                             {
832                                 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
833                                 if (target)
834                                 {
835                                     var_name_begin += ::strlen ("target.");
836                                     if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0)
837                                     {
838                                         ArchSpec arch (target->GetArchitecture ());
839                                         if (arch.IsValid())
840                                         {
841                                             s.PutCString (arch.GetArchitectureName());
842                                             var_success = true;
843                                         }
844                                     }
845                                 }
846                             }
847                             break;
848 
849 
850                         case 'm':
851                             if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0)
852                             {
853                                 if (sc && sc->module_sp.get())
854                                 {
855                                     Module *module = sc->module_sp.get();
856                                     var_name_begin += ::strlen ("module.");
857 
858                                     if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
859                                     {
860                                         if (module->GetFileSpec())
861                                         {
862                                             var_name_begin += ::strlen ("file.");
863 
864                                             if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
865                                             {
866                                                 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
867                                                 var_success = format_file_spec;
868                                             }
869                                             else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
870                                             {
871                                                 format_file_spec = module->GetFileSpec();
872                                                 var_success = format_file_spec;
873                                             }
874                                         }
875                                     }
876                                 }
877                             }
878                             break;
879 
880 
881                         case 'f':
882                             if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
883                             {
884                                 if (sc && sc->comp_unit != NULL)
885                                 {
886                                     var_name_begin += ::strlen ("file.");
887 
888                                     if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
889                                     {
890                                         format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
891                                         var_success = format_file_spec;
892                                     }
893                                     else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
894                                     {
895                                         format_file_spec = *sc->comp_unit;
896                                         var_success = format_file_spec;
897                                     }
898                                 }
899                             }
900                             else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0)
901                             {
902                                 if (exe_ctx && exe_ctx->frame)
903                                 {
904                                     var_name_begin += ::strlen ("frame.");
905                                     if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
906                                     {
907                                         s.Printf("%u", exe_ctx->frame->GetFrameIndex());
908                                         var_success = true;
909                                     }
910                                     else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0)
911                                     {
912                                         reg_kind = eRegisterKindGeneric;
913                                         reg_num = LLDB_REGNUM_GENERIC_PC;
914                                         var_success = true;
915                                     }
916                                     else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0)
917                                     {
918                                         reg_kind = eRegisterKindGeneric;
919                                         reg_num = LLDB_REGNUM_GENERIC_SP;
920                                         var_success = true;
921                                     }
922                                     else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0)
923                                     {
924                                         reg_kind = eRegisterKindGeneric;
925                                         reg_num = LLDB_REGNUM_GENERIC_FP;
926                                         var_success = true;
927                                     }
928                                     else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0)
929                                     {
930                                         reg_kind = eRegisterKindGeneric;
931                                         reg_num = LLDB_REGNUM_GENERIC_FLAGS;
932                                         var_success = true;
933                                     }
934                                     else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0)
935                                     {
936                                         reg_ctx = exe_ctx->frame->GetRegisterContext().get();
937                                         if (reg_ctx)
938                                         {
939                                             var_name_begin += ::strlen ("reg.");
940                                             if (var_name_begin < var_name_end)
941                                             {
942                                                 std::string reg_name (var_name_begin, var_name_end);
943                                                 reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
944                                                 if (reg_info)
945                                                     var_success = true;
946                                             }
947                                         }
948                                     }
949                                 }
950                             }
951                             else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0)
952                             {
953                                 if (sc && (sc->function != NULL || sc->symbol != NULL))
954                                 {
955                                     var_name_begin += ::strlen ("function.");
956                                     if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
957                                     {
958                                         if (sc->function)
959                                             s.Printf("function{0x%8.8x}", sc->function->GetID());
960                                         else
961                                             s.Printf("symbol[%u]", sc->symbol->GetID());
962 
963                                         var_success = true;
964                                     }
965                                     else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
966                                     {
967                                         if (sc->function)
968                                             cstr = sc->function->GetName().AsCString (NULL);
969                                         else if (sc->symbol)
970                                             cstr = sc->symbol->GetName().AsCString (NULL);
971                                         if (cstr)
972                                         {
973                                             s.PutCString(cstr);
974 
975                                             if (sc->block)
976                                             {
977                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
978                                                 if (inline_block)
979                                                 {
980                                                     const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
981                                                     if (inline_info)
982                                                     {
983                                                         s.PutCString(" [inlined] ");
984                                                         inline_info->GetName().Dump(&s);
985                                                     }
986                                                 }
987                                             }
988                                             var_success = true;
989                                         }
990                                     }
991                                     else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0)
992                                     {
993                                         var_success = addr != NULL;
994                                         if (var_success)
995                                         {
996                                             format_addr = *addr;
997                                             calculate_format_addr_function_offset = true;
998                                         }
999                                     }
1000                                     else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0)
1001                                     {
1002                                         var_success = sc->line_entry.range.GetBaseAddress().IsValid();
1003                                         if (var_success)
1004                                         {
1005                                             format_addr = sc->line_entry.range.GetBaseAddress();
1006                                             calculate_format_addr_function_offset = true;
1007                                         }
1008                                     }
1009                                     else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0)
1010                                     {
1011                                         var_success = exe_ctx->frame;
1012                                         if (var_success)
1013                                         {
1014                                             format_addr = exe_ctx->frame->GetFrameCodeAddress();
1015                                             calculate_format_addr_function_offset = true;
1016                                         }
1017                                     }
1018                                 }
1019                             }
1020                             break;
1021 
1022                         case 'l':
1023                             if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0)
1024                             {
1025                                 if (sc && sc->line_entry.IsValid())
1026                                 {
1027                                     var_name_begin += ::strlen ("line.");
1028                                     if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
1029                                     {
1030                                         var_name_begin += ::strlen ("file.");
1031 
1032                                         if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
1033                                         {
1034                                             format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
1035                                             var_success = format_file_spec;
1036                                         }
1037                                         else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
1038                                         {
1039                                             format_file_spec = sc->line_entry.file;
1040                                             var_success = format_file_spec;
1041                                         }
1042                                     }
1043                                     else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0)
1044                                     {
1045                                         var_success = true;
1046                                         s.Printf("%u", sc->line_entry.line);
1047                                     }
1048                                     else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) ||
1049                                              (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0))
1050                                     {
1051                                         var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
1052                                         if (var_success)
1053                                         {
1054                                             format_addr = sc->line_entry.range.GetBaseAddress();
1055                                             if (var_name_begin[0] == 'e')
1056                                                 format_addr.Slide (sc->line_entry.range.GetByteSize());
1057                                         }
1058                                     }
1059                                 }
1060                             }
1061                             break;
1062                         }
1063 
1064                         if (var_success)
1065                         {
1066                             // If format addr is valid, then we need to print an address
1067                             if (reg_num != LLDB_INVALID_REGNUM)
1068                             {
1069                                 // We have a register value to display...
1070                                 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
1071                                 {
1072                                     format_addr = exe_ctx->frame->GetFrameCodeAddress();
1073                                 }
1074                                 else
1075                                 {
1076                                     if (reg_ctx == NULL)
1077                                         reg_ctx = exe_ctx->frame->GetRegisterContext().get();
1078 
1079                                     if (reg_ctx)
1080                                     {
1081                                         if (reg_kind != kNumRegisterKinds)
1082                                             reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
1083                                         reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
1084                                         var_success = reg_info != NULL;
1085                                     }
1086                                 }
1087                             }
1088 
1089                             if (reg_info != NULL)
1090                             {
1091                                 DataExtractor reg_data;
1092                                 var_success = reg_ctx->ReadRegisterBytes (reg_info->kinds[eRegisterKindLLDB], reg_data);
1093                                 {
1094                                     reg_data.Dump(&s, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
1095                                 }
1096                             }
1097 
1098                             if (format_file_spec)
1099                             {
1100                                 s << format_file_spec;
1101                             }
1102 
1103                             // If format addr is valid, then we need to print an address
1104                             if (format_addr.IsValid())
1105                             {
1106                                 var_success = false;
1107 
1108                                 if (calculate_format_addr_function_offset)
1109                                 {
1110                                     Address func_addr;
1111 
1112                                     if (sc)
1113                                     {
1114                                         if (sc->function)
1115                                         {
1116                                             func_addr = sc->function->GetAddressRange().GetBaseAddress();
1117                                             if (sc->block)
1118                                             {
1119                                                 // Check to make sure we aren't in an inline
1120                                                 // function. If we are, use the inline block
1121                                                 // range that contains "format_addr" since
1122                                                 // blocks can be discontiguous.
1123                                                 Block *inline_block = sc->block->GetContainingInlinedBlock ();
1124                                                 AddressRange inline_range;
1125                                                 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
1126                                                     func_addr = inline_range.GetBaseAddress();
1127                                             }
1128                                         }
1129                                         else if (sc->symbol && sc->symbol->GetAddressRangePtr())
1130                                             func_addr = sc->symbol->GetAddressRangePtr()->GetBaseAddress();
1131                                     }
1132 
1133                                     if (func_addr.IsValid())
1134                                     {
1135                                         if (func_addr.GetSection() == format_addr.GetSection())
1136                                         {
1137                                             addr_t func_file_addr = func_addr.GetFileAddress();
1138                                             addr_t addr_file_addr = format_addr.GetFileAddress();
1139                                             if (addr_file_addr > func_file_addr)
1140                                                 s.Printf(" + %llu", addr_file_addr - func_file_addr);
1141                                             else if (addr_file_addr < func_file_addr)
1142                                                 s.Printf(" - %llu", func_file_addr - addr_file_addr);
1143                                             var_success = true;
1144                                         }
1145                                         else
1146                                         {
1147                                             Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
1148                                             if (target)
1149                                             {
1150                                                 addr_t func_load_addr = func_addr.GetLoadAddress (target);
1151                                                 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
1152                                                 if (addr_load_addr > func_load_addr)
1153                                                     s.Printf(" + %llu", addr_load_addr - func_load_addr);
1154                                                 else if (addr_load_addr < func_load_addr)
1155                                                     s.Printf(" - %llu", func_load_addr - addr_load_addr);
1156                                                 var_success = true;
1157                                             }
1158                                         }
1159                                     }
1160                                 }
1161                                 else
1162                                 {
1163                                     Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
1164                                     addr_t vaddr = LLDB_INVALID_ADDRESS;
1165                                     if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
1166                                         vaddr = format_addr.GetLoadAddress (target);
1167                                     if (vaddr == LLDB_INVALID_ADDRESS)
1168                                         vaddr = format_addr.GetFileAddress ();
1169 
1170                                     if (vaddr != LLDB_INVALID_ADDRESS)
1171                                     {
1172                                         int addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
1173                                         if (addr_width == 0)
1174                                             addr_width = 16;
1175                                         s.Printf("0x%*.*llx", addr_width, addr_width, vaddr);
1176                                         var_success = true;
1177                                     }
1178                                 }
1179                             }
1180                         }
1181 
1182                         if (var_success == false)
1183                             success = false;
1184                     }
1185                     p = var_name_end;
1186                 }
1187                 else
1188                     break;
1189             }
1190             else
1191             {
1192                 // We got a dollar sign with no '{' after it, it must just be a dollar sign
1193                 s.PutChar(*p);
1194             }
1195         }
1196         else if (*p == '\\')
1197         {
1198             ++p; // skip the slash
1199             switch (*p)
1200             {
1201             case 'a': s.PutChar ('\a'); break;
1202             case 'b': s.PutChar ('\b'); break;
1203             case 'f': s.PutChar ('\f'); break;
1204             case 'n': s.PutChar ('\n'); break;
1205             case 'r': s.PutChar ('\r'); break;
1206             case 't': s.PutChar ('\t'); break;
1207             case 'v': s.PutChar ('\v'); break;
1208             case '\'': s.PutChar ('\''); break;
1209             case '\\': s.PutChar ('\\'); break;
1210             case '0':
1211                 // 1 to 3 octal chars
1212                 {
1213                     // Make a string that can hold onto the initial zero char,
1214                     // up to 3 octal digits, and a terminating NULL.
1215                     char oct_str[5] = { 0, 0, 0, 0, 0 };
1216 
1217                     int i;
1218                     for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
1219                         oct_str[i] = p[i];
1220 
1221                     // We don't want to consume the last octal character since
1222                     // the main for loop will do this for us, so we advance p by
1223                     // one less than i (even if i is zero)
1224                     p += i - 1;
1225                     unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
1226                     if (octal_value <= UINT8_MAX)
1227                     {
1228                         char octal_char = octal_value;
1229                         s.Write (&octal_char, 1);
1230                     }
1231                 }
1232                 break;
1233 
1234             case 'x':
1235                 // hex number in the format
1236                 if (isxdigit(p[1]))
1237                 {
1238                     ++p;    // Skip the 'x'
1239 
1240                     // Make a string that can hold onto two hex chars plus a
1241                     // NULL terminator
1242                     char hex_str[3] = { 0,0,0 };
1243                     hex_str[0] = *p;
1244                     if (isxdigit(p[1]))
1245                     {
1246                         ++p; // Skip the first of the two hex chars
1247                         hex_str[1] = *p;
1248                     }
1249 
1250                     unsigned long hex_value = strtoul (hex_str, NULL, 16);
1251                     if (hex_value <= UINT8_MAX)
1252                         s.PutChar (hex_value);
1253                 }
1254                 else
1255                 {
1256                     s.PutChar('x');
1257                 }
1258                 break;
1259 
1260             default:
1261                 // Just desensitize any other character by just printing what
1262                 // came after the '\'
1263                 s << *p;
1264                 break;
1265 
1266             }
1267 
1268         }
1269     }
1270     if (end)
1271         *end = p;
1272     return success;
1273 }
1274 
1275 #pragma mark Debugger::SettingsController
1276 
1277 //--------------------------------------------------
1278 // class Debugger::SettingsController
1279 //--------------------------------------------------
1280 
1281 Debugger::SettingsController::SettingsController () :
1282     UserSettingsController ("", lldb::UserSettingsControllerSP())
1283 {
1284     m_default_settings.reset (new DebuggerInstanceSettings (*this, false,
1285                                                             InstanceSettings::GetDefaultName().AsCString()));
1286 }
1287 
1288 Debugger::SettingsController::~SettingsController ()
1289 {
1290 }
1291 
1292 
1293 lldb::InstanceSettingsSP
1294 Debugger::SettingsController::CreateInstanceSettings (const char *instance_name)
1295 {
1296     DebuggerInstanceSettings *new_settings = new DebuggerInstanceSettings (*GetSettingsController(),
1297                                                                            false, instance_name);
1298     lldb::InstanceSettingsSP new_settings_sp (new_settings);
1299     return new_settings_sp;
1300 }
1301 
1302 #pragma mark DebuggerInstanceSettings
1303 //--------------------------------------------------
1304 //  class DebuggerInstanceSettings
1305 //--------------------------------------------------
1306 
1307 DebuggerInstanceSettings::DebuggerInstanceSettings
1308 (
1309     UserSettingsController &owner,
1310     bool live_instance,
1311     const char *name
1312 ) :
1313     InstanceSettings (owner, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance),
1314     m_term_width (80),
1315     m_prompt (),
1316     m_frame_format (),
1317     m_thread_format (),
1318     m_script_lang (),
1319     m_use_external_editor (false),
1320     m_auto_confirm_on (false)
1321 {
1322     // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called
1323     // until the vtables for DebuggerInstanceSettings are properly set up, i.e. AFTER all the initializers.
1324     // For this reason it has to be called here, rather than in the initializer or in the parent constructor.
1325     // The same is true of CreateInstanceName().
1326 
1327     if (GetInstanceName() == InstanceSettings::InvalidName())
1328     {
1329         ChangeInstanceName (std::string (CreateInstanceName().AsCString()));
1330         m_owner.RegisterInstanceSettings (this);
1331     }
1332 
1333     if (live_instance)
1334     {
1335         const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
1336         CopyInstanceSettings (pending_settings, false);
1337     }
1338 }
1339 
1340 DebuggerInstanceSettings::DebuggerInstanceSettings (const DebuggerInstanceSettings &rhs) :
1341     InstanceSettings (*Debugger::GetSettingsController(), CreateInstanceName ().AsCString()),
1342     m_prompt (rhs.m_prompt),
1343     m_frame_format (rhs.m_frame_format),
1344     m_thread_format (rhs.m_thread_format),
1345     m_script_lang (rhs.m_script_lang),
1346     m_use_external_editor (rhs.m_use_external_editor),
1347     m_auto_confirm_on(rhs.m_auto_confirm_on)
1348 {
1349     const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
1350     CopyInstanceSettings (pending_settings, false);
1351     m_owner.RemovePendingSettings (m_instance_name);
1352 }
1353 
1354 DebuggerInstanceSettings::~DebuggerInstanceSettings ()
1355 {
1356 }
1357 
1358 DebuggerInstanceSettings&
1359 DebuggerInstanceSettings::operator= (const DebuggerInstanceSettings &rhs)
1360 {
1361     if (this != &rhs)
1362     {
1363         m_term_width = rhs.m_term_width;
1364         m_prompt = rhs.m_prompt;
1365         m_frame_format = rhs.m_frame_format;
1366         m_thread_format = rhs.m_thread_format;
1367         m_script_lang = rhs.m_script_lang;
1368         m_use_external_editor = rhs.m_use_external_editor;
1369         m_auto_confirm_on = rhs.m_auto_confirm_on;
1370     }
1371 
1372     return *this;
1373 }
1374 
1375 bool
1376 DebuggerInstanceSettings::ValidTermWidthValue (const char *value, Error err)
1377 {
1378     bool valid = false;
1379 
1380     // Verify we have a value string.
1381     if (value == NULL || value[0] == '\0')
1382     {
1383         err.SetErrorString ("Missing value. Can't set terminal width without a value.\n");
1384     }
1385     else
1386     {
1387         char *end = NULL;
1388         const uint32_t width = ::strtoul (value, &end, 0);
1389 
1390         if (end && end[0] == '\0')
1391         {
1392             if (width >= 10 && width <= 1024)
1393                 valid = true;
1394             else
1395                 err.SetErrorString ("Invalid term-width value; value must be between 10 and 1024.\n");
1396         }
1397         else
1398             err.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string.\n", value);
1399     }
1400 
1401     return valid;
1402 }
1403 
1404 
1405 void
1406 DebuggerInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name,
1407                                                           const char *index_value,
1408                                                           const char *value,
1409                                                           const ConstString &instance_name,
1410                                                           const SettingEntry &entry,
1411                                                           VarSetOperationType op,
1412                                                           Error &err,
1413                                                           bool pending)
1414 {
1415 
1416     if (var_name == TermWidthVarName())
1417     {
1418         if (ValidTermWidthValue (value, err))
1419         {
1420             m_term_width = ::strtoul (value, NULL, 0);
1421         }
1422     }
1423     else if (var_name == PromptVarName())
1424     {
1425         UserSettingsController::UpdateStringVariable (op, m_prompt, value, err);
1426         if (!pending)
1427         {
1428             // 'instance_name' is actually (probably) in the form '[<instance_name>]';  if so, we need to
1429             // strip off the brackets before passing it to BroadcastPromptChange.
1430 
1431             std::string tmp_instance_name (instance_name.AsCString());
1432             if ((tmp_instance_name[0] == '[')
1433                 && (tmp_instance_name[instance_name.GetLength() - 1] == ']'))
1434                 tmp_instance_name = tmp_instance_name.substr (1, instance_name.GetLength() - 2);
1435             ConstString new_name (tmp_instance_name.c_str());
1436 
1437             BroadcastPromptChange (new_name, m_prompt.c_str());
1438         }
1439     }
1440     else if (var_name == GetFrameFormatName())
1441     {
1442         UserSettingsController::UpdateStringVariable (op, m_frame_format, value, err);
1443     }
1444     else if (var_name == GetThreadFormatName())
1445     {
1446         UserSettingsController::UpdateStringVariable (op, m_thread_format, value, err);
1447     }
1448     else if (var_name == ScriptLangVarName())
1449     {
1450         bool success;
1451         m_script_lang = Args::StringToScriptLanguage (value, eScriptLanguageDefault,
1452                                                       &success);
1453     }
1454     else if (var_name == UseExternalEditorVarName ())
1455     {
1456         UserSettingsController::UpdateBooleanVariable (op, m_use_external_editor, value, false, err);
1457     }
1458     else if (var_name == AutoConfirmName ())
1459     {
1460         UserSettingsController::UpdateBooleanVariable (op, m_auto_confirm_on, value, false, err);
1461     }
1462 }
1463 
1464 bool
1465 DebuggerInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
1466                                                     const ConstString &var_name,
1467                                                     StringList &value,
1468                                                     Error *err)
1469 {
1470     if (var_name == PromptVarName())
1471     {
1472         value.AppendString (m_prompt.c_str(), m_prompt.size());
1473 
1474     }
1475     else if (var_name == ScriptLangVarName())
1476     {
1477         value.AppendString (ScriptInterpreter::LanguageToString (m_script_lang).c_str());
1478     }
1479     else if (var_name == TermWidthVarName())
1480     {
1481         StreamString width_str;
1482         width_str.Printf ("%d", m_term_width);
1483         value.AppendString (width_str.GetData());
1484     }
1485     else if (var_name == GetFrameFormatName ())
1486     {
1487         value.AppendString(m_frame_format.c_str(), m_frame_format.size());
1488     }
1489     else if (var_name == GetThreadFormatName ())
1490     {
1491         value.AppendString(m_thread_format.c_str(), m_thread_format.size());
1492     }
1493     else if (var_name == UseExternalEditorVarName())
1494     {
1495         if (m_use_external_editor)
1496             value.AppendString ("true");
1497         else
1498             value.AppendString ("false");
1499     }
1500     else if (var_name == AutoConfirmName())
1501     {
1502         if (m_auto_confirm_on)
1503             value.AppendString ("true");
1504         else
1505             value.AppendString ("false");
1506     }
1507     else
1508     {
1509         if (err)
1510             err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString());
1511         return false;
1512     }
1513     return true;
1514 }
1515 
1516 void
1517 DebuggerInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings,
1518                                                 bool pending)
1519 {
1520     if (new_settings.get() == NULL)
1521         return;
1522 
1523     DebuggerInstanceSettings *new_debugger_settings = (DebuggerInstanceSettings *) new_settings.get();
1524 
1525     m_prompt = new_debugger_settings->m_prompt;
1526     if (!pending)
1527     {
1528         // 'instance_name' is actually (probably) in the form '[<instance_name>]';  if so, we need to
1529         // strip off the brackets before passing it to BroadcastPromptChange.
1530 
1531         std::string tmp_instance_name (m_instance_name.AsCString());
1532         if ((tmp_instance_name[0] == '[')
1533             && (tmp_instance_name[m_instance_name.GetLength() - 1] == ']'))
1534             tmp_instance_name = tmp_instance_name.substr (1, m_instance_name.GetLength() - 2);
1535         ConstString new_name (tmp_instance_name.c_str());
1536 
1537         BroadcastPromptChange (new_name, m_prompt.c_str());
1538     }
1539     m_frame_format = new_debugger_settings->m_frame_format;
1540     m_thread_format = new_debugger_settings->m_thread_format;
1541     m_term_width = new_debugger_settings->m_term_width;
1542     m_script_lang = new_debugger_settings->m_script_lang;
1543     m_use_external_editor = new_debugger_settings->m_use_external_editor;
1544     m_auto_confirm_on = new_debugger_settings->m_auto_confirm_on;
1545 }
1546 
1547 
1548 bool
1549 DebuggerInstanceSettings::BroadcastPromptChange (const ConstString &instance_name, const char *new_prompt)
1550 {
1551     std::string tmp_prompt;
1552 
1553     if (new_prompt != NULL)
1554     {
1555         tmp_prompt = new_prompt ;
1556         int len = tmp_prompt.size();
1557         if (len > 1
1558             && (tmp_prompt[0] == '\'' || tmp_prompt[0] == '"')
1559             && (tmp_prompt[len-1] == tmp_prompt[0]))
1560         {
1561             tmp_prompt = tmp_prompt.substr(1,len-2);
1562         }
1563         len = tmp_prompt.size();
1564         if (tmp_prompt[len-1] != ' ')
1565             tmp_prompt.append(" ");
1566     }
1567     EventSP new_event_sp;
1568     new_event_sp.reset (new Event(CommandInterpreter::eBroadcastBitResetPrompt,
1569                                   new EventDataBytes (tmp_prompt.c_str())));
1570 
1571     if (instance_name.GetLength() != 0)
1572     {
1573         // Set prompt for a particular instance.
1574         Debugger *dbg = Debugger::FindDebuggerWithInstanceName (instance_name).get();
1575         if (dbg != NULL)
1576         {
1577             dbg->GetCommandInterpreter().BroadcastEvent (new_event_sp);
1578         }
1579     }
1580 
1581     return true;
1582 }
1583 
1584 const ConstString
1585 DebuggerInstanceSettings::CreateInstanceName ()
1586 {
1587     static int instance_count = 1;
1588     StreamString sstr;
1589 
1590     sstr.Printf ("debugger_%d", instance_count);
1591     ++instance_count;
1592 
1593     const ConstString ret_val (sstr.GetData());
1594 
1595     return ret_val;
1596 }
1597 
1598 const ConstString &
1599 DebuggerInstanceSettings::PromptVarName ()
1600 {
1601     static ConstString prompt_var_name ("prompt");
1602 
1603     return prompt_var_name;
1604 }
1605 
1606 const ConstString &
1607 DebuggerInstanceSettings::GetFrameFormatName ()
1608 {
1609     static ConstString prompt_var_name ("frame-format");
1610 
1611     return prompt_var_name;
1612 }
1613 
1614 const ConstString &
1615 DebuggerInstanceSettings::GetThreadFormatName ()
1616 {
1617     static ConstString prompt_var_name ("thread-format");
1618 
1619     return prompt_var_name;
1620 }
1621 
1622 const ConstString &
1623 DebuggerInstanceSettings::ScriptLangVarName ()
1624 {
1625     static ConstString script_lang_var_name ("script-lang");
1626 
1627     return script_lang_var_name;
1628 }
1629 
1630 const ConstString &
1631 DebuggerInstanceSettings::TermWidthVarName ()
1632 {
1633     static ConstString term_width_var_name ("term-width");
1634 
1635     return term_width_var_name;
1636 }
1637 
1638 const ConstString &
1639 DebuggerInstanceSettings::UseExternalEditorVarName ()
1640 {
1641     static ConstString use_external_editor_var_name ("use-external-editor");
1642 
1643     return use_external_editor_var_name;
1644 }
1645 
1646 const ConstString &
1647 DebuggerInstanceSettings::AutoConfirmName ()
1648 {
1649     static ConstString use_external_editor_var_name ("auto-confirm");
1650 
1651     return use_external_editor_var_name;
1652 }
1653 
1654 //--------------------------------------------------
1655 // SettingsController Variable Tables
1656 //--------------------------------------------------
1657 
1658 
1659 SettingEntry
1660 Debugger::SettingsController::global_settings_table[] =
1661 {
1662   //{ "var-name",    var-type,      "default", enum-table, init'd, hidden, "help-text"},
1663   // The Debugger level global table should always be empty; all Debugger settable variables should be instance
1664   // variables.
1665     {  NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
1666 };
1667 
1668 #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name}${function.pc-offset}}}"
1669 #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
1670 
1671 #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\
1672     "{, ${frame.pc}}"\
1673     MODULE_WITH_FUNC\
1674     FILE_AND_LINE\
1675     "{, stop reason = ${thread.stop-reason}}"\
1676     "\\n"
1677 
1678 //#define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\
1679 //    "{, ${frame.pc}}"\
1680 //    MODULE_WITH_FUNC\
1681 //    FILE_AND_LINE\
1682 //    "{, stop reason = ${thread.stop-reason}}"\
1683 //    "{, name = ${thread.name}}"\
1684 //    "{, queue = ${thread.queue}}"\
1685 //    "\\n"
1686 
1687 #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
1688     MODULE_WITH_FUNC\
1689     FILE_AND_LINE\
1690     "\\n"
1691 
1692 SettingEntry
1693 Debugger::SettingsController::instance_settings_table[] =
1694 {
1695 //  NAME                    Setting variable type   Default                 Enum  Init'd Hidden Help
1696 //  ======================= ======================= ======================  ====  ====== ====== ======================
1697 {   "frame-format",         eSetVarTypeString,      DEFAULT_FRAME_FORMAT,   NULL, false, false, "The default frame format string to use when displaying thread information." },
1698 {   "prompt",               eSetVarTypeString,      "(lldb) ",              NULL, false, false, "The debugger command line prompt displayed for the user." },
1699 {   "script-lang",          eSetVarTypeString,      "python",               NULL, false, false, "The script language to be used for evaluating user-written scripts." },
1700 {   "term-width",           eSetVarTypeInt,         "80"    ,               NULL, false, false, "The maximum number of columns to use for displaying text." },
1701 {   "thread-format",        eSetVarTypeString,      DEFAULT_THREAD_FORMAT,  NULL, false, false, "The default thread format string to use when displaying thread information." },
1702 {   "use-external-editor",  eSetVarTypeBoolean,        "false",                NULL, false, false, "Whether to use an external editor or not." },
1703 {   "auto-confirm",         eSetVarTypeBoolean,        "false",                NULL, false, false, "If true all confirmation prompts will receive their default reply." },
1704 {   NULL,                   eSetVarTypeNone,        NULL,                   NULL, false, false, NULL }
1705 };
1706