blob: ba43411dfafe3834a45389515600a6ecfe56d462 [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
10#include "lldb/lldb-private.h"
11#include "lldb/Core/ConnectionFileDescriptor.h"
12#include "lldb/Core/Debugger.h"
13#include "lldb/Core/InputReader.h"
Greg Clayton7349bd92011-05-09 20:18:18 +000014#include "lldb/Core/RegisterValue.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015#include "lldb/Core/State.h"
Jim Ingham5b52f0c2011-06-02 23:58:26 +000016#include "lldb/Core/StreamAsynchronousIO.h"
Greg Clayton1b654882010-09-19 02:33:57 +000017#include "lldb/Core/StreamString.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018#include "lldb/Core/Timer.h"
Greg Claytona3406612011-02-07 23:24:47 +000019#include "lldb/Host/Terminal.h"
Greg Clayton66111032010-06-23 01:19:29 +000020#include "lldb/Interpreter/CommandInterpreter.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/Target/TargetList.h"
22#include "lldb/Target/Process.h"
Greg Clayton1b654882010-09-19 02:33:57 +000023#include "lldb/Target/RegisterContext.h"
24#include "lldb/Target/StopInfo.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Target/Thread.h"
26
27
28using namespace lldb;
29using namespace lldb_private;
30
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031
Greg Clayton1b654882010-09-19 02:33:57 +000032static uint32_t g_shared_debugger_refcount = 0;
Caroline Ticeebc1bb22010-06-30 16:22:25 +000033static lldb::user_id_t g_unique_id = 1;
34
Greg Clayton1b654882010-09-19 02:33:57 +000035#pragma mark Static Functions
36
37static Mutex &
38GetDebuggerListMutex ()
39{
40 static Mutex g_mutex(Mutex::eMutexTypeRecursive);
41 return g_mutex;
42}
43
44typedef std::vector<DebuggerSP> DebuggerList;
45
46static DebuggerList &
47GetDebuggerList()
48{
49 // hide the static debugger list inside a singleton accessor to avoid
50 // global init contructors
51 static DebuggerList g_list;
52 return g_list;
53}
54
55
56#pragma mark Debugger
57
Greg Clayton99d0faf2010-11-18 23:32:35 +000058UserSettingsControllerSP &
59Debugger::GetSettingsController ()
60{
61 static UserSettingsControllerSP g_settings_controller;
62 return g_settings_controller;
63}
64
Caroline Tice2f88aad2011-01-14 00:29:16 +000065int
66Debugger::TestDebuggerRefCount ()
67{
68 return g_shared_debugger_refcount;
69}
70
Chris Lattner30fdc8d2010-06-08 16:52:24 +000071void
72Debugger::Initialize ()
73{
Greg Clayton66111032010-06-23 01:19:29 +000074 if (g_shared_debugger_refcount == 0)
Greg Clayton99d0faf2010-11-18 23:32:35 +000075 {
Greg Claytondbe54502010-11-19 03:46:01 +000076 lldb_private::Initialize();
Greg Clayton99d0faf2010-11-18 23:32:35 +000077 }
Greg Clayton66111032010-06-23 01:19:29 +000078 g_shared_debugger_refcount++;
Greg Clayton99d0faf2010-11-18 23:32:35 +000079
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080}
81
82void
83Debugger::Terminate ()
84{
Greg Clayton66111032010-06-23 01:19:29 +000085 if (g_shared_debugger_refcount > 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000086 {
Greg Clayton66111032010-06-23 01:19:29 +000087 g_shared_debugger_refcount--;
88 if (g_shared_debugger_refcount == 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000089 {
Greg Claytondbe54502010-11-19 03:46:01 +000090 lldb_private::WillTerminate();
91 lldb_private::Terminate();
Caroline Tice6760a512011-01-17 21:55:19 +000092
93 // Clear our master list of debugger objects
94 Mutex::Locker locker (GetDebuggerListMutex ());
95 GetDebuggerList().clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000096 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000097 }
98}
99
Caroline Tice20bd37f2011-03-10 22:14:10 +0000100void
101Debugger::SettingsInitialize ()
102{
103 static bool g_initialized = false;
104
105 if (!g_initialized)
106 {
107 g_initialized = true;
108 UserSettingsControllerSP &usc = GetSettingsController();
109 usc.reset (new SettingsController);
110 UserSettingsController::InitializeSettingsController (usc,
111 SettingsController::global_settings_table,
112 SettingsController::instance_settings_table);
113 // Now call SettingsInitialize for each settings 'child' of Debugger
114 Target::SettingsInitialize ();
115 }
116}
117
118void
119Debugger::SettingsTerminate ()
120{
121
122 // Must call SettingsTerminate() for each settings 'child' of Debugger, before terminating the Debugger's
123 // Settings.
124
125 Target::SettingsTerminate ();
126
127 // Now terminate the Debugger Settings.
128
129 UserSettingsControllerSP &usc = GetSettingsController();
130 UserSettingsController::FinalizeSettingsController (usc);
131 usc.reset();
132}
133
Greg Clayton66111032010-06-23 01:19:29 +0000134DebuggerSP
135Debugger::CreateInstance ()
136{
137 DebuggerSP debugger_sp (new Debugger);
138 // Scope for locker
139 {
140 Mutex::Locker locker (GetDebuggerListMutex ());
141 GetDebuggerList().push_back(debugger_sp);
142 }
143 return debugger_sp;
144}
145
Caroline Ticee02657b2011-01-22 01:02:07 +0000146void
147Debugger::Destroy (lldb::DebuggerSP &debugger_sp)
148{
149 if (debugger_sp.get() == NULL)
150 return;
151
152 Mutex::Locker locker (GetDebuggerListMutex ());
153 DebuggerList &debugger_list = GetDebuggerList ();
154 DebuggerList::iterator pos, end = debugger_list.end();
155 for (pos = debugger_list.begin (); pos != end; ++pos)
156 {
157 if ((*pos).get() == debugger_sp.get())
158 {
159 debugger_list.erase (pos);
160 return;
161 }
162 }
163
164}
165
Greg Clayton66111032010-06-23 01:19:29 +0000166lldb::DebuggerSP
167Debugger::GetSP ()
168{
169 lldb::DebuggerSP debugger_sp;
170
171 Mutex::Locker locker (GetDebuggerListMutex ());
172 DebuggerList &debugger_list = GetDebuggerList();
173 DebuggerList::iterator pos, end = debugger_list.end();
174 for (pos = debugger_list.begin(); pos != end; ++pos)
175 {
176 if ((*pos).get() == this)
177 {
178 debugger_sp = *pos;
179 break;
180 }
181 }
182 return debugger_sp;
183}
184
Caroline Tice3df9a8d2010-09-04 00:03:46 +0000185lldb::DebuggerSP
186Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
187{
188 lldb::DebuggerSP debugger_sp;
189
190 Mutex::Locker locker (GetDebuggerListMutex ());
191 DebuggerList &debugger_list = GetDebuggerList();
192 DebuggerList::iterator pos, end = debugger_list.end();
193
194 for (pos = debugger_list.begin(); pos != end; ++pos)
195 {
196 if ((*pos).get()->m_instance_name == instance_name)
197 {
198 debugger_sp = *pos;
199 break;
200 }
201 }
202 return debugger_sp;
203}
Greg Clayton66111032010-06-23 01:19:29 +0000204
205TargetSP
206Debugger::FindTargetWithProcessID (lldb::pid_t pid)
207{
208 lldb::TargetSP target_sp;
209 Mutex::Locker locker (GetDebuggerListMutex ());
210 DebuggerList &debugger_list = GetDebuggerList();
211 DebuggerList::iterator pos, end = debugger_list.end();
212 for (pos = debugger_list.begin(); pos != end; ++pos)
213 {
214 target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
215 if (target_sp)
216 break;
217 }
218 return target_sp;
219}
220
221
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000222Debugger::Debugger () :
Caroline Ticeebc1bb22010-06-30 16:22:25 +0000223 UserID (g_unique_id++),
Greg Claytondbe54502010-11-19 03:46:01 +0000224 DebuggerInstanceSettings (*GetSettingsController()),
Greg Claytond46c87a2010-12-04 02:39:47 +0000225 m_input_comm("debugger.input"),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000226 m_input_file (),
227 m_output_file (),
228 m_error_file (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000229 m_target_list (),
Greg Claytonded470d2011-03-19 01:12:21 +0000230 m_platform_list (),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000231 m_listener ("lldb.Debugger"),
232 m_source_manager (),
Greg Clayton66111032010-06-23 01:19:29 +0000233 m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000234 m_input_reader_stack (),
Greg Clayton4957bf62010-09-30 21:49:03 +0000235 m_input_reader_data ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000236{
Greg Clayton66111032010-06-23 01:19:29 +0000237 m_command_interpreter_ap->Initialize ();
Greg Claytonded470d2011-03-19 01:12:21 +0000238 // Always add our default platform to the platform list
239 PlatformSP default_platform_sp (Platform::GetDefaultPlatform());
240 assert (default_platform_sp.get());
241 m_platform_list.Append (default_platform_sp, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000242}
243
244Debugger::~Debugger ()
245{
Caroline Tice3d6086f2010-12-20 18:35:50 +0000246 CleanUpInputReaders();
Greg Clayton66111032010-06-23 01:19:29 +0000247 int num_targets = m_target_list.GetNumTargets();
248 for (int i = 0; i < num_targets; i++)
249 {
250 ProcessSP process_sp (m_target_list.GetTargetAtIndex (i)->GetProcessSP());
251 if (process_sp)
252 process_sp->Destroy();
253 }
254 DisconnectInput();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000255}
256
257
258bool
Greg Claytonfc3f0272011-05-29 04:06:55 +0000259Debugger::GetCloseInputOnEOF () const
260{
261 return m_input_comm.GetCloseOnEOF();
262}
263
264void
265Debugger::SetCloseInputOnEOF (bool b)
266{
267 m_input_comm.SetCloseOnEOF(b);
268}
269
270bool
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000271Debugger::GetAsyncExecution ()
272{
Greg Clayton66111032010-06-23 01:19:29 +0000273 return !m_command_interpreter_ap->GetSynchronous();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000274}
275
276void
277Debugger::SetAsyncExecution (bool async_execution)
278{
Greg Clayton66111032010-06-23 01:19:29 +0000279 m_command_interpreter_ap->SetSynchronous (!async_execution);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000280}
281
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000282
283void
284Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
285{
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000286 File &in_file = GetInputFile();
287 in_file.SetStream (fh, tranfer_ownership);
288 if (in_file.IsValid() == false)
289 in_file.SetStream (stdin, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000290
291 // Disconnect from any old connection if we had one
292 m_input_comm.Disconnect ();
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000293 m_input_comm.SetConnection (new ConnectionFileDescriptor (in_file.GetDescriptor(), true));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000294 m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this);
295
296 Error error;
297 if (m_input_comm.StartReadThread (&error) == false)
298 {
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000299 File &err_file = GetErrorFile();
300
301 err_file.Printf ("error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error");
302 exit(1);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000303 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000304}
305
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000306void
307Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
308{
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000309 File &out_file = GetOutputFile();
310 out_file.SetStream (fh, tranfer_ownership);
311 if (out_file.IsValid() == false)
312 out_file.SetStream (stdout, false);
Caroline Tice2f88aad2011-01-14 00:29:16 +0000313
314 GetCommandInterpreter().GetScriptInterpreter()->ResetOutputFileHandle (fh);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000315}
316
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000317void
318Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
319{
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000320 File &err_file = GetErrorFile();
321 err_file.SetStream (fh, tranfer_ownership);
322 if (err_file.IsValid() == false)
323 err_file.SetStream (stderr, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000324}
325
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000326ExecutionContext
Jim Ingham2976d002010-08-26 21:32:51 +0000327Debugger::GetSelectedExecutionContext ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000328{
329 ExecutionContext exe_ctx;
330 exe_ctx.Clear();
331
Jim Ingham2976d002010-08-26 21:32:51 +0000332 lldb::TargetSP target_sp = GetSelectedTarget();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000333 exe_ctx.target = target_sp.get();
334
335 if (target_sp)
336 {
337 exe_ctx.process = target_sp->GetProcessSP().get();
338 if (exe_ctx.process && exe_ctx.process->IsRunning() == false)
339 {
Jim Ingham2976d002010-08-26 21:32:51 +0000340 exe_ctx.thread = exe_ctx.process->GetThreadList().GetSelectedThread().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000341 if (exe_ctx.thread == NULL)
342 exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
343 if (exe_ctx.thread)
344 {
Jim Ingham2976d002010-08-26 21:32:51 +0000345 exe_ctx.frame = exe_ctx.thread->GetSelectedFrame().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000346 if (exe_ctx.frame == NULL)
347 exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex (0).get();
348 }
349 }
350 }
351 return exe_ctx;
352
353}
354
Caroline Ticeb44880c2011-02-10 01:15:13 +0000355InputReaderSP
356Debugger::GetCurrentInputReader ()
357{
358 InputReaderSP reader_sp;
359
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000360 if (!m_input_reader_stack.IsEmpty())
Caroline Ticeb44880c2011-02-10 01:15:13 +0000361 {
362 // Clear any finished readers from the stack
363 while (CheckIfTopInputReaderIsDone()) ;
364
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000365 if (!m_input_reader_stack.IsEmpty())
366 reader_sp = m_input_reader_stack.Top();
Caroline Ticeb44880c2011-02-10 01:15:13 +0000367 }
368
369 return reader_sp;
370}
371
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000372void
373Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len)
374{
Caroline Ticeefed6132010-11-19 20:47:54 +0000375 if (bytes_len > 0)
376 ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
377 else
378 ((Debugger *)baton)->DispatchInputEndOfFile ();
379}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000380
381
382void
383Debugger::DispatchInput (const char *bytes, size_t bytes_len)
384{
Caroline Ticeefed6132010-11-19 20:47:54 +0000385 if (bytes == NULL || bytes_len == 0)
386 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000387
388 WriteToDefaultReader (bytes, bytes_len);
389}
390
391void
Caroline Ticeefed6132010-11-19 20:47:54 +0000392Debugger::DispatchInputInterrupt ()
393{
394 m_input_reader_data.clear();
395
Caroline Ticeb44880c2011-02-10 01:15:13 +0000396 InputReaderSP reader_sp (GetCurrentInputReader ());
397 if (reader_sp)
Caroline Ticeefed6132010-11-19 20:47:54 +0000398 {
Caroline Ticeb44880c2011-02-10 01:15:13 +0000399 reader_sp->Notify (eInputReaderInterrupt);
Caroline Ticeefed6132010-11-19 20:47:54 +0000400
Caroline Ticeb44880c2011-02-10 01:15:13 +0000401 // If notifying the reader of the interrupt finished the reader, we should pop it off the stack.
Caroline Ticeefed6132010-11-19 20:47:54 +0000402 while (CheckIfTopInputReaderIsDone ()) ;
403 }
404}
405
406void
407Debugger::DispatchInputEndOfFile ()
408{
409 m_input_reader_data.clear();
410
Caroline Ticeb44880c2011-02-10 01:15:13 +0000411 InputReaderSP reader_sp (GetCurrentInputReader ());
412 if (reader_sp)
Caroline Ticeefed6132010-11-19 20:47:54 +0000413 {
Caroline Ticeb44880c2011-02-10 01:15:13 +0000414 reader_sp->Notify (eInputReaderEndOfFile);
Caroline Ticeefed6132010-11-19 20:47:54 +0000415
Caroline Ticeb44880c2011-02-10 01:15:13 +0000416 // 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 +0000417 while (CheckIfTopInputReaderIsDone ()) ;
418 }
419}
420
421void
Caroline Tice3d6086f2010-12-20 18:35:50 +0000422Debugger::CleanUpInputReaders ()
423{
424 m_input_reader_data.clear();
425
Caroline Ticeb44880c2011-02-10 01:15:13 +0000426 // 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 +0000427 while (m_input_reader_stack.GetSize() > 1)
Caroline Tice3d6086f2010-12-20 18:35:50 +0000428 {
Caroline Ticeb44880c2011-02-10 01:15:13 +0000429 InputReaderSP reader_sp (GetCurrentInputReader ());
Caroline Tice3d6086f2010-12-20 18:35:50 +0000430 if (reader_sp)
431 {
432 reader_sp->Notify (eInputReaderEndOfFile);
433 reader_sp->SetIsDone (true);
434 }
435 }
436}
437
438void
Caroline Tice969ed3d2011-05-02 20:41:46 +0000439Debugger::NotifyTopInputReader (InputReaderAction notification)
440{
441 InputReaderSP reader_sp (GetCurrentInputReader());
442 if (reader_sp)
443 {
444 reader_sp->Notify (notification);
445
446 // Flush out any input readers that are done.
447 while (CheckIfTopInputReaderIsDone ())
448 /* Do nothing. */;
449 }
450}
451
Caroline Tice9088b062011-05-09 23:06:58 +0000452bool
453Debugger::InputReaderIsTopReader (const lldb::InputReaderSP& reader_sp)
454{
Caroline Ticed61c10b2011-06-16 16:27:19 +0000455 InputReaderSP top_reader_sp (GetCurrentInputReader());
Caroline Tice9088b062011-05-09 23:06:58 +0000456
Caroline Ticed61c10b2011-06-16 16:27:19 +0000457 return (reader_sp.get() == top_reader_sp.get());
Caroline Tice9088b062011-05-09 23:06:58 +0000458}
459
460
Caroline Tice969ed3d2011-05-02 20:41:46 +0000461void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000462Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
463{
464 if (bytes && bytes_len)
465 m_input_reader_data.append (bytes, bytes_len);
466
467 if (m_input_reader_data.empty())
468 return;
469
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000470 while (!m_input_reader_stack.IsEmpty() && !m_input_reader_data.empty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000471 {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000472 // Get the input reader from the top of the stack
Caroline Ticeb44880c2011-02-10 01:15:13 +0000473 InputReaderSP reader_sp (GetCurrentInputReader ());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000474 if (!reader_sp)
475 break;
476
Greg Clayton471b31c2010-07-20 22:52:08 +0000477 size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000478 m_input_reader_data.size());
479 if (bytes_handled)
480 {
481 m_input_reader_data.erase (0, bytes_handled);
482 }
483 else
484 {
485 // No bytes were handled, we might not have reached our
486 // granularity, just return and wait for more data
487 break;
488 }
489 }
490
Caroline Ticeb44880c2011-02-10 01:15:13 +0000491 // Flush out any input readers that are done.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000492 while (CheckIfTopInputReaderIsDone ())
493 /* Do nothing. */;
494
495}
496
497void
498Debugger::PushInputReader (const InputReaderSP& reader_sp)
499{
500 if (!reader_sp)
501 return;
Caroline Ticeb44880c2011-02-10 01:15:13 +0000502
503 // Deactivate the old top reader
504 InputReaderSP top_reader_sp (GetCurrentInputReader ());
505
506 if (top_reader_sp)
507 top_reader_sp->Notify (eInputReaderDeactivate);
508
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000509 m_input_reader_stack.Push (reader_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000510 reader_sp->Notify (eInputReaderActivate);
511 ActivateInputReader (reader_sp);
512}
513
514bool
515Debugger::PopInputReader (const lldb::InputReaderSP& pop_reader_sp)
516{
517 bool result = false;
518
519 // The reader on the stop of the stack is done, so let the next
520 // read on the stack referesh its prompt and if there is one...
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000521 if (!m_input_reader_stack.IsEmpty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000522 {
Caroline Ticeb44880c2011-02-10 01:15:13 +0000523 // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000524 InputReaderSP reader_sp(m_input_reader_stack.Top());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000525
526 if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
527 {
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000528 m_input_reader_stack.Pop ();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000529 reader_sp->Notify (eInputReaderDeactivate);
530 reader_sp->Notify (eInputReaderDone);
531 result = true;
532
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000533 if (!m_input_reader_stack.IsEmpty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000534 {
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000535 reader_sp = m_input_reader_stack.Top();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000536 if (reader_sp)
537 {
538 ActivateInputReader (reader_sp);
539 reader_sp->Notify (eInputReaderReactivate);
540 }
541 }
542 }
543 }
544 return result;
545}
546
547bool
548Debugger::CheckIfTopInputReaderIsDone ()
549{
550 bool result = false;
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000551 if (!m_input_reader_stack.IsEmpty())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000552 {
Caroline Ticeb44880c2011-02-10 01:15:13 +0000553 // Cannot call GetCurrentInputReader here, as that would cause an infinite loop.
Caroline Ticed5a0a01b2011-06-02 19:18:55 +0000554 InputReaderSP reader_sp(m_input_reader_stack.Top());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000555
556 if (reader_sp && reader_sp->IsDone())
557 {
558 result = true;
559 PopInputReader (reader_sp);
560 }
561 }
562 return result;
563}
564
565void
566Debugger::ActivateInputReader (const InputReaderSP &reader_sp)
567{
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000568 int input_fd = m_input_file.GetFile().GetDescriptor();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000569
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000570 if (input_fd >= 0)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000571 {
Greg Clayton51b1e2d2011-02-09 01:08:52 +0000572 Terminal tty(input_fd);
Greg Claytona3406612011-02-07 23:24:47 +0000573
574 tty.SetEcho(reader_sp->GetEcho());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000575
Greg Claytona3406612011-02-07 23:24:47 +0000576 switch (reader_sp->GetGranularity())
577 {
578 case eInputReaderGranularityByte:
579 case eInputReaderGranularityWord:
580 tty.SetCanonical (false);
581 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000582
Greg Claytona3406612011-02-07 23:24:47 +0000583 case eInputReaderGranularityLine:
584 case eInputReaderGranularityAll:
585 tty.SetCanonical (true);
586 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000587
Greg Claytona3406612011-02-07 23:24:47 +0000588 default:
589 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000590 }
591 }
592}
Greg Clayton66111032010-06-23 01:19:29 +0000593
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000594StreamSP
595Debugger::GetAsyncOutputStream ()
596{
597 return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
598 CommandInterpreter::eBroadcastBitAsynchronousOutputData));
599}
600
601StreamSP
602Debugger::GetAsyncErrorStream ()
603{
604 return StreamSP (new StreamAsynchronousIO (GetCommandInterpreter(),
605 CommandInterpreter::eBroadcastBitAsynchronousErrorData));
606}
607
Caroline Ticeebc1bb22010-06-30 16:22:25 +0000608DebuggerSP
609Debugger::FindDebuggerWithID (lldb::user_id_t id)
610{
611 lldb::DebuggerSP debugger_sp;
612
613 Mutex::Locker locker (GetDebuggerListMutex ());
614 DebuggerList &debugger_list = GetDebuggerList();
615 DebuggerList::iterator pos, end = debugger_list.end();
616 for (pos = debugger_list.begin(); pos != end; ++pos)
617 {
618 if ((*pos).get()->GetID() == id)
619 {
620 debugger_sp = *pos;
621 break;
622 }
623 }
624 return debugger_sp;
625}
Caroline Tice3df9a8d2010-09-04 00:03:46 +0000626
Greg Clayton1b654882010-09-19 02:33:57 +0000627static void
628TestPromptFormats (StackFrame *frame)
629{
630 if (frame == NULL)
631 return;
632
633 StreamString s;
634 const char *prompt_format =
635 "{addr = '${addr}'\n}"
636 "{process.id = '${process.id}'\n}"
637 "{process.name = '${process.name}'\n}"
638 "{process.file.basename = '${process.file.basename}'\n}"
639 "{process.file.fullpath = '${process.file.fullpath}'\n}"
640 "{thread.id = '${thread.id}'\n}"
641 "{thread.index = '${thread.index}'\n}"
642 "{thread.name = '${thread.name}'\n}"
643 "{thread.queue = '${thread.queue}'\n}"
644 "{thread.stop-reason = '${thread.stop-reason}'\n}"
645 "{target.arch = '${target.arch}'\n}"
646 "{module.file.basename = '${module.file.basename}'\n}"
647 "{module.file.fullpath = '${module.file.fullpath}'\n}"
648 "{file.basename = '${file.basename}'\n}"
649 "{file.fullpath = '${file.fullpath}'\n}"
650 "{frame.index = '${frame.index}'\n}"
651 "{frame.pc = '${frame.pc}'\n}"
652 "{frame.sp = '${frame.sp}'\n}"
653 "{frame.fp = '${frame.fp}'\n}"
654 "{frame.flags = '${frame.flags}'\n}"
655 "{frame.reg.rdi = '${frame.reg.rdi}'\n}"
656 "{frame.reg.rip = '${frame.reg.rip}'\n}"
657 "{frame.reg.rsp = '${frame.reg.rsp}'\n}"
658 "{frame.reg.rbp = '${frame.reg.rbp}'\n}"
659 "{frame.reg.rflags = '${frame.reg.rflags}'\n}"
660 "{frame.reg.xmm0 = '${frame.reg.xmm0}'\n}"
661 "{frame.reg.carp = '${frame.reg.carp}'\n}"
662 "{function.id = '${function.id}'\n}"
663 "{function.name = '${function.name}'\n}"
664 "{function.addr-offset = '${function.addr-offset}'\n}"
665 "{function.line-offset = '${function.line-offset}'\n}"
666 "{function.pc-offset = '${function.pc-offset}'\n}"
667 "{line.file.basename = '${line.file.basename}'\n}"
668 "{line.file.fullpath = '${line.file.fullpath}'\n}"
669 "{line.number = '${line.number}'\n}"
670 "{line.start-addr = '${line.start-addr}'\n}"
671 "{line.end-addr = '${line.end-addr}'\n}"
672;
673
674 SymbolContext sc (frame->GetSymbolContext(eSymbolContextEverything));
675 ExecutionContext exe_ctx;
Greg Clayton0603aa92010-10-04 01:05:56 +0000676 frame->CalculateExecutionContext(exe_ctx);
Greg Clayton1b654882010-09-19 02:33:57 +0000677 const char *end = NULL;
678 if (Debugger::FormatPrompt (prompt_format, &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, &end))
679 {
680 printf("%s\n", s.GetData());
681 }
682 else
683 {
684 printf ("error: at '%s'\n", end);
685 printf ("what we got: %s\n", s.GetData());
686 }
687}
688
689bool
690Debugger::FormatPrompt
691(
692 const char *format,
693 const SymbolContext *sc,
694 const ExecutionContext *exe_ctx,
695 const Address *addr,
696 Stream &s,
697 const char **end
698)
699{
700 bool success = true;
701 const char *p;
702 for (p = format; *p != '\0'; ++p)
703 {
704 size_t non_special_chars = ::strcspn (p, "${}\\");
705 if (non_special_chars > 0)
706 {
707 if (success)
708 s.Write (p, non_special_chars);
709 p += non_special_chars;
710 }
711
712 if (*p == '\0')
713 {
714 break;
715 }
716 else if (*p == '{')
717 {
718 // Start a new scope that must have everything it needs if it is to
719 // to make it into the final output stream "s". If you want to make
720 // a format that only prints out the function or symbol name if there
721 // is one in the symbol context you can use:
722 // "{function =${function.name}}"
723 // The first '{' starts a new scope that end with the matching '}' at
724 // the end of the string. The contents "function =${function.name}"
725 // will then be evaluated and only be output if there is a function
726 // or symbol with a valid name.
727 StreamString sub_strm;
728
729 ++p; // Skip the '{'
730
731 if (FormatPrompt (p, sc, exe_ctx, addr, sub_strm, &p))
732 {
733 // The stream had all it needed
734 s.Write(sub_strm.GetData(), sub_strm.GetSize());
735 }
736 if (*p != '}')
737 {
738 success = false;
739 break;
740 }
741 }
742 else if (*p == '}')
743 {
744 // End of a enclosing scope
745 break;
746 }
747 else if (*p == '$')
748 {
749 // We have a prompt variable to print
750 ++p;
751 if (*p == '{')
752 {
753 ++p;
754 const char *var_name_begin = p;
755 const char *var_name_end = ::strchr (p, '}');
756
757 if (var_name_end && var_name_begin < var_name_end)
758 {
759 // if we have already failed to parse, skip this variable
760 if (success)
761 {
762 const char *cstr = NULL;
763 Address format_addr;
764 bool calculate_format_addr_function_offset = false;
765 // Set reg_kind and reg_num to invalid values
766 RegisterKind reg_kind = kNumRegisterKinds;
767 uint32_t reg_num = LLDB_INVALID_REGNUM;
768 FileSpec format_file_spec;
Greg Claytone0d378b2011-03-24 21:19:54 +0000769 const RegisterInfo *reg_info = NULL;
Greg Clayton1b654882010-09-19 02:33:57 +0000770 RegisterContext *reg_ctx = NULL;
771
772 // Each variable must set success to true below...
773 bool var_success = false;
774 switch (var_name_begin[0])
775 {
776 case 'a':
777 if (::strncmp (var_name_begin, "addr}", strlen("addr}")) == 0)
778 {
779 if (addr && addr->IsValid())
780 {
781 var_success = true;
782 format_addr = *addr;
783 }
784 }
785 break;
786
787 case 'p':
788 if (::strncmp (var_name_begin, "process.", strlen("process.")) == 0)
789 {
790 if (exe_ctx && exe_ctx->process != NULL)
791 {
792 var_name_begin += ::strlen ("process.");
793 if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
794 {
795 s.Printf("%i", exe_ctx->process->GetID());
796 var_success = true;
797 }
798 else if ((::strncmp (var_name_begin, "name}", strlen("name}")) == 0) ||
799 (::strncmp (var_name_begin, "file.basename}", strlen("file.basename}")) == 0) ||
800 (::strncmp (var_name_begin, "file.fullpath}", strlen("file.fullpath}")) == 0))
801 {
802 ModuleSP exe_module_sp (exe_ctx->process->GetTarget().GetExecutableModule());
803 if (exe_module_sp)
804 {
805 if (var_name_begin[0] == 'n' || var_name_begin[5] == 'f')
806 {
807 format_file_spec.GetFilename() = exe_module_sp->GetFileSpec().GetFilename();
808 var_success = format_file_spec;
809 }
810 else
811 {
812 format_file_spec = exe_module_sp->GetFileSpec();
813 var_success = format_file_spec;
814 }
815 }
816 }
817 }
818 }
819 break;
820
821 case 't':
822 if (::strncmp (var_name_begin, "thread.", strlen("thread.")) == 0)
823 {
824 if (exe_ctx && exe_ctx->thread)
825 {
826 var_name_begin += ::strlen ("thread.");
827 if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
828 {
829 s.Printf("0x%4.4x", exe_ctx->thread->GetID());
830 var_success = true;
831 }
832 else if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
833 {
834 s.Printf("%u", exe_ctx->thread->GetIndexID());
835 var_success = true;
836 }
837 else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
838 {
839 cstr = exe_ctx->thread->GetName();
840 var_success = cstr && cstr[0];
841 if (var_success)
842 s.PutCString(cstr);
843 }
844 else if (::strncmp (var_name_begin, "queue}", strlen("queue}")) == 0)
845 {
846 cstr = exe_ctx->thread->GetQueueName();
847 var_success = cstr && cstr[0];
848 if (var_success)
849 s.PutCString(cstr);
850 }
851 else if (::strncmp (var_name_begin, "stop-reason}", strlen("stop-reason}")) == 0)
852 {
Jim Inghamb15bfc72010-10-20 00:39:53 +0000853 StopInfoSP stop_info_sp = exe_ctx->thread->GetStopInfo ();
854 if (stop_info_sp)
Greg Clayton1b654882010-09-19 02:33:57 +0000855 {
Jim Inghamb15bfc72010-10-20 00:39:53 +0000856 cstr = stop_info_sp->GetDescription();
Greg Clayton1b654882010-09-19 02:33:57 +0000857 if (cstr && cstr[0])
858 {
859 s.PutCString(cstr);
860 var_success = true;
861 }
862 }
863 }
864 }
865 }
866 else if (::strncmp (var_name_begin, "target.", strlen("target.")) == 0)
867 {
Greg Clayton0603aa92010-10-04 01:05:56 +0000868 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
869 if (target)
Greg Clayton1b654882010-09-19 02:33:57 +0000870 {
Greg Clayton1b654882010-09-19 02:33:57 +0000871 var_name_begin += ::strlen ("target.");
872 if (::strncmp (var_name_begin, "arch}", strlen("arch}")) == 0)
873 {
874 ArchSpec arch (target->GetArchitecture ());
875 if (arch.IsValid())
876 {
Greg Clayton64195a22011-02-23 00:35:02 +0000877 s.PutCString (arch.GetArchitectureName());
Greg Clayton1b654882010-09-19 02:33:57 +0000878 var_success = true;
879 }
880 }
881 }
882 }
883 break;
884
885
886 case 'm':
887 if (::strncmp (var_name_begin, "module.", strlen("module.")) == 0)
888 {
Greg Clayton0603aa92010-10-04 01:05:56 +0000889 if (sc && sc->module_sp.get())
Greg Clayton1b654882010-09-19 02:33:57 +0000890 {
Greg Clayton0603aa92010-10-04 01:05:56 +0000891 Module *module = sc->module_sp.get();
Greg Clayton1b654882010-09-19 02:33:57 +0000892 var_name_begin += ::strlen ("module.");
893
894 if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
895 {
896 if (module->GetFileSpec())
897 {
898 var_name_begin += ::strlen ("file.");
899
900 if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
901 {
902 format_file_spec.GetFilename() = module->GetFileSpec().GetFilename();
903 var_success = format_file_spec;
904 }
905 else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
906 {
907 format_file_spec = module->GetFileSpec();
908 var_success = format_file_spec;
909 }
910 }
911 }
912 }
913 }
914 break;
915
916
917 case 'f':
918 if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
919 {
920 if (sc && sc->comp_unit != NULL)
921 {
922 var_name_begin += ::strlen ("file.");
923
924 if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
925 {
926 format_file_spec.GetFilename() = sc->comp_unit->GetFilename();
927 var_success = format_file_spec;
928 }
929 else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
930 {
931 format_file_spec = *sc->comp_unit;
932 var_success = format_file_spec;
933 }
934 }
935 }
936 else if (::strncmp (var_name_begin, "frame.", strlen("frame.")) == 0)
937 {
938 if (exe_ctx && exe_ctx->frame)
939 {
940 var_name_begin += ::strlen ("frame.");
941 if (::strncmp (var_name_begin, "index}", strlen("index}")) == 0)
942 {
943 s.Printf("%u", exe_ctx->frame->GetFrameIndex());
944 var_success = true;
945 }
946 else if (::strncmp (var_name_begin, "pc}", strlen("pc}")) == 0)
947 {
948 reg_kind = eRegisterKindGeneric;
949 reg_num = LLDB_REGNUM_GENERIC_PC;
950 var_success = true;
951 }
952 else if (::strncmp (var_name_begin, "sp}", strlen("sp}")) == 0)
953 {
954 reg_kind = eRegisterKindGeneric;
955 reg_num = LLDB_REGNUM_GENERIC_SP;
956 var_success = true;
957 }
958 else if (::strncmp (var_name_begin, "fp}", strlen("fp}")) == 0)
959 {
960 reg_kind = eRegisterKindGeneric;
961 reg_num = LLDB_REGNUM_GENERIC_FP;
962 var_success = true;
963 }
964 else if (::strncmp (var_name_begin, "flags}", strlen("flags}")) == 0)
965 {
966 reg_kind = eRegisterKindGeneric;
967 reg_num = LLDB_REGNUM_GENERIC_FLAGS;
968 var_success = true;
969 }
970 else if (::strncmp (var_name_begin, "reg.", strlen ("reg.")) == 0)
971 {
Greg Clayton5ccbd292011-01-06 22:15:06 +0000972 reg_ctx = exe_ctx->frame->GetRegisterContext().get();
Greg Clayton1b654882010-09-19 02:33:57 +0000973 if (reg_ctx)
974 {
975 var_name_begin += ::strlen ("reg.");
976 if (var_name_begin < var_name_end)
977 {
978 std::string reg_name (var_name_begin, var_name_end);
979 reg_info = reg_ctx->GetRegisterInfoByName (reg_name.c_str());
980 if (reg_info)
981 var_success = true;
982 }
983 }
984 }
985 }
986 }
987 else if (::strncmp (var_name_begin, "function.", strlen("function.")) == 0)
988 {
989 if (sc && (sc->function != NULL || sc->symbol != NULL))
990 {
991 var_name_begin += ::strlen ("function.");
992 if (::strncmp (var_name_begin, "id}", strlen("id}")) == 0)
993 {
994 if (sc->function)
995 s.Printf("function{0x%8.8x}", sc->function->GetID());
996 else
997 s.Printf("symbol[%u]", sc->symbol->GetID());
998
999 var_success = true;
1000 }
1001 else if (::strncmp (var_name_begin, "name}", strlen("name}")) == 0)
1002 {
1003 if (sc->function)
1004 cstr = sc->function->GetName().AsCString (NULL);
1005 else if (sc->symbol)
1006 cstr = sc->symbol->GetName().AsCString (NULL);
1007 if (cstr)
1008 {
1009 s.PutCString(cstr);
Greg Clayton0d9c9932010-10-04 17:26:49 +00001010
1011 if (sc->block)
1012 {
1013 Block *inline_block = sc->block->GetContainingInlinedBlock ();
1014 if (inline_block)
1015 {
1016 const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
1017 if (inline_info)
1018 {
1019 s.PutCString(" [inlined] ");
1020 inline_info->GetName().Dump(&s);
1021 }
1022 }
1023 }
Greg Clayton1b654882010-09-19 02:33:57 +00001024 var_success = true;
1025 }
1026 }
1027 else if (::strncmp (var_name_begin, "addr-offset}", strlen("addr-offset}")) == 0)
1028 {
1029 var_success = addr != NULL;
1030 if (var_success)
1031 {
1032 format_addr = *addr;
1033 calculate_format_addr_function_offset = true;
1034 }
1035 }
1036 else if (::strncmp (var_name_begin, "line-offset}", strlen("line-offset}")) == 0)
1037 {
1038 var_success = sc->line_entry.range.GetBaseAddress().IsValid();
1039 if (var_success)
1040 {
1041 format_addr = sc->line_entry.range.GetBaseAddress();
1042 calculate_format_addr_function_offset = true;
1043 }
1044 }
1045 else if (::strncmp (var_name_begin, "pc-offset}", strlen("pc-offset}")) == 0)
1046 {
1047 var_success = exe_ctx->frame;
1048 if (var_success)
1049 {
1050 format_addr = exe_ctx->frame->GetFrameCodeAddress();
1051 calculate_format_addr_function_offset = true;
1052 }
1053 }
1054 }
1055 }
1056 break;
1057
1058 case 'l':
1059 if (::strncmp (var_name_begin, "line.", strlen("line.")) == 0)
1060 {
1061 if (sc && sc->line_entry.IsValid())
1062 {
1063 var_name_begin += ::strlen ("line.");
1064 if (::strncmp (var_name_begin, "file.", strlen("file.")) == 0)
1065 {
1066 var_name_begin += ::strlen ("file.");
1067
1068 if (::strncmp (var_name_begin, "basename}", strlen("basename}")) == 0)
1069 {
1070 format_file_spec.GetFilename() = sc->line_entry.file.GetFilename();
1071 var_success = format_file_spec;
1072 }
1073 else if (::strncmp (var_name_begin, "fullpath}", strlen("fullpath}")) == 0)
1074 {
1075 format_file_spec = sc->line_entry.file;
1076 var_success = format_file_spec;
1077 }
1078 }
1079 else if (::strncmp (var_name_begin, "number}", strlen("number}")) == 0)
1080 {
1081 var_success = true;
1082 s.Printf("%u", sc->line_entry.line);
1083 }
1084 else if ((::strncmp (var_name_begin, "start-addr}", strlen("start-addr}")) == 0) ||
1085 (::strncmp (var_name_begin, "end-addr}", strlen("end-addr}")) == 0))
1086 {
1087 var_success = sc && sc->line_entry.range.GetBaseAddress().IsValid();
1088 if (var_success)
1089 {
1090 format_addr = sc->line_entry.range.GetBaseAddress();
1091 if (var_name_begin[0] == 'e')
1092 format_addr.Slide (sc->line_entry.range.GetByteSize());
1093 }
1094 }
1095 }
1096 }
1097 break;
1098 }
1099
1100 if (var_success)
1101 {
1102 // If format addr is valid, then we need to print an address
1103 if (reg_num != LLDB_INVALID_REGNUM)
1104 {
1105 // We have a register value to display...
1106 if (reg_num == LLDB_REGNUM_GENERIC_PC && reg_kind == eRegisterKindGeneric)
1107 {
1108 format_addr = exe_ctx->frame->GetFrameCodeAddress();
1109 }
1110 else
1111 {
1112 if (reg_ctx == NULL)
Greg Clayton5ccbd292011-01-06 22:15:06 +00001113 reg_ctx = exe_ctx->frame->GetRegisterContext().get();
Greg Clayton1b654882010-09-19 02:33:57 +00001114
1115 if (reg_ctx)
1116 {
1117 if (reg_kind != kNumRegisterKinds)
1118 reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
1119 reg_info = reg_ctx->GetRegisterInfoAtIndex (reg_num);
1120 var_success = reg_info != NULL;
1121 }
1122 }
1123 }
1124
1125 if (reg_info != NULL)
1126 {
Greg Clayton7349bd92011-05-09 20:18:18 +00001127 RegisterValue reg_value;
1128 var_success = reg_ctx->ReadRegister (reg_info, reg_value);
1129 if (var_success)
Greg Clayton1b654882010-09-19 02:33:57 +00001130 {
Greg Clayton9a8fa912011-05-15 04:12:07 +00001131 reg_value.Dump(&s, reg_info, false, false, eFormatDefault);
Greg Clayton1b654882010-09-19 02:33:57 +00001132 }
1133 }
1134
1135 if (format_file_spec)
1136 {
1137 s << format_file_spec;
1138 }
1139
1140 // If format addr is valid, then we need to print an address
1141 if (format_addr.IsValid())
1142 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001143 var_success = false;
1144
Greg Clayton1b654882010-09-19 02:33:57 +00001145 if (calculate_format_addr_function_offset)
1146 {
1147 Address func_addr;
Greg Clayton1b654882010-09-19 02:33:57 +00001148
Greg Clayton0603aa92010-10-04 01:05:56 +00001149 if (sc)
1150 {
1151 if (sc->function)
Greg Clayton0d9c9932010-10-04 17:26:49 +00001152 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001153 func_addr = sc->function->GetAddressRange().GetBaseAddress();
Greg Clayton0d9c9932010-10-04 17:26:49 +00001154 if (sc->block)
1155 {
1156 // Check to make sure we aren't in an inline
1157 // function. If we are, use the inline block
1158 // range that contains "format_addr" since
1159 // blocks can be discontiguous.
1160 Block *inline_block = sc->block->GetContainingInlinedBlock ();
1161 AddressRange inline_range;
1162 if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
1163 func_addr = inline_range.GetBaseAddress();
1164 }
1165 }
Greg Clayton0603aa92010-10-04 01:05:56 +00001166 else if (sc->symbol && sc->symbol->GetAddressRangePtr())
1167 func_addr = sc->symbol->GetAddressRangePtr()->GetBaseAddress();
1168 }
1169
1170 if (func_addr.IsValid())
Greg Clayton1b654882010-09-19 02:33:57 +00001171 {
1172 if (func_addr.GetSection() == format_addr.GetSection())
1173 {
1174 addr_t func_file_addr = func_addr.GetFileAddress();
1175 addr_t addr_file_addr = format_addr.GetFileAddress();
1176 if (addr_file_addr > func_file_addr)
Greg Clayton1b654882010-09-19 02:33:57 +00001177 s.Printf(" + %llu", addr_file_addr - func_file_addr);
Greg Clayton1b654882010-09-19 02:33:57 +00001178 else if (addr_file_addr < func_file_addr)
Greg Clayton1b654882010-09-19 02:33:57 +00001179 s.Printf(" - %llu", func_file_addr - addr_file_addr);
Greg Clayton0603aa92010-10-04 01:05:56 +00001180 var_success = true;
Greg Clayton1b654882010-09-19 02:33:57 +00001181 }
1182 else
Greg Clayton0603aa92010-10-04 01:05:56 +00001183 {
1184 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
1185 if (target)
1186 {
1187 addr_t func_load_addr = func_addr.GetLoadAddress (target);
1188 addr_t addr_load_addr = format_addr.GetLoadAddress (target);
1189 if (addr_load_addr > func_load_addr)
1190 s.Printf(" + %llu", addr_load_addr - func_load_addr);
1191 else if (addr_load_addr < func_load_addr)
1192 s.Printf(" - %llu", func_load_addr - addr_load_addr);
1193 var_success = true;
1194 }
1195 }
Greg Clayton1b654882010-09-19 02:33:57 +00001196 }
1197 }
1198 else
1199 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001200 Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
Greg Clayton1b654882010-09-19 02:33:57 +00001201 addr_t vaddr = LLDB_INVALID_ADDRESS;
Greg Clayton0603aa92010-10-04 01:05:56 +00001202 if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
1203 vaddr = format_addr.GetLoadAddress (target);
Greg Clayton1b654882010-09-19 02:33:57 +00001204 if (vaddr == LLDB_INVALID_ADDRESS)
1205 vaddr = format_addr.GetFileAddress ();
1206
1207 if (vaddr != LLDB_INVALID_ADDRESS)
Greg Clayton0603aa92010-10-04 01:05:56 +00001208 {
Greg Clayton514487e2011-02-15 21:59:32 +00001209 int addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
Greg Clayton35f1a0d2010-11-19 04:16:11 +00001210 if (addr_width == 0)
1211 addr_width = 16;
1212 s.Printf("0x%*.*llx", addr_width, addr_width, vaddr);
Greg Clayton0603aa92010-10-04 01:05:56 +00001213 var_success = true;
1214 }
Greg Clayton1b654882010-09-19 02:33:57 +00001215 }
1216 }
1217 }
1218
1219 if (var_success == false)
1220 success = false;
1221 }
1222 p = var_name_end;
1223 }
1224 else
1225 break;
1226 }
1227 else
1228 {
1229 // We got a dollar sign with no '{' after it, it must just be a dollar sign
1230 s.PutChar(*p);
1231 }
1232 }
1233 else if (*p == '\\')
1234 {
1235 ++p; // skip the slash
1236 switch (*p)
1237 {
1238 case 'a': s.PutChar ('\a'); break;
1239 case 'b': s.PutChar ('\b'); break;
1240 case 'f': s.PutChar ('\f'); break;
1241 case 'n': s.PutChar ('\n'); break;
1242 case 'r': s.PutChar ('\r'); break;
1243 case 't': s.PutChar ('\t'); break;
1244 case 'v': s.PutChar ('\v'); break;
1245 case '\'': s.PutChar ('\''); break;
1246 case '\\': s.PutChar ('\\'); break;
1247 case '0':
1248 // 1 to 3 octal chars
1249 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001250 // Make a string that can hold onto the initial zero char,
1251 // up to 3 octal digits, and a terminating NULL.
1252 char oct_str[5] = { 0, 0, 0, 0, 0 };
1253
1254 int i;
1255 for (i=0; (p[i] >= '0' && p[i] <= '7') && i<4; ++i)
1256 oct_str[i] = p[i];
1257
1258 // We don't want to consume the last octal character since
1259 // the main for loop will do this for us, so we advance p by
1260 // one less than i (even if i is zero)
1261 p += i - 1;
1262 unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
1263 if (octal_value <= UINT8_MAX)
Greg Clayton1b654882010-09-19 02:33:57 +00001264 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001265 char octal_char = octal_value;
1266 s.Write (&octal_char, 1);
Greg Clayton1b654882010-09-19 02:33:57 +00001267 }
Greg Clayton1b654882010-09-19 02:33:57 +00001268 }
1269 break;
1270
1271 case 'x':
1272 // hex number in the format
Greg Clayton0603aa92010-10-04 01:05:56 +00001273 if (isxdigit(p[1]))
Greg Clayton1b654882010-09-19 02:33:57 +00001274 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001275 ++p; // Skip the 'x'
Greg Clayton1b654882010-09-19 02:33:57 +00001276
Greg Clayton0603aa92010-10-04 01:05:56 +00001277 // Make a string that can hold onto two hex chars plus a
1278 // NULL terminator
1279 char hex_str[3] = { 0,0,0 };
1280 hex_str[0] = *p;
1281 if (isxdigit(p[1]))
Greg Clayton1b654882010-09-19 02:33:57 +00001282 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001283 ++p; // Skip the first of the two hex chars
1284 hex_str[1] = *p;
1285 }
1286
1287 unsigned long hex_value = strtoul (hex_str, NULL, 16);
1288 if (hex_value <= UINT8_MAX)
Greg Clayton1b654882010-09-19 02:33:57 +00001289 s.PutChar (hex_value);
Greg Clayton0603aa92010-10-04 01:05:56 +00001290 }
1291 else
1292 {
1293 s.PutChar('x');
Greg Clayton1b654882010-09-19 02:33:57 +00001294 }
1295 break;
1296
1297 default:
Greg Clayton0603aa92010-10-04 01:05:56 +00001298 // Just desensitize any other character by just printing what
1299 // came after the '\'
1300 s << *p;
Greg Clayton1b654882010-09-19 02:33:57 +00001301 break;
1302
1303 }
1304
1305 }
1306 }
1307 if (end)
1308 *end = p;
1309 return success;
1310}
1311
1312#pragma mark Debugger::SettingsController
1313
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001314//--------------------------------------------------
Greg Clayton1b654882010-09-19 02:33:57 +00001315// class Debugger::SettingsController
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001316//--------------------------------------------------
1317
Greg Clayton1b654882010-09-19 02:33:57 +00001318Debugger::SettingsController::SettingsController () :
Caroline Tice101c7c22010-09-09 06:25:08 +00001319 UserSettingsController ("", lldb::UserSettingsControllerSP())
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001320{
Caroline Tice91123da2010-09-08 17:48:55 +00001321 m_default_settings.reset (new DebuggerInstanceSettings (*this, false,
1322 InstanceSettings::GetDefaultName().AsCString()));
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001323}
1324
Greg Clayton1b654882010-09-19 02:33:57 +00001325Debugger::SettingsController::~SettingsController ()
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001326{
1327}
1328
1329
1330lldb::InstanceSettingsSP
Greg Clayton1b654882010-09-19 02:33:57 +00001331Debugger::SettingsController::CreateInstanceSettings (const char *instance_name)
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001332{
Greg Claytondbe54502010-11-19 03:46:01 +00001333 DebuggerInstanceSettings *new_settings = new DebuggerInstanceSettings (*GetSettingsController(),
Caroline Tice91123da2010-09-08 17:48:55 +00001334 false, instance_name);
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001335 lldb::InstanceSettingsSP new_settings_sp (new_settings);
1336 return new_settings_sp;
1337}
1338
Greg Clayton1b654882010-09-19 02:33:57 +00001339#pragma mark DebuggerInstanceSettings
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001340//--------------------------------------------------
1341// class DebuggerInstanceSettings
1342//--------------------------------------------------
1343
Greg Claytona7015092010-09-18 01:14:36 +00001344DebuggerInstanceSettings::DebuggerInstanceSettings
1345(
1346 UserSettingsController &owner,
1347 bool live_instance,
1348 const char *name
1349) :
Greg Clayton85851dd2010-12-04 00:10:17 +00001350 InstanceSettings (owner, name ? name : InstanceSettings::InvalidName().AsCString(), live_instance),
Greg Claytona7015092010-09-18 01:14:36 +00001351 m_term_width (80),
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001352 m_prompt (),
Greg Clayton0603aa92010-10-04 01:05:56 +00001353 m_frame_format (),
1354 m_thread_format (),
Caroline Ticedaccaa92010-09-20 20:44:43 +00001355 m_script_lang (),
Jim Ingham3bcdb292010-10-04 22:44:14 +00001356 m_use_external_editor (false),
1357 m_auto_confirm_on (false)
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001358{
Caroline Ticef20e8232010-09-09 18:26:37 +00001359 // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called
1360 // until the vtables for DebuggerInstanceSettings are properly set up, i.e. AFTER all the initializers.
1361 // 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 +00001362 // The same is true of CreateInstanceName().
1363
1364 if (GetInstanceName() == InstanceSettings::InvalidName())
1365 {
1366 ChangeInstanceName (std::string (CreateInstanceName().AsCString()));
1367 m_owner.RegisterInstanceSettings (this);
1368 }
Caroline Ticef20e8232010-09-09 18:26:37 +00001369
1370 if (live_instance)
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001371 {
1372 const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
1373 CopyInstanceSettings (pending_settings, false);
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001374 }
1375}
1376
1377DebuggerInstanceSettings::DebuggerInstanceSettings (const DebuggerInstanceSettings &rhs) :
Greg Clayton99d0faf2010-11-18 23:32:35 +00001378 InstanceSettings (*Debugger::GetSettingsController(), CreateInstanceName ().AsCString()),
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001379 m_prompt (rhs.m_prompt),
Greg Clayton0603aa92010-10-04 01:05:56 +00001380 m_frame_format (rhs.m_frame_format),
1381 m_thread_format (rhs.m_thread_format),
Caroline Ticedaccaa92010-09-20 20:44:43 +00001382 m_script_lang (rhs.m_script_lang),
Jim Ingham3bcdb292010-10-04 22:44:14 +00001383 m_use_external_editor (rhs.m_use_external_editor),
1384 m_auto_confirm_on(rhs.m_auto_confirm_on)
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001385{
1386 const lldb::InstanceSettingsSP &pending_settings = m_owner.FindPendingSettings (m_instance_name);
1387 CopyInstanceSettings (pending_settings, false);
1388 m_owner.RemovePendingSettings (m_instance_name);
1389}
1390
1391DebuggerInstanceSettings::~DebuggerInstanceSettings ()
1392{
1393}
1394
1395DebuggerInstanceSettings&
1396DebuggerInstanceSettings::operator= (const DebuggerInstanceSettings &rhs)
1397{
1398 if (this != &rhs)
1399 {
Greg Clayton1b654882010-09-19 02:33:57 +00001400 m_term_width = rhs.m_term_width;
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001401 m_prompt = rhs.m_prompt;
Greg Clayton0603aa92010-10-04 01:05:56 +00001402 m_frame_format = rhs.m_frame_format;
1403 m_thread_format = rhs.m_thread_format;
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001404 m_script_lang = rhs.m_script_lang;
Caroline Ticedaccaa92010-09-20 20:44:43 +00001405 m_use_external_editor = rhs.m_use_external_editor;
Jim Ingham3bcdb292010-10-04 22:44:14 +00001406 m_auto_confirm_on = rhs.m_auto_confirm_on;
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001407 }
1408
1409 return *this;
1410}
1411
Greg Clayton1b654882010-09-19 02:33:57 +00001412bool
1413DebuggerInstanceSettings::ValidTermWidthValue (const char *value, Error err)
1414{
1415 bool valid = false;
1416
1417 // Verify we have a value string.
1418 if (value == NULL || value[0] == '\0')
1419 {
1420 err.SetErrorString ("Missing value. Can't set terminal width without a value.\n");
1421 }
1422 else
1423 {
1424 char *end = NULL;
1425 const uint32_t width = ::strtoul (value, &end, 0);
1426
Johnny Chenea9fc182010-09-20 16:36:43 +00001427 if (end && end[0] == '\0')
Greg Clayton1b654882010-09-19 02:33:57 +00001428 {
Johnny Chen433d7742010-09-20 17:04:41 +00001429 if (width >= 10 && width <= 1024)
Greg Clayton1b654882010-09-19 02:33:57 +00001430 valid = true;
1431 else
1432 err.SetErrorString ("Invalid term-width value; value must be between 10 and 1024.\n");
1433 }
1434 else
1435 err.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string.\n", value);
1436 }
1437
1438 return valid;
1439}
1440
1441
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001442void
1443DebuggerInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_name,
1444 const char *index_value,
1445 const char *value,
1446 const ConstString &instance_name,
1447 const SettingEntry &entry,
Greg Claytone0d378b2011-03-24 21:19:54 +00001448 VarSetOperationType op,
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001449 Error &err,
1450 bool pending)
1451{
Greg Clayton0603aa92010-10-04 01:05:56 +00001452
1453 if (var_name == TermWidthVarName())
1454 {
1455 if (ValidTermWidthValue (value, err))
1456 {
1457 m_term_width = ::strtoul (value, NULL, 0);
1458 }
1459 }
1460 else if (var_name == PromptVarName())
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001461 {
Caroline Tice101c7c22010-09-09 06:25:08 +00001462 UserSettingsController::UpdateStringVariable (op, m_prompt, value, err);
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001463 if (!pending)
1464 {
Caroline Tice49e27372010-09-07 18:35:40 +00001465 // 'instance_name' is actually (probably) in the form '[<instance_name>]'; if so, we need to
1466 // strip off the brackets before passing it to BroadcastPromptChange.
1467
1468 std::string tmp_instance_name (instance_name.AsCString());
1469 if ((tmp_instance_name[0] == '[')
1470 && (tmp_instance_name[instance_name.GetLength() - 1] == ']'))
1471 tmp_instance_name = tmp_instance_name.substr (1, instance_name.GetLength() - 2);
1472 ConstString new_name (tmp_instance_name.c_str());
1473
1474 BroadcastPromptChange (new_name, m_prompt.c_str());
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001475 }
1476 }
Greg Clayton0603aa92010-10-04 01:05:56 +00001477 else if (var_name == GetFrameFormatName())
1478 {
1479 UserSettingsController::UpdateStringVariable (op, m_frame_format, value, err);
1480 }
1481 else if (var_name == GetThreadFormatName())
1482 {
1483 UserSettingsController::UpdateStringVariable (op, m_thread_format, value, err);
1484 }
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001485 else if (var_name == ScriptLangVarName())
1486 {
1487 bool success;
1488 m_script_lang = Args::StringToScriptLanguage (value, eScriptLanguageDefault,
1489 &success);
1490 }
Caroline Ticedaccaa92010-09-20 20:44:43 +00001491 else if (var_name == UseExternalEditorVarName ())
1492 {
Greg Clayton385aa282011-04-22 03:55:06 +00001493 UserSettingsController::UpdateBooleanVariable (op, m_use_external_editor, value, false, err);
Caroline Ticedaccaa92010-09-20 20:44:43 +00001494 }
Jim Ingham3bcdb292010-10-04 22:44:14 +00001495 else if (var_name == AutoConfirmName ())
1496 {
Greg Clayton385aa282011-04-22 03:55:06 +00001497 UserSettingsController::UpdateBooleanVariable (op, m_auto_confirm_on, value, false, err);
Jim Ingham3bcdb292010-10-04 22:44:14 +00001498 }
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001499}
1500
Caroline Tice12cecd72010-09-20 21:37:42 +00001501bool
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001502DebuggerInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
1503 const ConstString &var_name,
Caroline Ticedaccaa92010-09-20 20:44:43 +00001504 StringList &value,
Caroline Tice12cecd72010-09-20 21:37:42 +00001505 Error *err)
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001506{
1507 if (var_name == PromptVarName())
1508 {
Greg Clayton0603aa92010-10-04 01:05:56 +00001509 value.AppendString (m_prompt.c_str(), m_prompt.size());
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001510
1511 }
1512 else if (var_name == ScriptLangVarName())
1513 {
1514 value.AppendString (ScriptInterpreter::LanguageToString (m_script_lang).c_str());
1515 }
Caroline Tice101c7c22010-09-09 06:25:08 +00001516 else if (var_name == TermWidthVarName())
1517 {
1518 StreamString width_str;
1519 width_str.Printf ("%d", m_term_width);
1520 value.AppendString (width_str.GetData());
1521 }
Greg Clayton0603aa92010-10-04 01:05:56 +00001522 else if (var_name == GetFrameFormatName ())
1523 {
1524 value.AppendString(m_frame_format.c_str(), m_frame_format.size());
1525 }
1526 else if (var_name == GetThreadFormatName ())
1527 {
1528 value.AppendString(m_thread_format.c_str(), m_thread_format.size());
1529 }
Caroline Ticedaccaa92010-09-20 20:44:43 +00001530 else if (var_name == UseExternalEditorVarName())
1531 {
1532 if (m_use_external_editor)
1533 value.AppendString ("true");
1534 else
1535 value.AppendString ("false");
1536 }
Jim Ingham3bcdb292010-10-04 22:44:14 +00001537 else if (var_name == AutoConfirmName())
1538 {
1539 if (m_auto_confirm_on)
1540 value.AppendString ("true");
1541 else
1542 value.AppendString ("false");
1543 }
Caroline Ticedaccaa92010-09-20 20:44:43 +00001544 else
Caroline Tice12cecd72010-09-20 21:37:42 +00001545 {
1546 if (err)
1547 err->SetErrorStringWithFormat ("unrecognized variable name '%s'", var_name.AsCString());
1548 return false;
1549 }
1550 return true;
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001551}
1552
1553void
1554DebuggerInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &new_settings,
1555 bool pending)
1556{
1557 if (new_settings.get() == NULL)
1558 return;
1559
1560 DebuggerInstanceSettings *new_debugger_settings = (DebuggerInstanceSettings *) new_settings.get();
1561
1562 m_prompt = new_debugger_settings->m_prompt;
1563 if (!pending)
Caroline Tice49e27372010-09-07 18:35:40 +00001564 {
1565 // 'instance_name' is actually (probably) in the form '[<instance_name>]'; if so, we need to
1566 // strip off the brackets before passing it to BroadcastPromptChange.
1567
1568 std::string tmp_instance_name (m_instance_name.AsCString());
1569 if ((tmp_instance_name[0] == '[')
1570 && (tmp_instance_name[m_instance_name.GetLength() - 1] == ']'))
1571 tmp_instance_name = tmp_instance_name.substr (1, m_instance_name.GetLength() - 2);
1572 ConstString new_name (tmp_instance_name.c_str());
1573
1574 BroadcastPromptChange (new_name, m_prompt.c_str());
1575 }
Greg Clayton0603aa92010-10-04 01:05:56 +00001576 m_frame_format = new_debugger_settings->m_frame_format;
1577 m_thread_format = new_debugger_settings->m_thread_format;
Caroline Ticedaccaa92010-09-20 20:44:43 +00001578 m_term_width = new_debugger_settings->m_term_width;
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001579 m_script_lang = new_debugger_settings->m_script_lang;
Caroline Ticedaccaa92010-09-20 20:44:43 +00001580 m_use_external_editor = new_debugger_settings->m_use_external_editor;
Jim Ingham3bcdb292010-10-04 22:44:14 +00001581 m_auto_confirm_on = new_debugger_settings->m_auto_confirm_on;
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001582}
1583
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001584
1585bool
1586DebuggerInstanceSettings::BroadcastPromptChange (const ConstString &instance_name, const char *new_prompt)
1587{
1588 std::string tmp_prompt;
1589
1590 if (new_prompt != NULL)
1591 {
1592 tmp_prompt = new_prompt ;
1593 int len = tmp_prompt.size();
1594 if (len > 1
1595 && (tmp_prompt[0] == '\'' || tmp_prompt[0] == '"')
1596 && (tmp_prompt[len-1] == tmp_prompt[0]))
1597 {
1598 tmp_prompt = tmp_prompt.substr(1,len-2);
1599 }
1600 len = tmp_prompt.size();
1601 if (tmp_prompt[len-1] != ' ')
1602 tmp_prompt.append(" ");
1603 }
1604 EventSP new_event_sp;
1605 new_event_sp.reset (new Event(CommandInterpreter::eBroadcastBitResetPrompt,
1606 new EventDataBytes (tmp_prompt.c_str())));
1607
1608 if (instance_name.GetLength() != 0)
1609 {
1610 // Set prompt for a particular instance.
1611 Debugger *dbg = Debugger::FindDebuggerWithInstanceName (instance_name).get();
1612 if (dbg != NULL)
1613 {
1614 dbg->GetCommandInterpreter().BroadcastEvent (new_event_sp);
1615 }
1616 }
1617
1618 return true;
1619}
1620
1621const ConstString
1622DebuggerInstanceSettings::CreateInstanceName ()
1623{
1624 static int instance_count = 1;
1625 StreamString sstr;
1626
1627 sstr.Printf ("debugger_%d", instance_count);
1628 ++instance_count;
1629
1630 const ConstString ret_val (sstr.GetData());
1631
1632 return ret_val;
1633}
1634
1635const ConstString &
1636DebuggerInstanceSettings::PromptVarName ()
1637{
1638 static ConstString prompt_var_name ("prompt");
1639
1640 return prompt_var_name;
1641}
1642
1643const ConstString &
Greg Clayton0603aa92010-10-04 01:05:56 +00001644DebuggerInstanceSettings::GetFrameFormatName ()
1645{
1646 static ConstString prompt_var_name ("frame-format");
1647
1648 return prompt_var_name;
1649}
1650
1651const ConstString &
1652DebuggerInstanceSettings::GetThreadFormatName ()
1653{
1654 static ConstString prompt_var_name ("thread-format");
1655
1656 return prompt_var_name;
1657}
1658
1659const ConstString &
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001660DebuggerInstanceSettings::ScriptLangVarName ()
1661{
1662 static ConstString script_lang_var_name ("script-lang");
1663
1664 return script_lang_var_name;
1665}
1666
Caroline Tice101c7c22010-09-09 06:25:08 +00001667const ConstString &
1668DebuggerInstanceSettings::TermWidthVarName ()
1669{
1670 static ConstString term_width_var_name ("term-width");
1671
1672 return term_width_var_name;
1673}
1674
Caroline Ticedaccaa92010-09-20 20:44:43 +00001675const ConstString &
1676DebuggerInstanceSettings::UseExternalEditorVarName ()
1677{
1678 static ConstString use_external_editor_var_name ("use-external-editor");
1679
1680 return use_external_editor_var_name;
1681}
1682
Jim Ingham3bcdb292010-10-04 22:44:14 +00001683const ConstString &
1684DebuggerInstanceSettings::AutoConfirmName ()
1685{
1686 static ConstString use_external_editor_var_name ("auto-confirm");
1687
1688 return use_external_editor_var_name;
1689}
1690
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001691//--------------------------------------------------
Greg Clayton1b654882010-09-19 02:33:57 +00001692// SettingsController Variable Tables
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001693//--------------------------------------------------
1694
1695
1696SettingEntry
Greg Clayton1b654882010-09-19 02:33:57 +00001697Debugger::SettingsController::global_settings_table[] =
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001698{
1699 //{ "var-name", var-type, "default", enum-table, init'd, hidden, "help-text"},
Caroline Tice101c7c22010-09-09 06:25:08 +00001700 // The Debugger level global table should always be empty; all Debugger settable variables should be instance
1701 // variables.
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001702 { NULL, eSetVarTypeNone, NULL, NULL, 0, 0, NULL }
1703};
1704
Greg Claytonbb562b12010-10-04 02:44:26 +00001705#define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name}${function.pc-offset}}}"
Greg Clayton0603aa92010-10-04 01:05:56 +00001706#define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001707
Greg Clayton0603aa92010-10-04 01:05:56 +00001708#define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\
1709 "{, ${frame.pc}}"\
1710 MODULE_WITH_FUNC\
Greg Claytoncf4b9072010-10-04 17:04:23 +00001711 FILE_AND_LINE\
Greg Clayton0603aa92010-10-04 01:05:56 +00001712 "{, stop reason = ${thread.stop-reason}}"\
Greg Clayton0603aa92010-10-04 01:05:56 +00001713 "\\n"
1714
Greg Clayton315d2ca2010-11-02 01:53:21 +00001715//#define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id}"\
1716// "{, ${frame.pc}}"\
1717// MODULE_WITH_FUNC\
1718// FILE_AND_LINE\
1719// "{, stop reason = ${thread.stop-reason}}"\
1720// "{, name = ${thread.name}}"\
1721// "{, queue = ${thread.queue}}"\
1722// "\\n"
1723
Greg Clayton0603aa92010-10-04 01:05:56 +00001724#define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
1725 MODULE_WITH_FUNC\
1726 FILE_AND_LINE\
1727 "\\n"
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001728
1729SettingEntry
Greg Clayton1b654882010-09-19 02:33:57 +00001730Debugger::SettingsController::instance_settings_table[] =
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001731{
Greg Clayton0603aa92010-10-04 01:05:56 +00001732// NAME Setting variable type Default Enum Init'd Hidden Help
1733// ======================= ======================= ====================== ==== ====== ====== ======================
Greg Clayton0603aa92010-10-04 01:05:56 +00001734{ "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 +00001735{ "prompt", eSetVarTypeString, "(lldb) ", NULL, false, false, "The debugger command line prompt displayed for the user." },
Jim Ingham3bcdb292010-10-04 22:44:14 +00001736{ "script-lang", eSetVarTypeString, "python", NULL, false, false, "The script language to be used for evaluating user-written scripts." },
1737{ "term-width", eSetVarTypeInt, "80" , NULL, false, false, "The maximum number of columns to use for displaying text." },
Greg Clayton0603aa92010-10-04 01:05:56 +00001738{ "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 +00001739{ "use-external-editor", eSetVarTypeBoolean, "false", NULL, false, false, "Whether to use an external editor or not." },
1740{ "auto-confirm", eSetVarTypeBoolean, "false", NULL, false, false, "If true all confirmation prompts will receive their default reply." },
Greg Clayton0603aa92010-10-04 01:05:56 +00001741{ NULL, eSetVarTypeNone, NULL, NULL, false, false, NULL }
Caroline Tice3df9a8d2010-09-04 00:03:46 +00001742};