1 //===-- Debugger.cpp --------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/lldb-private.h"
11 #include "lldb/Core/ConnectionFileDescriptor.h"
12 #include "lldb/Core/Debugger.h"
13 #include "lldb/Core/InputReader.h"
14 #include "lldb/Core/State.h"
15 #include "lldb/Core/Timer.h"
16 #include "lldb/Interpreter/CommandInterpreter.h"
17 #include "lldb/Target/TargetList.h"
18 #include "lldb/Target/Process.h"
19 #include "lldb/Target/Thread.h"
20 
21 
22 using namespace lldb;
23 using namespace lldb_private;
24 
25 static uint32_t g_shared_debugger_refcount = 0;
26 
27 static lldb::user_id_t g_unique_id = 1;
28 
29 void
30 Debugger::Initialize ()
31 {
32     if (g_shared_debugger_refcount == 0)
33         lldb_private::Initialize();
34     g_shared_debugger_refcount++;
35 }
36 
37 void
38 Debugger::Terminate ()
39 {
40     if (g_shared_debugger_refcount > 0)
41     {
42         g_shared_debugger_refcount--;
43         if (g_shared_debugger_refcount == 0)
44         {
45             lldb_private::WillTerminate();
46             lldb_private::Terminate();
47         }
48     }
49 }
50 
51 typedef std::vector<DebuggerSP> DebuggerList;
52 
53 static Mutex &
54 GetDebuggerListMutex ()
55 {
56     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
57     return g_mutex;
58 }
59 
60 static DebuggerList &
61 GetDebuggerList()
62 {
63     // hide the static debugger list inside a singleton accessor to avoid
64     // global init contructors
65     static DebuggerList g_list;
66     return g_list;
67 }
68 
69 
70 DebuggerSP
71 Debugger::CreateInstance ()
72 {
73     DebuggerSP debugger_sp (new Debugger);
74     // Scope for locker
75     {
76         Mutex::Locker locker (GetDebuggerListMutex ());
77         GetDebuggerList().push_back(debugger_sp);
78     }
79     return debugger_sp;
80 }
81 
82 lldb::DebuggerSP
83 Debugger::GetSP ()
84 {
85     lldb::DebuggerSP debugger_sp;
86 
87     Mutex::Locker locker (GetDebuggerListMutex ());
88     DebuggerList &debugger_list = GetDebuggerList();
89     DebuggerList::iterator pos, end = debugger_list.end();
90     for (pos = debugger_list.begin(); pos != end; ++pos)
91     {
92         if ((*pos).get() == this)
93         {
94             debugger_sp = *pos;
95             break;
96         }
97     }
98     return debugger_sp;
99 }
100 
101 
102 TargetSP
103 Debugger::FindTargetWithProcessID (lldb::pid_t pid)
104 {
105     lldb::TargetSP target_sp;
106     Mutex::Locker locker (GetDebuggerListMutex ());
107     DebuggerList &debugger_list = GetDebuggerList();
108     DebuggerList::iterator pos, end = debugger_list.end();
109     for (pos = debugger_list.begin(); pos != end; ++pos)
110     {
111         target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
112         if (target_sp)
113             break;
114     }
115     return target_sp;
116 }
117 
118 
119 Debugger::Debugger () :
120     UserID (g_unique_id++),
121     m_input_comm("debugger.input"),
122     m_input_file (),
123     m_output_file (),
124     m_error_file (),
125     m_target_list (),
126     m_listener ("lldb.Debugger"),
127     m_source_manager (),
128     m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
129     m_exe_ctx (),
130     m_input_readers (),
131     m_input_reader_data ()
132 {
133     m_command_interpreter_ap->Initialize ();
134 }
135 
136 Debugger::~Debugger ()
137 {
138     int num_targets = m_target_list.GetNumTargets();
139     for (int i = 0; i < num_targets; i++)
140     {
141         ProcessSP process_sp (m_target_list.GetTargetAtIndex (i)->GetProcessSP());
142         if (process_sp)
143             process_sp->Destroy();
144     }
145     DisconnectInput();
146 }
147 
148 
149 bool
150 Debugger::GetAsyncExecution ()
151 {
152     return !m_command_interpreter_ap->GetSynchronous();
153 }
154 
155 void
156 Debugger::SetAsyncExecution (bool async_execution)
157 {
158     m_command_interpreter_ap->SetSynchronous (!async_execution);
159 }
160 
161 void
162 Debugger::DisconnectInput()
163 {
164     m_input_comm.Clear ();
165 }
166 
167 void
168 Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
169 {
170     m_input_file.SetFileHandle (fh, tranfer_ownership);
171     if (m_input_file.GetFileHandle() == NULL)
172         m_input_file.SetFileHandle (stdin, false);
173 
174     // Disconnect from any old connection if we had one
175     m_input_comm.Disconnect ();
176     m_input_comm.SetConnection (new ConnectionFileDescriptor (::fileno (GetInputFileHandle()), true));
177     m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this);
178 
179     Error error;
180     if (m_input_comm.StartReadThread (&error) == false)
181     {
182         FILE *err_fh = GetErrorFileHandle();
183         if (err_fh)
184         {
185             ::fprintf (err_fh, "error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error");
186             exit(1);
187         }
188     }
189 
190 }
191 
192 FILE *
193 Debugger::GetInputFileHandle ()
194 {
195     return m_input_file.GetFileHandle();
196 }
197 
198 
199 void
200 Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
201 {
202     m_output_file.SetFileHandle (fh, tranfer_ownership);
203     if (m_output_file.GetFileHandle() == NULL)
204         m_output_file.SetFileHandle (stdin, false);
205 }
206 
207 FILE *
208 Debugger::GetOutputFileHandle ()
209 {
210     return m_output_file.GetFileHandle();
211 }
212 
213 void
214 Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
215 {
216     m_error_file.SetFileHandle (fh, tranfer_ownership);
217     if (m_error_file.GetFileHandle() == NULL)
218         m_error_file.SetFileHandle (stdin, false);
219 }
220 
221 
222 FILE *
223 Debugger::GetErrorFileHandle ()
224 {
225     return m_error_file.GetFileHandle();
226 }
227 
228 CommandInterpreter &
229 Debugger::GetCommandInterpreter ()
230 {
231     assert (m_command_interpreter_ap.get());
232     return *m_command_interpreter_ap;
233 }
234 
235 Listener &
236 Debugger::GetListener ()
237 {
238     return m_listener;
239 }
240 
241 
242 TargetSP
243 Debugger::GetCurrentTarget ()
244 {
245     return m_target_list.GetCurrentTarget ();
246 }
247 
248 ExecutionContext
249 Debugger::GetCurrentExecutionContext ()
250 {
251     ExecutionContext exe_ctx;
252     exe_ctx.Clear();
253 
254     lldb::TargetSP target_sp = GetCurrentTarget();
255     exe_ctx.target = target_sp.get();
256 
257     if (target_sp)
258     {
259         exe_ctx.process = target_sp->GetProcessSP().get();
260         if (exe_ctx.process && exe_ctx.process->IsRunning() == false)
261         {
262             exe_ctx.thread = exe_ctx.process->GetThreadList().GetCurrentThread().get();
263             if (exe_ctx.thread == NULL)
264                 exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
265             if (exe_ctx.thread)
266             {
267                 exe_ctx.frame = exe_ctx.thread->GetCurrentFrame().get();
268                 if (exe_ctx.frame == NULL)
269                     exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex (0).get();
270             }
271         }
272     }
273     return exe_ctx;
274 
275 }
276 
277 SourceManager &
278 Debugger::GetSourceManager ()
279 {
280     return m_source_manager;
281 }
282 
283 
284 TargetList&
285 Debugger::GetTargetList ()
286 {
287     return m_target_list;
288 }
289 
290 void
291 Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len)
292 {
293     ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
294 }
295 
296 
297 void
298 Debugger::DispatchInput (const char *bytes, size_t bytes_len)
299 {
300     if (bytes == NULL || bytes_len == 0)
301         return;
302 
303     // TODO: implement the STDIO to the process as an input reader...
304     TargetSP target = GetCurrentTarget();
305     if (target.get() != NULL)
306     {
307         ProcessSP process_sp = target->GetProcessSP();
308         if (process_sp.get() != NULL
309             && StateIsRunningState (process_sp->GetState()))
310         {
311             Error error;
312             if (process_sp->PutSTDIN (bytes, bytes_len, error) == bytes_len)
313                 return;
314         }
315     }
316 
317     WriteToDefaultReader (bytes, bytes_len);
318 }
319 
320 void
321 Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
322 {
323     if (bytes && bytes_len)
324         m_input_reader_data.append (bytes, bytes_len);
325 
326     if (m_input_reader_data.empty())
327         return;
328 
329     while (!m_input_readers.empty() && !m_input_reader_data.empty())
330     {
331         while (CheckIfTopInputReaderIsDone ())
332             /* Do nothing. */;
333 
334         // Get the input reader from the top of the stack
335         InputReaderSP reader_sp(m_input_readers.top());
336 
337         if (!reader_sp)
338             break;
339 
340         size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.data(),
341                                                           m_input_reader_data.size());
342         if (bytes_handled)
343         {
344             m_input_reader_data.erase (0, bytes_handled);
345         }
346         else
347         {
348             // No bytes were handled, we might not have reached our
349             // granularity, just return and wait for more data
350             break;
351         }
352     }
353 
354     // Flush out any input readers that are donesvn
355     while (CheckIfTopInputReaderIsDone ())
356         /* Do nothing. */;
357 
358 }
359 
360 void
361 Debugger::PushInputReader (const InputReaderSP& reader_sp)
362 {
363     if (!reader_sp)
364         return;
365     if (!m_input_readers.empty())
366     {
367         // Deactivate the old top reader
368         InputReaderSP top_reader_sp (m_input_readers.top());
369         if (top_reader_sp)
370             top_reader_sp->Notify (eInputReaderDeactivate);
371     }
372     m_input_readers.push (reader_sp);
373     reader_sp->Notify (eInputReaderActivate);
374     ActivateInputReader (reader_sp);
375 }
376 
377 bool
378 Debugger::PopInputReader (const lldb::InputReaderSP& pop_reader_sp)
379 {
380     bool result = false;
381 
382     // The reader on the stop of the stack is done, so let the next
383     // read on the stack referesh its prompt and if there is one...
384     if (!m_input_readers.empty())
385     {
386         InputReaderSP reader_sp(m_input_readers.top());
387 
388         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
389         {
390             m_input_readers.pop ();
391             reader_sp->Notify (eInputReaderDeactivate);
392             reader_sp->Notify (eInputReaderDone);
393             result = true;
394 
395             if (!m_input_readers.empty())
396             {
397                 reader_sp = m_input_readers.top();
398                 if (reader_sp)
399                 {
400                     ActivateInputReader (reader_sp);
401                     reader_sp->Notify (eInputReaderReactivate);
402                 }
403             }
404         }
405     }
406     return result;
407 }
408 
409 bool
410 Debugger::CheckIfTopInputReaderIsDone ()
411 {
412     bool result = false;
413     if (!m_input_readers.empty())
414     {
415         InputReaderSP reader_sp(m_input_readers.top());
416 
417         if (reader_sp && reader_sp->IsDone())
418         {
419             result = true;
420             PopInputReader (reader_sp);
421         }
422     }
423     return result;
424 }
425 
426 void
427 Debugger::ActivateInputReader (const InputReaderSP &reader_sp)
428 {
429     FILE *in_fh = GetInputFileHandle();
430 
431     if (in_fh)
432     {
433         struct termios in_fh_termios;
434         int in_fd = fileno (in_fh);
435         if (::tcgetattr(in_fd, &in_fh_termios) == 0)
436         {
437             if (reader_sp->GetEcho())
438                 in_fh_termios.c_lflag |= ECHO;  // Turn on echoing
439             else
440                 in_fh_termios.c_lflag &= ~ECHO; // Turn off echoing
441 
442             switch (reader_sp->GetGranularity())
443             {
444             case eInputReaderGranularityByte:
445             case eInputReaderGranularityWord:
446                 in_fh_termios.c_lflag &= ~ICANON;   // Get one char at a time
447                 break;
448 
449             case eInputReaderGranularityLine:
450             case eInputReaderGranularityAll:
451                 in_fh_termios.c_lflag |= ICANON;   // Get lines at a time
452                 break;
453 
454             default:
455                 break;
456             }
457             ::tcsetattr (in_fd, TCSANOW, &in_fh_termios);
458         }
459     }
460 }
461 
462 void
463 Debugger::UpdateExecutionContext (ExecutionContext *override_context)
464 {
465     m_exe_ctx.Clear();
466 
467     if (override_context != NULL)
468     {
469         m_exe_ctx.target = override_context->target;
470         m_exe_ctx.process = override_context->process;
471         m_exe_ctx.thread = override_context->thread;
472         m_exe_ctx.frame = override_context->frame;
473     }
474     else
475     {
476         TargetSP target_sp (GetCurrentTarget());
477         if (target_sp)
478         {
479             m_exe_ctx.target = target_sp.get();
480             m_exe_ctx.process = target_sp->GetProcessSP().get();
481             if (m_exe_ctx.process && m_exe_ctx.process->IsRunning() == false)
482             {
483                 m_exe_ctx.thread = m_exe_ctx.process->GetThreadList().GetCurrentThread().get();
484                 if (m_exe_ctx.thread == NULL)
485                     m_exe_ctx.thread = m_exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
486                 if (m_exe_ctx.thread)
487                 {
488                     m_exe_ctx.frame = m_exe_ctx.thread->GetCurrentFrame().get();
489                     if (m_exe_ctx.frame == NULL)
490                         m_exe_ctx.frame = m_exe_ctx.thread->GetStackFrameAtIndex (0).get();
491                 }
492             }
493         }
494     }
495 }
496 
497 DebuggerSP
498 Debugger::FindDebuggerWithID (lldb::user_id_t id)
499 {
500     lldb::DebuggerSP debugger_sp;
501 
502     Mutex::Locker locker (GetDebuggerListMutex ());
503     DebuggerList &debugger_list = GetDebuggerList();
504     DebuggerList::iterator pos, end = debugger_list.end();
505     for (pos = debugger_list.begin(); pos != end; ++pos)
506     {
507         if ((*pos).get()->GetID() == id)
508         {
509             debugger_sp = *pos;
510             break;
511         }
512     }
513     return debugger_sp;
514 }
515