blob: b7be1715ca99a203fe65c7c4a1f4051725509b24 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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
Greg Clayton4a33d312011-06-23 17:59:56 +000010#include "lldb/Core/Debugger.h"
11
12#include <map>
13
Chris Lattner30fdc8d2010-06-08 16:52:24 +000014#include "lldb/lldb-private.h"
15#include "lldb/Core/ConnectionFileDescriptor.h"
Greg Clayton4a33d312011-06-23 17:59:56 +000016#include "lldb/Core/FormatManager.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017#include "lldb/Core/InputReader.h"
Greg Clayton7349bd92011-05-09 20:18:18 +000018#include "lldb/Core/RegisterValue.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Core/State.h"
Jim Ingham5b52f0c2011-06-02 23:58:26 +000020#include "lldb/Core/StreamAsynchronousIO.h"
Greg Clayton1b654882010-09-19 02:33:57 +000021#include "lldb/Core/StreamString.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Core/Timer.h"
Greg Claytona3406612011-02-07 23:24:47 +000023#include "lldb/Host/Terminal.h"
Greg Clayton66111032010-06-23 01:19:29 +000024#include "lldb/Interpreter/CommandInterpreter.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Target/TargetList.h"
26#include "lldb/Target/Process.h"
Greg Clayton1b654882010-09-19 02:33:57 +000027#include "lldb/Target/RegisterContext.h"
28#include "lldb/Target/StopInfo.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Target/Thread.h"
30
31
32using namespace lldb;
33using namespace lldb_private;
34
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035
Greg Clayton1b654882010-09-19 02:33:57 +000036static uint32_t g_shared_debugger_refcount = 0;
Caroline Ticeebc1bb22010-06-30 16:22:25 +000037static lldb::user_id_t g_unique_id = 1;
38
Greg Clayton1b654882010-09-19 02:33:57 +000039#pragma mark Static Functions
40
41static Mutex &
42GetDebuggerListMutex ()
43{
44 static Mutex g_mutex(Mutex::eMutexTypeRecursive);
45 return g_mutex;
46}
47
48typedef std::vector<DebuggerSP> DebuggerList;
49
50static DebuggerList &
51GetDebuggerList()
52{
53 // hide the static debugger list inside a singleton accessor to avoid
54 // global init contructors
55 static DebuggerList g_list;
56 return g_list;
57}
58
59
60#pragma mark Debugger
61
Greg Clayton99d0faf2010-11-18 23:32:35 +000062UserSettingsControllerSP &
63Debugger::GetSettingsController ()
64{
65 static UserSettingsControllerSP g_settings_controller;
66 return g_settings_controller;
67}
68
Caroline Tice2f88aad2011-01-14 00:29:16 +000069int
70Debugger::TestDebuggerRefCount ()
71{
72 return g_shared_debugger_refcount;
73}
74
Chris Lattner30fdc8d2010-06-08 16:52:24 +000075void
76Debugger::Initialize ()
77{
Greg Clayton66111032010-06-23 01:19:29 +000078 if (g_shared_debugger_refcount == 0)
Greg Clayton99d0faf2010-11-18 23:32:35 +000079 {
Greg Claytondbe54502010-11-19 03:46:01 +000080 lldb_private::Initialize();
Greg Clayton99d0faf2010-11-18 23:32:35 +000081 }
Greg Clayton66111032010-06-23 01:19:29 +000082 g_shared_debugger_refcount++;
Greg Clayton99d0faf2010-11-18 23:32:35 +000083
Chris Lattner30fdc8d2010-06-08 16:52:24 +000084}
85
86void
87Debugger::Terminate ()
88{
Greg Clayton66111032010-06-23 01:19:29 +000089 if (g_shared_debugger_refcount > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000090 {
Greg Clayton66111032010-06-23 01:19:29 +000091 g_shared_debugger_refcount--;
92 if (g_shared_debugger_refcount == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000093 {
Greg Claytondbe54502010-11-19 03:46:01 +000094 lldb_private::WillTerminate();
95 lldb_private::Terminate();
Caroline Tice6760a512011-01-17 21:55:19 +000096
97 // Clear our master list of debugger objects
98 Mutex::Locker locker (GetDebuggerListMutex ());
99 GetDebuggerList().clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000100 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000101 }
102}
103
Caroline Tice20bd37f2011-03-10 22:14:10 +0000104void
105Debugger::SettingsInitialize ()
106{
107 static bool g_initialized = false;
108
109 if (!g_initialized)
110 {
111 g_initialized = true;
112 UserSettingsControllerSP &usc = GetSettingsController();
113 usc.reset (new SettingsController);
114 UserSettingsController::InitializeSettingsController (usc,
115 SettingsController::global_settings_table,
116 SettingsController::instance_settings_table);
117 // Now call SettingsInitialize for each settings 'child' of Debugger
118 Target::SettingsInitialize ();
119 }
120}
121
122void
123Debugger::SettingsTerminate ()
124{
125
126 // Must call SettingsTerminate() for each settings 'child' of Debugger, before terminating the Debugger's
127 // Settings.
128
129 Target::SettingsTerminate ();
130
131 // Now terminate the Debugger Settings.
132
133 UserSettingsControllerSP &usc = GetSettingsController();
134 UserSettingsController::FinalizeSettingsController (usc);
135 usc.reset();
136}
137
Greg Clayton66111032010-06-23 01:19:29 +0000138DebuggerSP
139Debugger::CreateInstance ()
140{
141 DebuggerSP debugger_sp (new Debugger);
142 // Scope for locker
143 {
144 Mutex::Locker locker (GetDebuggerListMutex ());
145 GetDebuggerList().push_back(debugger_sp);
146 }
147 return debugger_sp;
148}
149
Caroline Ticee02657b2011-01-22 01:02:07 +0000150void
151Debugger::Destroy (lldb::DebuggerSP &debugger_sp)
152{
153 if (debugger_sp.get() == NULL)
154 return;
155
156 Mutex::Locker locker (GetDebuggerListMutex ());
157 DebuggerList &debugger_list = GetDebuggerList ();
158 DebuggerList::iterator pos, end = debugger_list.end();
159 for (pos = debugger_list.begin (); pos != end; ++pos)
160 {
161 if ((*pos).get() == debugger_sp.get())
162 {
163 debugger_list.erase (pos);
164 return;
165 }
166 }
167
168}
169
Greg Clayton66111032010-06-23 01:19:29 +0000170lldb::DebuggerSP
171Debugger::GetSP ()
172{
173 lldb::DebuggerSP debugger_sp;
174
175 Mutex::Locker locker (GetDebuggerListMutex ());
176 DebuggerList &debugger_list = GetDebuggerList();
177 DebuggerList::iterator pos, end = debugger_list.end();
178 for (pos = debugger_list.begin(); pos != end; ++pos)
179 {
180 if ((*pos).get() == this)
181 {
182 debugger_sp = *pos;
183 break;
184 }
185 }
186 return debugger_sp;
187}
188
Caroline Tice3df9a8d2010-09-04 00:03:46 +0000189lldb::DebuggerSP
190Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
191{
192 lldb::DebuggerSP debugger_sp;
193
194 Mutex::Locker locker (GetDebuggerListMutex ());
195 DebuggerList &debugger_list = GetDebuggerList();
196 DebuggerList::iterator pos, end = debugger_list.end();
197
198 for (pos = debugger_list.begin(); pos != end; ++pos)
199 {
200 if ((*pos).get()->m_instance_name == instance_name)
201 {
202 debugger_sp = *pos;
203 break;
204 }
205 }
206 return debugger_sp;
207}
Greg Clayton66111032010-06-23 01:19:29 +0000208
209TargetSP
210Debugger::FindTargetWithProcessID (lldb::pid_t pid)
211{
212 lldb::TargetSP target_sp;
213 Mutex::Locker locker (GetDebuggerListMutex ());
214 DebuggerList &debugger_list = GetDebuggerList();
215 DebuggerList::iterator pos, end = debugger_list.end();
216 for (pos = debugger_list.begin(); pos != end; ++pos)
217 {
218 target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
219 if (target_sp)
220 break;
221 }
222 return target_sp;
223}
224
225
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000226Debugger::Debugger () :
Caroline Ticeebc1bb22010-06-30 16:22:25 +0000227 UserID (g_unique_id++),
Greg Claytondbe54502010-11-19 03:46:01 +0000228 DebuggerInstanceSettings (*GetSettingsController()),
Greg Claytond46c87a2010-12-04 02:39:47 +0000229 m_input_comm("debugger.input"),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000230 m_input_file (),
231 m_output_file (),
232 m_error_file (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000233 m_target_list (),
Greg Claytonded470d2011-03-19 01:12:21 +0000234 m_platform_list (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000235 m_listener ("lldb.Debugger"),
236 m_source_manager (),
Greg Clayton66111032010-06-23 01:19:29 +0000237 m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000238 m_input_reader_stack (),
Greg Clayton4957bf62010-09-30 21:49:03 +0000239 m_input_reader_data ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000240{
Greg Clayton66111032010-06-23 01:19:29 +0000241 m_command_interpreter_ap->Initialize ();
Greg Claytonded470d2011-03-19 01:12:21 +0000242 // Always add our default platform to the platform list
243 PlatformSP default_platform_sp (Platform::GetDefaultPlatform());
244 assert (default_platform_sp.get());
245 m_platform_list.Append (default_platform_sp, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000246}
247
248Debugger::~Debugger ()
249{
Caroline Tice3d6086f2010-12-20 18:35:50 +0000250 CleanUpInputReaders();
Greg Clayton66111032010-06-23 01:19:29 +0000251 int num_targets = m_target_list.GetNumTargets();
252 for (int i = 0; i < num_targets; i++)
253 {
254 ProcessSP process_sp (m_target_list.GetTargetAtIndex (i)->GetProcessSP());
255 if (process_sp)
256 process_sp->Destroy();
257 }
258 DisconnectInput();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000259}
260
261
262bool
Greg Claytonfc3f0272011-05-29 04:06:55 +0000263Debugger::GetCloseInputOnEOF () const
264{
265 return m_input_comm.GetCloseOnEOF();
266}
267
268void
269Debugger::SetCloseInputOnEOF (bool b)
270{
271 m_input_comm.SetCloseOnEOF(b);
272}
273
274bool
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000275Debugger::GetAsyncExecution ()
276{
Greg Clayton66111032010-06-23 01:19:29 +0000277 return !m_command_interpreter_ap->GetSynchronous();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000278}
279
280void
281Debugger::SetAsyncExecution (bool async_execution)
282{
Greg Clayton66111032010-06-23 01:19:29 +0000283 m_command_interpreter_ap->SetSynchronous (!async_execution);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000284}
285
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000286
287void
288Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
289{
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000290 File &in_file = GetInputFile();
291 in_file.SetStream (fh, tranfer_ownership);
292 if (in_file.IsValid() == false)
293 in_file.SetStream (stdin, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000294
295 // Disconnect from any old connection if we had one
296 m_input_comm.Disconnect ();
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000297 m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), true));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000298 m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this);
299
300 Error error;
301 if (m_input_comm.StartReadThread (&error) == false)
302 {
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000303 File &err_file = GetErrorFile();
304
305 err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error");
306 exit(1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000307 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000308}
309
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000310void
311Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
312{
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000313 File &out_file = GetOutputFile();
314 out_file.SetStream (fh, tranfer_ownership);
315 if (out_file.IsValid() == false)
316 out_file.SetStream (stdout, false);
Caroline Tice2f88aad2011-01-14 00:29:16 +0000317
318 GetCommandInterpreter().GetScriptInterpreter()->ResetOutputFileHandle (fh);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000319}
320
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000321void
322Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
323{
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000324 File &err_file = GetErrorFile();
325 err_file.SetStream (fh, tranfer_ownership);
326 if (err_file.IsValid() == false)
327 err_file.SetStream (stderr, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000328}
329
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000330ExecutionContext
Jim Ingham2976d002010-08-26 21:32:51 +0000331Debugger::GetSelectedExecutionContext ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000332{
333 ExecutionContext exe_ctx;
334 exe_ctx.Clear();
335
Jim Ingham2976d002010-08-26 21:32:51 +0000336 lldb::TargetSP target_sp = GetSelectedTarget();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000337 exe_ctx.target = target_sp.get();
338
339 if (target_sp)
340 {
341 exe_ctx.process = target_sp->GetProcessSP().get();
342 if (exe_ctx.process && exe_ctx.process->IsRunning() == false)
343 {
Jim Ingham2976d002010-08-26 21:32:51 +0000344 exe_ctx.thread = exe_ctx.process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000345 if (exe_ctx.thread == NULL)
346 exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
347 if (exe_ctx.thread)
348 {
Jim Ingham2976d002010-08-26 21:32:51 +0000349 exe_ctx.frame = exe_ctx.thread->GetSelectedFrame().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000350 if (exe_ctx.frame == NULL)
351 exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex (0).get();
352 }
353 }
354 }
355 return exe_ctx;
356
357}
358
Caroline Ticeb44880c2011-02-10 01:15:13 +0000359InputReaderSP
360Debugger::GetCurrentInputReader ()
361{
362 InputReaderSP reader_sp;
363
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000364 if (!m_input_reader_stack.IsEmpty())
Caroline Ticeb44880c2011-02-10 01:15:13 +0000365 {
366 // Clear any finished readers from the stack
367 while (CheckIfTopInputReaderIsDone()) ;
368
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000369 if (!m_input_reader_stack.IsEmpty())
370 reader_sp = m_input_reader_stack.Top();
Caroline Ticeb44880c2011-02-10 01:15:13 +0000371 }
372
373 return reader_sp;
374}
375
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000376void
377Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len)
378{
Caroline Ticeefed6132010-11-19 20:47:54 +0000379 if (bytes_len > 0)
380 ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
381 else
382 ((Debugger *)baton)->DispatchInputEndOfFile ();
383}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384
385
386void
387Debugger::DispatchInput (const char *bytes, size_t bytes_len)
388{
Caroline Ticeefed6132010-11-19 20:47:54 +0000389 if (bytes == NULL || bytes_len == 0)
390 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000391
392 WriteToDefaultReader (bytes, bytes_len);
393}
394
395void
Caroline Ticeefed6132010-11-19 20:47:54 +0000396Debugger::DispatchInputInterrupt ()
397{
398 m_input_reader_data.clear();
399
Caroline Ticeb44880c2011-02-10 01:15:13 +0000400 InputReaderSP reader_sp (GetCurrentInputReader ());
401 if (reader_sp)
Caroline Ticeefed6132010-11-19 20:47:54 +0000402 {
Caroline Ticeb44880c2011-02-10 01:15:13 +0000403 reader_sp->Notify (eInputReaderInterrupt);
Caroline Ticeefed6132010-11-19 20:47:54 +0000404
Caroline Ticeb44880c2011-02-10 01:15:13 +0000405 // If notifying the reader of the interrupt finished the reader, we should pop it off the stack.
Caroline Ticeefed6132010-11-19 20:47:54 +0000406 while (CheckIfTopInputReaderIsDone ()) ;
407 }
408}
409
410void
411Debugger::DispatchInputEndOfFile ()
412{
413 m_input_reader_data.clear();
414
Caroline Ticeb44880c2011-02-10 01:15:13 +0000415 InputReaderSP reader_sp (GetCurrentInputReader ());
416 if (reader_sp)
Caroline Ticeefed6132010-11-19 20:47:54 +0000417 {
Caroline Ticeb44880c2011-02-10 01:15:13 +0000418 reader_sp->Notify (eInputReaderEndOfFile);
Caroline Ticeefed6132010-11-19 20:47:54 +0000419
Caroline Ticeb44880c2011-02-10 01:15:13 +0000420 // If notifying the reader of the end-of-file finished the reader, we should pop it off the stack.
Caroline Ticeefed6132010-11-19 20:47:54 +0000421 while (CheckIfTopInputReaderIsDone ()) ;
422 }
423}
424
425void
Caroline Tice3d6086f2010-12-20 18:35:50 +0000426Debugger::CleanUpInputReaders ()
427{
428 m_input_reader_data.clear();
429
Caroline Ticeb44880c2011-02-10 01:15:13 +0000430 // The bottom input reader should be the main debugger input reader. We do not want to close that one here.
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000431 while (m_input_reader_stack.GetSize() > 1)
Caroline Tice3d6086f2010-12-20 18:35:50 +0000432 {
Caroline Ticeb44880c2011-02-10 01:15:13 +0000433 InputReaderSP reader_sp (GetCurrentInputReader ());
Caroline Tice3d6086f2010-12-20 18:35:50 +0000434 if (reader_sp)
435 {
436 reader_sp->Notify (eInputReaderEndOfFile);
437 reader_sp->SetIsDone (true);
438 }
439 }
440}
441
442void
Caroline Tice969ed3d2011-05-02 20:41:46 +0000443Debugger::NotifyTopInputReader (InputReaderAction notification)
444{
445 InputReaderSP reader_sp (GetCurrentInputReader());
446 if (reader_sp)
447 {
448 reader_sp->Notify (notification);
449
450 // Flush out any input readers that are done.
451 while (CheckIfTopInputReaderIsDone ())
452 /* Do nothing. */;
453 }
454}
455
Caroline Tice9088b062011-05-09 23:06:58 +0000456bool
457Debugger::InputReaderIsTopReader (const lldb::InputReaderSP& reader_sp)
458{
Caroline Ticed61c10b2011-06-16 16:27:19 +0000459 InputReaderSP top_reader_sp (GetCurrentInputReader());
Caroline Tice9088b062011-05-09 23:06:58 +0000460
Caroline Ticed61c10b2011-06-16 16:27:19 +0000461 return (reader_sp.get() == top_reader_sp.get());
Caroline Tice9088b062011-05-09 23:06:58 +0000462}
463
464
Caroline Tice969ed3d2011-05-02 20:41:46 +0000465void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000466Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
467{
468 if (bytes && bytes_len)
469 m_input_reader_data.append (bytes, bytes_len);
470
471 if (m_input_reader_data.empty())
472 return;
473
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000474 while (!m_input_reader_stack.IsEmpty() && !m_input_reader_data.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000475 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000476 // Get the input reader from the top of the stack
Caroline Ticeb44880c2011-02-10 01:15:13 +0000477 InputReaderSP reader_sp (GetCurrentInputReader ());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000478 if (!reader_sp)
479 break;
480
Greg Clayton471b31c2010-07-20 22:52:08 +0000481 size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000482 m_input_reader_data.size());
483 if (bytes_handled)
484 {
485 m_input_reader_data.erase (0, bytes_handled);
486 }
487 else
488 {
489 // No bytes were handled, we might not have reached our
490 // granularity, just return and wait for more data
491 break;
492 }
493 }
494
Caroline Ticeb44880c2011-02-10 01:15:13 +0000495 // Flush out any input readers that are done.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000496 while (CheckIfTopInputReaderIsDone ())
497 /* Do nothing. */;
498
499}
500
501void
502Debugger::PushInputReader (const InputReaderSP& reader_sp)
503{
504 if (!reader_sp)
505 return;
Caroline Ticeb44880c2011-02-10 01:15:13 +0000506
507 // Deactivate the old top reader
508 InputReaderSP top_reader_sp (GetCurrentInputReader ());
509
510 if (top_reader_sp)
511 top_reader_sp->Notify (eInputReaderDeactivate);
512
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000513 m_input_reader_stack.Push (reader_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000514 reader_sp->Notify (eInputReaderActivate);
515 ActivateInputReader (reader_sp);
516}
517
518bool
519Debugger::PopInputReader (const lldb::InputReaderSP& pop_reader_sp)
520{
521 bool result = false;
522
523 // The reader on the stop of the stack is done, so let the next
524 // read on the stack referesh its prompt and if there is one...
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000525 if (!m_input_reader_stack.IsEmpty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000526 {
Caroline Ticeb44880c2011-02-10 01:15:13 +0000527 // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000528 InputReaderSP reader_sp(m_input_reader_stack.Top());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000529
530 if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
531 {
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000532 m_input_reader_stack.Pop ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000533 reader_sp->Notify (eInputReaderDeactivate);
534 reader_sp->Notify (eInputReaderDone);
535 result = true;
536
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000537 if (!m_input_reader_stack.IsEmpty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000538 {
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000539 reader_sp = m_input_reader_stack.Top();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000540 if (reader_sp)
541 {
542 ActivateInputReader (reader_sp);
543 reader_sp->Notify (eInputReaderReactivate);
544 }
545 }
546 }
547 }
548 return result;
549}
550
551bool
552Debugger::CheckIfTopInputReaderIsDone ()
553{
554 bool result = false;
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000555 if (!m_input_reader_stack.IsEmpty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000556 {
Caroline Ticeb44880c2011-02-10 01:15:13 +0000557 // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000558 InputReaderSP reader_sp(m_input_reader_stack.Top());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000559
560 if (reader_sp && reader_sp->IsDone())
561 {
562 result = true;
563 PopInputReader (reader_sp);
564 }
565 }
566 return result;
567}
568
569void
570Debugger::ActivateInputReader (const InputReaderSP &reader_sp)
571{
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000572 int input_fd = m_input_file.GetFile().GetDescriptor();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000573
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000574 if (input_fd >= 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000575 {
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000576 Terminal tty(input_fd);
Greg Claytona3406612011-02-07 23:24:47 +0000577
578 tty.SetEcho(reader_sp->GetEcho());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000579
Greg Claytona3406612011-02-07 23:24:47 +0000580 switch (reader_sp->GetGranularity())
581 {
582 case eInputReaderGranularityByte:
583 case eInputReaderGranularityWord:
584 tty.SetCanonical (false);
585 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000586
Greg Claytona3406612011-02-07 23:24:47 +0000587 case eInputReaderGranularityLine:
588 case eInputReaderGranularityAll:
589 tty.SetCanonical (true);
590 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000591
Greg Claytona3406612011-02-07 23:24:47 +0000592 default:
593 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000594 }
595 }
596}
Greg Clayton66111032010-06-23 01:19:29 +0000597
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000598StreamSP
599Debugger::GetAsyncOutputStream ()
600{
601 return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
602 CommandInterpreter::eBroadcastBitAsynchronousOutputData));
603}
604
605StreamSP
606Debugger::GetAsyncErrorStream ()
607{
608 return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
609 CommandInterpreter::eBroadcastBitAsynchronousErrorData));
610}
611
Caroline Ticeebc1bb22010-06-30 16:22:25 +0000612DebuggerSP
613Debugger::FindDebuggerWithID (lldb::user_id_t id)
614{
615 lldb::DebuggerSP debugger_sp;
616
617 Mutex::Locker locker (GetDebuggerListMutex ());
618 DebuggerList &debugger_list = GetDebuggerList();
619 DebuggerList::iterator pos, end = debugger_list.end();
620 for (pos = debugger_list.begin(); pos != end; ++pos)
621 {
622 if ((*pos).get()->GetID() == id)
623 {
624 debugger_sp = *pos;
625 break;
626 }
627 }
628 return debugger_sp;
629}
Caroline Tice3df9a8d2010-09-04 00:03:46 +0000630
Greg Clayton1b654882010-09-19 02:33:57 +0000631static void
632TestPromptFormats (StackFrame *frame)
633{
634 if (frame == NULL)
635 return;
636
637 StreamString s;
638 const char *prompt_format =
639 "{addr = '${addr}'\n}"
640 "{process.id = '${process.id}'\n}"
641 "{process.name = '${process.name}'\n}"
642 "{process.file.basename = '${process.file.basename}'\n}"
643 "{process.file.fullpath = '${process.file.fullpath}'\n}"
644 "{thread.id = '${thread.id}'\n}"
645 "{thread.index = '${thread.index}'\n}"
646 "{thread.name = '${thread.name}'\n}"
647 "{thread.queue = '${thread.queue}'\n}"
648 "{thread.stop-reason = '${thread.stop-reason}'\n}"
649 "{target.arch = '${target.arch}'\n}"
650 "{module.file.basename = '${module.file.basename}'\n}"
651 "{module.file.fullpath = '${module.file.fullpath}'\n}"
652 "{file.basename = '${file.basename}'\n}"
653 "{file.fullpath = '${file.fullpath}'\n}"
654 "{frame.index = '${frame.index}'\n}"
655 "{frame.pc = '${frame.pc}'\n}"
656 "{frame.sp = '${frame.sp}'\n}"
657 "{frame.fp = '${frame.fp}'\n}"
658 "{frame.flags = '${frame.flags}'\n}"
659 "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
660 "{frame.reg.rip = '${frame.reg.rip}'\n}"
661 "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
662 "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
663 "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
664 "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
665 "{frame.reg.carp = '${frame.reg.carp}'\n}"
666 "{function.id = '${function.id}'\n}"
667 "{function.name = '${function.name}'\n}"
668 "{function.addr-offset = '${function.addr-offset}'\n}"
669 "{function.line-offset = '${function.line-offset}'\n}"
670 "{function.pc-offset = '${function.pc-offset}'\n}"
671 "{line.file.basename = '${line.file.basename}'\n}"
672 "{line.file.fullpath = '${line.file.fullpath}'\n}"
673 "{line.number = '${line.number}'\n}"
674 "{line.start-addr = '${line.start-addr}'\n}"
675 "{line.end-addr = '${line.end-addr}'\n}"
676;
677
678 SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
679 ExecutionContext exe_ctx;
Greg Clayton0603aa92010-10-04 01:05:56 +0000680 frame->CalculateExecutionContext(exe_ctx);
Greg Clayton1b654882010-09-19 02:33:57 +0000681 const char *end = NULL;
682 if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, &end))
683 {
684 printf("%s\n", s.GetData());
685 }
686 else
687 {
688 printf ("error: at '%s'\n", end);
689 printf ("what we got: %s\n", s.GetData());
690 }
691}
692
693bool
694Debugger::FormatPrompt
695(
696 const char *format,
697 const SymbolContext *sc,
698 const ExecutionContext *exe_ctx,
699 const Address *addr,
700 Stream &s,
701 const char **end
702)
703{
704 bool success = true;
705 const char *p;
706 for (p = format; *p != '\0'; ++p)
707 {
708 size_t non_special_chars = ::strcspn (p, "${}\\");
709 if (non_special_chars > 0)
710 {
711 if (success)
712 s.Write (p, non_special_chars);
713 p += non_special_chars;
714 }
715
716 if (*p == '\0')
717 {
718 break;
719 }
720 else if (*p == '{')
721 {
722 // Start a new scope that must have everything it needs if it is to
723 // to make it into the final output stream "s". If you want to make
724 // a format that only prints out the function or symbol name if there
725 // is one in the symbol context you can use:
726 // "{function =${function.name}}"
727 // The first '{' starts a new scope that end with the matching '}' at
728 // the end of the string. The contents "function =${function.name}"
729 // will then be evaluated and only be output if there is a function
730 // or symbol with a valid name.
731 StreamString sub_strm;
732
733 ++p; // Skip the '{'
734
735 if (FormatPrompt (p, sc, exe_ctx, addr, sub_strm, &p))
736 {
737 // The stream had all it needed
738 s.Write(sub_strm.GetData(), sub_strm.GetSize());
739 }
740 if (*p != '}')
741 {
742 success = false;
743 break;
744 }
745 }
746 else if (*p == '}')
747 {
748 // End of a enclosing scope
749 break;
750 }
751 else if (*p == '$')
752 {
753 // We have a prompt variable to print
754 ++p;
755 if (*p == '{')
756 {
757 ++p;
758 const char *var_name_begin = p;
759 const char *var_name_end = ::strchr (p, '}');
760
761 if (var_name_end && var_name_begin < var_name_end)
762 {
763 // if we have already failed to parse, skip this variable
764 if (success)
765 {
766 const char *cstr = NULL;
767 Address format_addr;
768 bool calculate_format_addr_function_offset = false;
769 // Set reg_kind and reg_num to invalid values
770 RegisterKind reg_kind = kNumRegisterKinds;
771 uint32_t reg_num = LLDB_INVALID_REGNUM;
772 FileSpec format_file_spec;
Greg Claytone0d378b2011-03-24 21:19:54 +0000773 const RegisterInfo *reg_info = NULL;
Greg Clayton1b654882010-09-19 02:33:57 +0000774 RegisterContext *reg_ctx = NULL;
775
776 // Each variable must set success to true below...
777 bool var_success = false;
778 switch (var_name_begin[0])
779 {
780 case 'a':
781 if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0)
782 {
783 if (addr && addr->IsValid())
784 {
785 var_success = true;
786 format_addr = *addr;
787 }
788 }
789 break;
790
791 case 'p':
792 if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0)
793 {
794 if (exe_ctx && exe_ctx->process != NULL)
795 {
796 var_name_begin += ::strlen ("process.");
797 if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
798 {
799 s.Printf("%i", exe_ctx->process->GetID());
800 var_success = true;
801 }
802 else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) ||
803 (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) ||
804 (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0))
805 {
806 ModuleSP exe_module_sp (exe_ctx->process->GetTarget().GetExecutableModule());
807 if (exe_module_sp)
808 {
809 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
810 {
811 format_file_spec.GetFilename() = exe_module_sp->GetFileSpec().GetFilename();
812 var_success = format_file_spec;
813 }
814 else
815 {
816 format_file_spec = exe_module_sp->GetFileSpec();
817 var_success = format_file_spec;
818 }
819 }
820 }
821 }
822 }
823 break;
824
825 case 't':
826 if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0)
827 {
828 if (exe_ctx && exe_ctx->thread)
829 {
830 var_name_begin += ::strlen ("thread.");
831 if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
832 {
833 s.Printf("0x%4.4x", exe_ctx->thread->GetID());
834 var_success = true;
835 }
836 else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
837 {
838 s.Printf("%u", exe_ctx->thread->GetIndexID());
839 var_success = true;
840 }
841 else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
842 {
843 cstr = exe_ctx->thread->GetName();
844 var_success = cstr && cstr[0];
845 if (var_success)
846 s.PutCString(cstr);
847 }
848 else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0)
849 {
850 cstr = exe_ctx->thread->GetQueueName();
851 var_success = cstr && cstr[0];
852 if (var_success)
853 s.PutCString(cstr);
854 }
855 else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0)
856 {
Jim Inghamb15bfc72010-10-20 00:39:53 +0000857 StopInfoSP stop_info_sp = exe_ctx->thread->GetStopInfo ();
858 if (stop_info_sp)
Greg Clayton1b654882010-09-19 02:33:57 +0000859 {
Jim Inghamb15bfc72010-10-20 00:39:53 +0000860 cstr = stop_info_sp->GetDescription();
Greg Clayton1b654882010-09-19 02:33:57 +0000861 if (cstr && cstr[0])
862 {
863 s.PutCString(cstr);
864 var_success = true;
865 }
866 }
867 }
868 }
869 }
870 else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0)
871 {
Greg Clayton0603aa92010-10-04 01:05:56 +0000872 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
873 if (target)
Greg Clayton1b654882010-09-19 02:33:57 +0000874 {
Greg Clayton1b654882010-09-19 02:33:57 +0000875 var_name_begin += ::strlen ("target.");
876 if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0)
877 {
878 ArchSpec arch (target->GetArchitecture ());
879 if (arch.IsValid())
880 {
Greg Clayton64195a22011-02-23 00:35:02 +0000881 s.PutCString (arch.GetArchitectureName());
Greg Clayton1b654882010-09-19 02:33:57 +0000882 var_success = true;
883 }
884 }
885 }
886 }
887 break;
888
889
890 case 'm':
891 if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0)
892 {
Greg Clayton0603aa92010-10-04 01:05:56 +0000893 if (sc && sc->module_sp.get())
Greg Clayton1b654882010-09-19 02:33:57 +0000894 {
Greg Clayton0603aa92010-10-04 01:05:56 +0000895 Module *module = sc->module_sp.get();
Greg Clayton1b654882010-09-19 02:33:57 +0000896 var_name_begin += ::strlen ("module.");
897
898 if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
899 {
900 if (module->GetFileSpec())
901 {
902 var_name_begin += ::strlen ("file.");
903
904 if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
905 {
906 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
907 var_success = format_file_spec;
908 }
909 else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
910 {
911 format_file_spec = module->GetFileSpec();
912 var_success = format_file_spec;
913 }
914 }
915 }
916 }
917 }
918 break;
919
920
921 case 'f':
922 if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
923 {
924 if (sc && sc->comp_unit != NULL)
925 {
926 var_name_begin += ::strlen ("file.");
927
928 if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
929 {
930 format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
931 var_success = format_file_spec;
932 }
933 else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
934 {
935 format_file_spec = *sc->comp_unit;
936 var_success = format_file_spec;
937 }
938 }
939 }
940 else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0)
941 {
942 if (exe_ctx && exe_ctx->frame)
943 {
944 var_name_begin += ::strlen ("frame.");
945 if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
946 {
947 s.Printf("%u", exe_ctx->frame->GetFrameIndex());
948 var_success = true;
949 }
950 else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0)
951 {
952 reg_kind = eRegisterKindGeneric;
953 reg_num = LLDB_REGNUM_GENERIC_PC;
954 var_success = true;
955 }
956 else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0)
957 {
958 reg_kind = eRegisterKindGeneric;
959 reg_num = LLDB_REGNUM_GENERIC_SP;
960 var_success = true;
961 }
962 else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0)
963 {
964 reg_kind = eRegisterKindGeneric;
965 reg_num = LLDB_REGNUM_GENERIC_FP;
966 var_success = true;
967 }
968 else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0)
969 {
970 reg_kind = eRegisterKindGeneric;
971 reg_num = LLDB_REGNUM_GENERIC_FLAGS;
972 var_success = true;
973 }
974 else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0)
975 {
Greg Clayton5ccbd292011-01-06 22:15:06 +0000976 reg_ctx = exe_ctx->frame->GetRegisterContext().get();
Greg Clayton1b654882010-09-19 02:33:57 +0000977 if (reg_ctx)
978 {
979 var_name_begin += ::strlen ("reg.");
980 if (var_name_begin < var_name_end)
981 {
982 std::string reg_name (var_name_begin, var_name_end);
983 reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
984 if (reg_info)
985 var_success = true;
986 }
987 }
988 }
989 }
990 }
991 else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0)
992 {
993 if (sc && (sc->function != NULL || sc->symbol != NULL))
994 {
995 var_name_begin += ::strlen ("function.");
996 if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
997 {
998 if (sc->function)
999 s.Printf("function{0x%8.8x}", sc->function->GetID());
1000 else
1001 s.Printf("symbol[%u]", sc->symbol->GetID());
1002
1003 var_success = true;
1004 }
1005 else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
1006 {
1007 if (sc->function)
1008 cstr = sc->function->GetName().AsCString (NULL);
1009 else if (sc->symbol)
1010 cstr = sc->symbol->GetName().AsCString (NULL);
1011 if (cstr)
1012 {
1013 s.PutCString(cstr);
Greg Clayton0d9c9932010-10-04 17:26:49 +00001014
1015 if (sc->block)
1016 {
1017 Block *inline_block = sc->block->GetContainingInlinedBlock ();
1018 if (inline_block)
1019 {
1020 const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
1021 if (inline_info)
1022 {
1023 s.PutCString(" [inlined] ");
1024 inline_info->GetName().Dump(&s);
1025 }
1026 }
1027 }
Greg Clayton1b654882010-09-19 02:33:57 +00001028 var_success = true;
1029 }
1030 }
1031 else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0)
1032 {
1033 var_success = addr != NULL;
1034 if (var_success)
1035 {
1036 format_addr = *addr;
1037 calculate_format_addr_function_offset = true;
1038 }
1039 }
1040 else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0)
1041 {
1042 var_success = sc->line_entry.range.GetBaseAddress().IsValid();
1043 if (var_success)
1044 {
1045 format_addr = sc->line_entry.range.GetBaseAddress();
1046 calculate_format_addr_function_offset = true;
1047 }
1048 }
1049 else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0)
1050 {
1051 var_success = exe_ctx->frame;
1052 if (var_success)
1053 {
1054 format_addr = exe_ctx->frame->GetFrameCodeAddress();
1055 calculate_format_addr_function_offset = true;
1056 }
1057 }
1058 }
1059 }
1060 break;
1061
1062 case 'l':
1063 if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0)
1064 {
1065 if (sc && sc->line_entry.IsValid())
1066 {
1067 var_name_begin += ::strlen ("line.");
1068 if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
1069 {
1070 var_name_begin += ::strlen ("file.");
1071
1072 if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
1073 {
1074 format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
1075 var_success = format_file_spec;
1076 }
1077 else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
1078 {
1079 format_file_spec = sc->line_entry.file;
1080 var_success = format_file_spec;
1081 }
1082 }
1083 else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0)
1084 {
1085 var_success = true;
1086 s.Printf("%u", sc->line_entry.line);
1087 }
1088 else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) ||
1089 (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0))
1090 {
1091 var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
1092 if (var_success)
1093 {
1094 format_addr = sc->line_entry.range.GetBaseAddress();
1095 if (var_name_begin[0] == 'e')
1096 format_addr.Slide (sc->line_entry.range.GetByteSize());
1097 }
1098 }
1099 }
1100 }
1101 break;
1102 }
1103
1104 if (var_success)
1105 {
1106 // If format addr is valid, then we need to print an address
1107 if (reg_num != LLDB_INVALID_REGNUM)
1108 {
1109 // We have a register value to display...
1110 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
1111 {
1112 format_addr = exe_ctx->frame->GetFrameCodeAddress();
1113 }
1114 else
1115 {
1116 if (reg_ctx == NULL)
Greg Clayton5ccbd292011-01-06 22:15:06 +00001117 reg_ctx = exe_ctx->frame->GetRegisterContext().get();
Greg Clayton1b654882010-09-19 02:33:57 +00001118
1119 if (reg_ctx)
1120 {
1121 if (reg_kind != kNumRegisterKinds)
1122 reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
1123 reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
1124 var_success = reg_info != NULL;
1125 }
1126 }
1127 }
1128
1129 if (reg_info != NULL)
1130 {
Greg Clayton7349bd92011-05-09 20:18:18 +00001131 RegisterValue reg_value;
1132 var_success = reg_ctx->ReadRegister (reg_info, reg_value);
1133 if (var_success)
Greg Clayton1b654882010-09-19 02:33:57 +00001134 {
Greg Clayton9a8fa912011-05-15 04:12:07 +00001135 reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
Greg Clayton1b654882010-09-19 02:33:57 +00001136 }
1137 }
1138
1139 if (format_file_spec)
1140 {
1141 s << format_file_spec;
1142 }
1143
1144 // If format addr is valid, then we need to print an address
1145 if (format_addr.IsValid())
1146 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001147 var_success = false;
1148
Greg Clayton1b654882010-09-19 02:33:57 +00001149 if (calculate_format_addr_function_offset)
1150 {
1151 Address func_addr;
Greg Clayton1b654882010-09-19 02:33:57 +00001152
Greg Clayton0603aa92010-10-04 01:05:56 +00001153 if (sc)
1154 {
1155 if (sc->function)
Greg Clayton0d9c9932010-10-04 17:26:49 +00001156 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001157 func_addr = sc->function->GetAddressRange().GetBaseAddress();
Greg Clayton0d9c9932010-10-04 17:26:49 +00001158 if (sc->block)
1159 {
1160 // Check to make sure we aren't in an inline
1161 // function. If we are, use the inline block
1162 // range that contains "format_addr" since
1163 // blocks can be discontiguous.
1164 Block *inline_block = sc->block->GetContainingInlinedBlock ();
1165 AddressRange inline_range;
1166 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
1167 func_addr = inline_range.GetBaseAddress();
1168 }
1169 }
Greg Clayton0603aa92010-10-04 01:05:56 +00001170 else if (sc->symbol && sc->symbol->GetAddressRangePtr())
1171 func_addr = sc->symbol->GetAddressRangePtr()->GetBaseAddress();
1172 }
1173
1174 if (func_addr.IsValid())
Greg Clayton1b654882010-09-19 02:33:57 +00001175 {
1176 if (func_addr.GetSection() == format_addr.GetSection())
1177 {
1178 addr_t func_file_addr = func_addr.GetFileAddress();
1179 addr_t addr_file_addr = format_addr.GetFileAddress();
1180 if (addr_file_addr > func_file_addr)
Greg Clayton1b654882010-09-19 02:33:57 +00001181 s.Printf(" + %llu", addr_file_addr - func_file_addr);
Greg Clayton1b654882010-09-19 02:33:57 +00001182 else if (addr_file_addr < func_file_addr)
Greg Clayton1b654882010-09-19 02:33:57 +00001183 s.Printf(" - %llu", func_file_addr - addr_file_addr);
Greg Clayton0603aa92010-10-04 01:05:56 +00001184 var_success = true;
Greg Clayton1b654882010-09-19 02:33:57 +00001185 }
1186 else
Greg Clayton0603aa92010-10-04 01:05:56 +00001187 {
1188 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
1189 if (target)
1190 {
1191 addr_t func_load_addr = func_addr.GetLoadAddress (target);
1192 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
1193 if (addr_load_addr > func_load_addr)
1194 s.Printf(" + %llu", addr_load_addr - func_load_addr);
1195 else if (addr_load_addr < func_load_addr)
1196 s.Printf(" - %llu", func_load_addr - addr_load_addr);
1197 var_success = true;
1198 }
1199 }
Greg Clayton1b654882010-09-19 02:33:57 +00001200 }
1201 }
1202 else
1203 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001204 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
Greg Clayton1b654882010-09-19 02:33:57 +00001205 addr_t vaddr = LLDB_INVALID_ADDRESS;
Greg Clayton0603aa92010-10-04 01:05:56 +00001206 if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
1207 vaddr = format_addr.GetLoadAddress (target);
Greg Clayton1b654882010-09-19 02:33:57 +00001208 if (vaddr == LLDB_INVALID_ADDRESS)
1209 vaddr = format_addr.GetFileAddress ();
1210
1211 if (vaddr != LLDB_INVALID_ADDRESS)
Greg Clayton0603aa92010-10-04 01:05:56 +00001212 {
Greg Clayton514487e2011-02-15 21:59:32 +00001213 int addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
Greg Clayton35f1a0d2010-11-19 04:16:11 +00001214 if (addr_width == 0)
1215 addr_width = 16;
1216 s.Printf("0x%*.*llx", addr_width, addr_width, vaddr);
Greg Clayton0603aa92010-10-04 01:05:56 +00001217 var_success = true;
1218 }
Greg Clayton1b654882010-09-19 02:33:57 +00001219 }
1220 }
1221 }
1222
1223 if (var_success == false)
1224 success = false;
1225 }
1226 p = var_name_end;
1227 }
1228 else
1229 break;
1230 }
1231 else
1232 {
1233 // We got a dollar sign with no '{' after it, it must just be a dollar sign
1234 s.PutChar(*p);
1235 }
1236 }
1237 else if (*p == '\\')
1238 {
1239 ++p; // skip the slash
1240 switch (*p)
1241 {
1242 case 'a': s.PutChar ('\a'); break;
1243 case 'b': s.PutChar ('\b'); break;
1244 case 'f': s.PutChar ('\f'); break;
1245 case 'n': s.PutChar ('\n'); break;
1246 case 'r': s.PutChar ('\r'); break;
1247 case 't': s.PutChar ('\t'); break;
1248 case 'v': s.PutChar ('\v'); break;
1249 case '\'': s.PutChar ('\''); break;
1250 case '\\': s.PutChar ('\\'); break;
1251 case '0':
1252 // 1 to 3 octal chars
1253 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001254 // Make a string that can hold onto the initial zero char,
1255 // up to 3 octal digits, and a terminating NULL.
1256 char oct_str[5] = { 0, 0, 0, 0, 0 };
1257
1258 int i;
1259 for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
1260 oct_str[i] = p[i];
1261
1262 // We don't want to consume the last octal character since
1263 // the main for loop will do this for us, so we advance p by
1264 // one less than i (even if i is zero)
1265 p += i - 1;
1266 unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
1267 if (octal_value <= UINT8_MAX)
Greg Clayton1b654882010-09-19 02:33:57 +00001268 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001269 char octal_char = octal_value;
1270 s.Write (&octal_char, 1);
Greg Clayton1b654882010-09-19 02:33:57 +00001271 }
Greg Clayton1b654882010-09-19 02:33:57 +00001272 }
1273 break;
1274
1275 case 'x':
1276 // hex number in the format
Greg Clayton0603aa92010-10-04 01:05:56 +00001277 if (isxdigit(p[1]))
Greg Clayton1b654882010-09-19 02:33:57 +00001278 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001279 ++p; // Skip the 'x'
Greg Clayton1b654882010-09-19 02:33:57 +00001280
Greg Clayton0603aa92010-10-04 01:05:56 +00001281 // Make a string that can hold onto two hex chars plus a
1282 // NULL terminator
1283 char hex_str[3] = { 0,0,0 };
1284 hex_str[0] = *p;
1285 if (isxdigit(p[1]))
Greg Clayton1b654882010-09-19 02:33:57 +00001286 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001287 ++p; // Skip the first of the two hex chars
1288 hex_str[1] = *p;
1289 }
1290
1291 unsigned long hex_value = strtoul (hex_str, NULL, 16);
1292 if (hex_value <= UINT8_MAX)
Greg Clayton1b654882010-09-19 02:33:57 +00001293 s.PutChar (hex_value);
Greg Clayton0603aa92010-10-04 01:05:56 +00001294 }
1295 else
1296 {
1297 s.PutChar('x');
Greg Clayton1b654882010-09-19 02:33:57 +00001298 }
1299 break;
1300
1301 default:
Greg Clayton0603aa92010-10-04 01:05:56 +00001302 // Just desensitize any other character by just printing what
1303 // came after the '\'
1304 s << *p;
Greg Clayton1b654882010-09-19 02:33:57 +00001305 break;
1306
1307 }
1308
1309 }
1310 }
1311 if (end)
1312 *end = p;
1313 return success;
1314}
1315
Greg Clayton4a33d312011-06-23 17:59:56 +00001316
1317static FormatManager&
1318GetFormatManager() {
1319 static FormatManager g_format_manager;
1320 return g_format_manager;
1321}
1322
1323bool
1324Debugger::GetFormatForType (const ConstString &type, lldb::Format& format, bool& cascade)
1325{
1326 return GetFormatManager().GetFormatForType(type, format, cascade);
1327}
1328
1329void
1330Debugger::AddFormatForType (const ConstString &type, lldb::Format format, bool cascade)
1331{
1332 GetFormatManager().AddFormatForType(type,format, cascade);
1333}
1334
1335bool
1336Debugger::DeleteFormatForType (const ConstString &type)
1337{
1338 return GetFormatManager().DeleteFormatForType(type);
1339}
1340
1341void
1342Debugger::LoopThroughFormatList (FormatCallback cback, void* param)
1343{
1344 return GetFormatManager().LoopThroughFormatList(cback, param);
1345}
1346
Greg Clayton1b654882010-09-19 02:33:57 +00001347#pragma mark Debugger::SettingsController
1348
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001349//--------------------------------------------------
Greg Clayton1b654882010-09-19 02:33:57 +00001350// class Debugger::SettingsController
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001351//--------------------------------------------------
1352
Greg Clayton1b654882010-09-19 02:33:57 +00001353Debugger::SettingsController::SettingsController () :
Caroline Tice101c7c22010-09-09 06:25:08 +00001354 UserSettingsController ("", lldb::UserSettingsControllerSP())
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001355{
Caroline Tice91123da2010-09-08 17:48:55 +00001356 m_default_settings.reset (new DebuggerInstanceSettings (*this, false,
1357 InstanceSettings::GetDefaultName().AsCString()));
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001358}
1359
Greg Clayton1b654882010-09-19 02:33:57 +00001360Debugger::SettingsController::~SettingsController ()
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001361{
1362}
1363
1364
1365lldb::InstanceSettingsSP
Greg Clayton1b654882010-09-19 02:33:57 +00001366Debugger::SettingsController::CreateInstanceSettings (const char *instance_name)
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001367{
Greg Claytondbe54502010-11-19 03:46:01 +00001368 DebuggerInstanceSettings *new_settings = new DebuggerInstanceSettings (*GetSettingsController(),
Caroline Tice91123da2010-09-08 17:48:55 +00001369 false, instance_name);
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001370 lldb::InstanceSettingsSP new_settings_sp (new_settings);
1371 return new_settings_sp;
1372}
1373
Greg Clayton1b654882010-09-19 02:33:57 +00001374#pragma mark DebuggerInstanceSettings
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001375//--------------------------------------------------
1376// class DebuggerInstanceSettings
1377//--------------------------------------------------
1378
Greg Claytona7015092010-09-18 01:14:36 +00001379DebuggerInstanceSettings::DebuggerInstanceSettings
1380(
1381 UserSettingsController &owner,
1382 bool live_instance,
1383 const char *name
1384) :
Greg Clayton85851dd2010-12-04 00:10:17 +00001385 InstanceSettings (owner, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance),
Greg Claytona7015092010-09-18 01:14:36 +00001386 m_term_width (80),
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001387 m_prompt (),
Greg Clayton0603aa92010-10-04 01:05:56 +00001388 m_frame_format (),
1389 m_thread_format (),
Caroline Ticedaccaa92010-09-20 20:44:43 +00001390 m_script_lang (),
Jim Ingham3bcdb292010-10-04 22:44:14 +00001391 m_use_external_editor (false),
1392 m_auto_confirm_on (false)
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001393{
Caroline Ticef20e8232010-09-09 18:26:37 +00001394 // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called
1395 // until the vtables for DebuggerInstanceSettings are properly set up, i.e. AFTER all the initializers.
1396 // For this reason it has to be called here, rather than in the initializer or in the parent constructor.
Caroline Tice9e41c152010-09-16 19:05:55 +00001397 // The same is true of CreateInstanceName().
1398
1399 if (GetInstanceName() == InstanceSettings::InvalidName())
1400 {
1401 ChangeInstanceName (std::string (CreateInstanceName().AsCString()));
1402 m_owner.RegisterInstanceSettings (this);
1403 }
Caroline Ticef20e8232010-09-09 18:26:37 +00001404
1405 if (live_instance)
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001406 {
1407 const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
1408 CopyInstanceSettings (pending_settings, false);
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001409 }
1410}
1411
1412DebuggerInstanceSettings::DebuggerInstanceSettings (const DebuggerInstanceSettings &rhs) :
Greg Clayton99d0faf2010-11-18 23:32:35 +00001413 InstanceSettings (*Debugger::GetSettingsController(), CreateInstanceName ().AsCString()),
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001414 m_prompt (rhs.m_prompt),
Greg Clayton0603aa92010-10-04 01:05:56 +00001415 m_frame_format (rhs.m_frame_format),
1416 m_thread_format (rhs.m_thread_format),
Caroline Ticedaccaa92010-09-20 20:44:43 +00001417 m_script_lang (rhs.m_script_lang),
Jim Ingham3bcdb292010-10-04 22:44:14 +00001418 m_use_external_editor (rhs.m_use_external_editor),
1419 m_auto_confirm_on(rhs.m_auto_confirm_on)
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001420{
1421 const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
1422 CopyInstanceSettings (pending_settings, false);
1423 m_owner.RemovePendingSettings (m_instance_name);
1424}
1425
1426DebuggerInstanceSettings::~DebuggerInstanceSettings ()
1427{
1428}
1429
1430DebuggerInstanceSettings&
1431DebuggerInstanceSettings::operator= (const DebuggerInstanceSettings &rhs)
1432{
1433 if (this != &rhs)
1434 {
Greg Clayton1b654882010-09-19 02:33:57 +00001435 m_term_width = rhs.m_term_width;
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001436 m_prompt = rhs.m_prompt;
Greg Clayton0603aa92010-10-04 01:05:56 +00001437 m_frame_format = rhs.m_frame_format;
1438 m_thread_format = rhs.m_thread_format;
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001439 m_script_lang = rhs.m_script_lang;
Caroline Ticedaccaa92010-09-20 20:44:43 +00001440 m_use_external_editor = rhs.m_use_external_editor;
Jim Ingham3bcdb292010-10-04 22:44:14 +00001441 m_auto_confirm_on = rhs.m_auto_confirm_on;
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001442 }
1443
1444 return *this;
1445}
1446
Greg Clayton1b654882010-09-19 02:33:57 +00001447bool
1448DebuggerInstanceSettings::ValidTermWidthValue (const char *value, Error err)
1449{
1450 bool valid = false;
1451
1452 // Verify we have a value string.
1453 if (value == NULL || value[0] == '\0')
1454 {
1455 err.SetErrorString ("Missing value. Can't set terminal width without a value.\n");
1456 }
1457 else
1458 {
1459 char *end = NULL;
1460 const uint32_t width = ::strtoul (value, &end, 0);
1461
Johnny Chenea9fc182010-09-20 16:36:43 +00001462 if (end && end[0] == '\0')
Greg Clayton1b654882010-09-19 02:33:57 +00001463 {
Johnny Chen433d7742010-09-20 17:04:41 +00001464 if (width >= 10 && width <= 1024)
Greg Clayton1b654882010-09-19 02:33:57 +00001465 valid = true;
1466 else
1467 err.SetErrorString ("Invalid term-width value; value must be between 10 and 1024.\n");
1468 }
1469 else
1470 err.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string.\n", value);
1471 }
1472
1473 return valid;
1474}
1475
1476
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001477void
1478DebuggerInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name,
1479 const char *index_value,
1480 const char *value,
1481 const ConstString &instance_name,
1482 const SettingEntry &entry,
Greg Claytone0d378b2011-03-24 21:19:54 +00001483 VarSetOperationType op,
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001484 Error &err,
1485 bool pending)
1486{
Greg Clayton0603aa92010-10-04 01:05:56 +00001487
1488 if (var_name == TermWidthVarName())
1489 {
1490 if (ValidTermWidthValue (value, err))
1491 {
1492 m_term_width = ::strtoul (value, NULL, 0);
1493 }
1494 }
1495 else if (var_name == PromptVarName())
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001496 {
Caroline Tice101c7c22010-09-09 06:25:08 +00001497 UserSettingsController::UpdateStringVariable (op, m_prompt, value, err);
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001498 if (!pending)
1499 {
Caroline Tice49e27372010-09-07 18:35:40 +00001500 // 'instance_name' is actually (probably) in the form '[<instance_name>]'; if so, we need to
1501 // strip off the brackets before passing it to BroadcastPromptChange.
1502
1503 std::string tmp_instance_name (instance_name.AsCString());
1504 if ((tmp_instance_name[0] == '[')
1505 && (tmp_instance_name[instance_name.GetLength() - 1] == ']'))
1506 tmp_instance_name = tmp_instance_name.substr (1, instance_name.GetLength() - 2);
1507 ConstString new_name (tmp_instance_name.c_str());
1508
1509 BroadcastPromptChange (new_name, m_prompt.c_str());
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001510 }
1511 }
Greg Clayton0603aa92010-10-04 01:05:56 +00001512 else if (var_name == GetFrameFormatName())
1513 {
1514 UserSettingsController::UpdateStringVariable (op, m_frame_format, value, err);
1515 }
1516 else if (var_name == GetThreadFormatName())
1517 {
1518 UserSettingsController::UpdateStringVariable (op, m_thread_format, value, err);
1519 }
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001520 else if (var_name == ScriptLangVarName())
1521 {
1522 bool success;
1523 m_script_lang = Args::StringToScriptLanguage (value, eScriptLanguageDefault,
1524 &success);
1525 }
Caroline Ticedaccaa92010-09-20 20:44:43 +00001526 else if (var_name == UseExternalEditorVarName ())
1527 {
Greg Clayton385aa282011-04-22 03:55:06 +00001528 UserSettingsController::UpdateBooleanVariable (op, m_use_external_editor, value, false, err);
Caroline Ticedaccaa92010-09-20 20:44:43 +00001529 }
Jim Ingham3bcdb292010-10-04 22:44:14 +00001530 else if (var_name == AutoConfirmName ())
1531 {
Greg Clayton385aa282011-04-22 03:55:06 +00001532 UserSettingsController::UpdateBooleanVariable (op, m_auto_confirm_on, value, false, err);
Jim Ingham3bcdb292010-10-04 22:44:14 +00001533 }
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001534}
1535
Caroline Tice12cecd72010-09-20 21:37:42 +00001536bool
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001537DebuggerInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
1538 const ConstString &var_name,
Caroline Ticedaccaa92010-09-20 20:44:43 +00001539 StringList &value,
Caroline Tice12cecd72010-09-20 21:37:42 +00001540 Error *err)
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001541{
1542 if (var_name == PromptVarName())
1543 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001544 value.AppendString (m_prompt.c_str(), m_prompt.size());
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001545
1546 }
1547 else if (var_name == ScriptLangVarName())
1548 {
1549 value.AppendString (ScriptInterpreter::LanguageToString (m_script_lang).c_str());
1550 }
Caroline Tice101c7c22010-09-09 06:25:08 +00001551 else if (var_name == TermWidthVarName())
1552 {
1553 StreamString width_str;
1554 width_str.Printf ("%d", m_term_width);
1555 value.AppendString (width_str.GetData());
1556 }
Greg Clayton0603aa92010-10-04 01:05:56 +00001557 else if (var_name == GetFrameFormatName ())
1558 {
1559 value.AppendString(m_frame_format.c_str(), m_frame_format.size());
1560 }
1561 else if (var_name == GetThreadFormatName ())
1562 {
1563 value.AppendString(m_thread_format.c_str(), m_thread_format.size());
1564 }
Caroline Ticedaccaa92010-09-20 20:44:43 +00001565 else if (var_name == UseExternalEditorVarName())
1566 {
1567 if (m_use_external_editor)
1568 value.AppendString ("true");
1569 else
1570 value.AppendString ("false");
1571 }
Jim Ingham3bcdb292010-10-04 22:44:14 +00001572 else if (var_name == AutoConfirmName())
1573 {
1574 if (m_auto_confirm_on)
1575 value.AppendString ("true");
1576 else
1577 value.AppendString ("false");
1578 }
Caroline Ticedaccaa92010-09-20 20:44:43 +00001579 else
Caroline Tice12cecd72010-09-20 21:37:42 +00001580 {
1581 if (err)
1582 err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString());
1583 return false;
1584 }
1585 return true;
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001586}
1587
1588void
1589DebuggerInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings,
1590 bool pending)
1591{
1592 if (new_settings.get() == NULL)
1593 return;
1594
1595 DebuggerInstanceSettings *new_debugger_settings = (DebuggerInstanceSettings *) new_settings.get();
1596
1597 m_prompt = new_debugger_settings->m_prompt;
1598 if (!pending)
Caroline Tice49e27372010-09-07 18:35:40 +00001599 {
1600 // 'instance_name' is actually (probably) in the form '[<instance_name>]'; if so, we need to
1601 // strip off the brackets before passing it to BroadcastPromptChange.
1602
1603 std::string tmp_instance_name (m_instance_name.AsCString());
1604 if ((tmp_instance_name[0] == '[')
1605 && (tmp_instance_name[m_instance_name.GetLength() - 1] == ']'))
1606 tmp_instance_name = tmp_instance_name.substr (1, m_instance_name.GetLength() - 2);
1607 ConstString new_name (tmp_instance_name.c_str());
1608
1609 BroadcastPromptChange (new_name, m_prompt.c_str());
1610 }
Greg Clayton0603aa92010-10-04 01:05:56 +00001611 m_frame_format = new_debugger_settings->m_frame_format;
1612 m_thread_format = new_debugger_settings->m_thread_format;
Caroline Ticedaccaa92010-09-20 20:44:43 +00001613 m_term_width = new_debugger_settings->m_term_width;
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001614 m_script_lang = new_debugger_settings->m_script_lang;
Caroline Ticedaccaa92010-09-20 20:44:43 +00001615 m_use_external_editor = new_debugger_settings->m_use_external_editor;
Jim Ingham3bcdb292010-10-04 22:44:14 +00001616 m_auto_confirm_on = new_debugger_settings->m_auto_confirm_on;
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001617}
1618
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001619
1620bool
1621DebuggerInstanceSettings::BroadcastPromptChange (const ConstString &instance_name, const char *new_prompt)
1622{
1623 std::string tmp_prompt;
1624
1625 if (new_prompt != NULL)
1626 {
1627 tmp_prompt = new_prompt ;
1628 int len = tmp_prompt.size();
1629 if (len > 1
1630 && (tmp_prompt[0] == '\'' || tmp_prompt[0] == '"')
1631 && (tmp_prompt[len-1] == tmp_prompt[0]))
1632 {
1633 tmp_prompt = tmp_prompt.substr(1,len-2);
1634 }
1635 len = tmp_prompt.size();
1636 if (tmp_prompt[len-1] != ' ')
1637 tmp_prompt.append(" ");
1638 }
1639 EventSP new_event_sp;
1640 new_event_sp.reset (new Event(CommandInterpreter::eBroadcastBitResetPrompt,
1641 new EventDataBytes (tmp_prompt.c_str())));
1642
1643 if (instance_name.GetLength() != 0)
1644 {
1645 // Set prompt for a particular instance.
1646 Debugger *dbg = Debugger::FindDebuggerWithInstanceName (instance_name).get();
1647 if (dbg != NULL)
1648 {
1649 dbg->GetCommandInterpreter().BroadcastEvent (new_event_sp);
1650 }
1651 }
1652
1653 return true;
1654}
1655
1656const ConstString
1657DebuggerInstanceSettings::CreateInstanceName ()
1658{
1659 static int instance_count = 1;
1660 StreamString sstr;
1661
1662 sstr.Printf ("debugger_%d", instance_count);
1663 ++instance_count;
1664
1665 const ConstString ret_val (sstr.GetData());
1666
1667 return ret_val;
1668}
1669
1670const ConstString &
1671DebuggerInstanceSettings::PromptVarName ()
1672{
1673 static ConstString prompt_var_name ("prompt");
1674
1675 return prompt_var_name;
1676}
1677
1678const ConstString &
Greg Clayton0603aa92010-10-04 01:05:56 +00001679DebuggerInstanceSettings::GetFrameFormatName ()
1680{
1681 static ConstString prompt_var_name ("frame-format");
1682
1683 return prompt_var_name;
1684}
1685
1686const ConstString &
1687DebuggerInstanceSettings::GetThreadFormatName ()
1688{
1689 static ConstString prompt_var_name ("thread-format");
1690
1691 return prompt_var_name;
1692}
1693
1694const ConstString &
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001695DebuggerInstanceSettings::ScriptLangVarName ()
1696{
1697 static ConstString script_lang_var_name ("script-lang");
1698
1699 return script_lang_var_name;
1700}
1701
Caroline Tice101c7c22010-09-09 06:25:08 +00001702const ConstString &
1703DebuggerInstanceSettings::TermWidthVarName ()
1704{
1705 static ConstString term_width_var_name ("term-width");
1706
1707 return term_width_var_name;
1708}
1709
Caroline Ticedaccaa92010-09-20 20:44:43 +00001710const ConstString &
1711DebuggerInstanceSettings::UseExternalEditorVarName ()
1712{
1713 static ConstString use_external_editor_var_name ("use-external-editor");
1714
1715 return use_external_editor_var_name;
1716}
1717
Jim Ingham3bcdb292010-10-04 22:44:14 +00001718const ConstString &
1719DebuggerInstanceSettings::AutoConfirmName ()
1720{
1721 static ConstString use_external_editor_var_name ("auto-confirm");
1722
1723 return use_external_editor_var_name;
1724}
1725
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001726//--------------------------------------------------
Greg Clayton1b654882010-09-19 02:33:57 +00001727// SettingsController Variable Tables
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001728//--------------------------------------------------
1729
1730
1731SettingEntry
Greg Clayton1b654882010-09-19 02:33:57 +00001732Debugger::SettingsController::global_settings_table[] =
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001733{
1734 //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"},
Caroline Tice101c7c22010-09-09 06:25:08 +00001735 // The Debugger level global table should always be empty; all Debugger settable variables should be instance
1736 // variables.
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001737 { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
1738};
1739
Greg Claytonbb562b12010-10-04 02:44:26 +00001740#define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name}${function.pc-offset}}}"
Greg Clayton0603aa92010-10-04 01:05:56 +00001741#define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001742
Greg Clayton0603aa92010-10-04 01:05:56 +00001743#define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\
1744 "{, ${frame.pc}}"\
1745 MODULE_WITH_FUNC\
Greg Claytoncf4b9072010-10-04 17:04:23 +00001746 FILE_AND_LINE\
Greg Clayton0603aa92010-10-04 01:05:56 +00001747 "{, stop reason = ${thread.stop-reason}}"\
Greg Clayton0603aa92010-10-04 01:05:56 +00001748 "\\n"
1749
Greg Clayton315d2ca2010-11-02 01:53:21 +00001750//#define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\
1751// "{, ${frame.pc}}"\
1752// MODULE_WITH_FUNC\
1753// FILE_AND_LINE\
1754// "{, stop reason = ${thread.stop-reason}}"\
1755// "{, name = ${thread.name}}"\
1756// "{, queue = ${thread.queue}}"\
1757// "\\n"
1758
Greg Clayton0603aa92010-10-04 01:05:56 +00001759#define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
1760 MODULE_WITH_FUNC\
1761 FILE_AND_LINE\
1762 "\\n"
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001763
1764SettingEntry
Greg Clayton1b654882010-09-19 02:33:57 +00001765Debugger::SettingsController::instance_settings_table[] =
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001766{
Greg Clayton0603aa92010-10-04 01:05:56 +00001767// NAME Setting variable type Default Enum Init'd Hidden Help
1768// ======================= ======================= ====================== ==== ====== ====== ======================
Greg Clayton0603aa92010-10-04 01:05:56 +00001769{ "frame-format", eSetVarTypeString, DEFAULT_FRAME_FORMAT, NULL, false, false, "The default frame format string to use when displaying thread information." },
Greg Clayton54180392010-10-22 21:15:00 +00001770{ "prompt", eSetVarTypeString, "(lldb) ", NULL, false, false, "The debugger command line prompt displayed for the user." },
Jim Ingham3bcdb292010-10-04 22:44:14 +00001771{ "script-lang", eSetVarTypeString, "python", NULL, false, false, "The script language to be used for evaluating user-written scripts." },
1772{ "term-width", eSetVarTypeInt, "80" , NULL, false, false, "The maximum number of columns to use for displaying text." },
Greg Clayton0603aa92010-10-04 01:05:56 +00001773{ "thread-format", eSetVarTypeString, DEFAULT_THREAD_FORMAT, NULL, false, false, "The default thread format string to use when displaying thread information." },
Jim Ingham06e827c2010-11-11 19:26:09 +00001774{ "use-external-editor", eSetVarTypeBoolean, "false", NULL, false, false, "Whether to use an external editor or not." },
1775{ "auto-confirm", eSetVarTypeBoolean, "false", NULL, false, false, "If true all confirmation prompts will receive their default reply." },
Greg Clayton0603aa92010-10-04 01:05:56 +00001776{ NULL, eSetVarTypeNone, NULL, NULL, false, false, NULL }
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001777};