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 
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 int Debugger::g_shared_debugger_refcount = 0;
26 bool Debugger::g_in_terminate = false;
27 
28 Debugger::DebuggerSP &
29 Debugger::GetDebuggerSP ()
30 {
31     static DebuggerSP g_shared_debugger_sp;
32     return g_shared_debugger_sp;
33 }
34 
35 void
36 Debugger::Initialize ()
37 {
38     g_shared_debugger_refcount++;
39     if (GetDebuggerSP().get() == NULL)
40     {
41         GetDebuggerSP().reset (new Debugger());
42         lldb_private::Initialize();
43         GetDebuggerSP()->GetCommandInterpreter().Initialize();
44     }
45 }
46 
47 void
48 Debugger::Terminate ()
49 {
50     g_shared_debugger_refcount--;
51     if (g_shared_debugger_refcount == 0)
52     {
53         // Because Terminate is called also in the destructor, we need to make sure
54         // that none of the calls to GetSharedInstance leads to a call to Initialize,
55         // thus bumping the refcount back to 1 & causing Debugger::~Debugger to try to
56         // re-terminate.  So we use g_in_terminate to indicate this condition.
57         // When we can require at least Initialize to be called, we won't have to do
58         // this since then the GetSharedInstance won't have to auto-call Initialize...
59 
60         g_in_terminate = true;
61         int num_targets = GetDebuggerSP()->GetTargetList().GetNumTargets();
62         for (int i = 0; i < num_targets; i++)
63         {
64             ProcessSP process_sp(GetDebuggerSP()->GetTargetList().GetTargetAtIndex (i)->GetProcessSP());
65             if (process_sp)
66                 process_sp->Destroy();
67         }
68         GetDebuggerSP()->DisconnectInput();
69         lldb_private::WillTerminate();
70         GetDebuggerSP().reset();
71     }
72 }
73 
74 Debugger &
75 Debugger::GetSharedInstance()
76 {
77     // Don't worry about thread race conditions with the code below as
78     // lldb_private::Initialize(); does this in a thread safe way. I just
79     // want to avoid having to lock and unlock a mutex in
80     // lldb_private::Initialize(); every time we want to access the
81     // Debugger shared instance.
82 
83     // FIXME: We intend to require clients to call Initialize by hand (since they
84     // will also have to call Terminate by hand.)  But for now it is not clear where
85     // we can reliably call these in JH.  So the present version initializes on first use
86     // here, and terminates in the destructor.
87     if (g_shared_debugger_refcount == 0 && !g_in_terminate)
88         Initialize();
89 
90     assert(GetDebuggerSP().get()!= NULL);
91     return *(GetDebuggerSP().get());
92 }
93 
94 Debugger::Debugger () :
95     m_input_comm("debugger.input"),
96     m_input_file (),
97     m_output_file (),
98     m_error_file (),
99     m_async_execution (true),
100     m_target_list (),
101     m_listener ("lldb.Debugger"),
102     m_source_manager (),
103     m_command_interpreter (eScriptLanguageDefault, false, &m_listener, m_source_manager),
104     m_input_readers (),
105     m_input_reader_data ()
106 {
107 }
108 
109 Debugger::~Debugger ()
110 {
111     // FIXME:
112     // Remove this once this version of lldb has made its way through a build.
113     Terminate();
114 }
115 
116 
117 bool
118 Debugger::GetAsyncExecution ()
119 {
120     return m_async_execution;
121 }
122 
123 void
124 Debugger::SetAsyncExecution (bool async_execution)
125 {
126     static bool value_has_been_set = false;
127 
128     if (!value_has_been_set)
129     {
130         value_has_been_set = true;
131         m_async_execution = async_execution;
132         m_command_interpreter.SetSynchronous (!async_execution);
133     }
134 }
135 
136 void
137 Debugger::DisconnectInput()
138 {
139     m_input_comm.Clear ();
140 }
141 
142 void
143 Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
144 {
145     m_input_file.SetFileHandle (fh, tranfer_ownership);
146     if (m_input_file.GetFileHandle() == NULL)
147         m_input_file.SetFileHandle (stdin, false);
148 
149     // Disconnect from any old connection if we had one
150     m_input_comm.Disconnect ();
151     m_input_comm.SetConnection (new ConnectionFileDescriptor (::fileno (GetInputFileHandle()), true));
152     m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this);
153 
154     Error error;
155     if (m_input_comm.StartReadThread (&error) == false)
156     {
157         FILE *err_fh = GetErrorFileHandle();
158         if (err_fh)
159         {
160             ::fprintf (err_fh, "error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error");
161             exit(1);
162         }
163     }
164 
165 }
166 
167 FILE *
168 Debugger::GetInputFileHandle ()
169 {
170     return m_input_file.GetFileHandle();
171 }
172 
173 
174 void
175 Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
176 {
177     m_output_file.SetFileHandle (fh, tranfer_ownership);
178     if (m_output_file.GetFileHandle() == NULL)
179         m_output_file.SetFileHandle (stdin, false);
180 }
181 
182 FILE *
183 Debugger::GetOutputFileHandle ()
184 {
185     return m_output_file.GetFileHandle();
186 }
187 
188 void
189 Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
190 {
191     m_error_file.SetFileHandle (fh, tranfer_ownership);
192     if (m_error_file.GetFileHandle() == NULL)
193         m_error_file.SetFileHandle (stdin, false);
194 }
195 
196 
197 FILE *
198 Debugger::GetErrorFileHandle ()
199 {
200     return m_error_file.GetFileHandle();
201 }
202 
203 CommandInterpreter &
204 Debugger::GetCommandInterpreter ()
205 {
206     return m_command_interpreter;
207 }
208 
209 Listener &
210 Debugger::GetListener ()
211 {
212     return m_listener;
213 }
214 
215 
216 TargetSP
217 Debugger::GetCurrentTarget ()
218 {
219     return m_target_list.GetCurrentTarget ();
220 }
221 
222 ExecutionContext
223 Debugger::GetCurrentExecutionContext ()
224 {
225     ExecutionContext exe_ctx;
226     exe_ctx.Clear();
227 
228     lldb::TargetSP target_sp = GetCurrentTarget();
229     exe_ctx.target = target_sp.get();
230 
231     if (target_sp)
232     {
233         exe_ctx.process = target_sp->GetProcessSP().get();
234         if (exe_ctx.process && exe_ctx.process->IsRunning() == false)
235         {
236             exe_ctx.thread = exe_ctx.process->GetThreadList().GetCurrentThread().get();
237             if (exe_ctx.thread == NULL)
238                 exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
239             if (exe_ctx.thread)
240             {
241                 exe_ctx.frame = exe_ctx.thread->GetCurrentFrame().get();
242                 if (exe_ctx.frame == NULL)
243                     exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex (0).get();
244             }
245         }
246     }
247     return exe_ctx;
248 
249 }
250 
251 SourceManager &
252 Debugger::GetSourceManager ()
253 {
254     return m_source_manager;
255 }
256 
257 
258 TargetList&
259 Debugger::GetTargetList ()
260 {
261     return m_target_list;
262 }
263 
264 void
265 Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len)
266 {
267     ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
268 }
269 
270 
271 void
272 Debugger::DispatchInput (const char *bytes, size_t bytes_len)
273 {
274     if (bytes == NULL || bytes_len == 0)
275         return;
276 
277     // TODO: implement the STDIO to the process as an input reader...
278     TargetSP target = GetCurrentTarget();
279     if (target.get() != NULL)
280     {
281         ProcessSP process_sp = target->GetProcessSP();
282         if (process_sp.get() != NULL
283             && StateIsRunningState (process_sp->GetState()))
284         {
285             Error error;
286             if (process_sp->PutSTDIN (bytes, bytes_len, error) == bytes_len)
287                 return;
288         }
289     }
290 
291     WriteToDefaultReader (bytes, bytes_len);
292 }
293 
294 void
295 Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
296 {
297     if (bytes && bytes_len)
298         m_input_reader_data.append (bytes, bytes_len);
299 
300     if (m_input_reader_data.empty())
301         return;
302 
303     while (!m_input_readers.empty() && !m_input_reader_data.empty())
304     {
305         while (CheckIfTopInputReaderIsDone ())
306             /* Do nothing. */;
307 
308         // Get the input reader from the top of the stack
309         InputReaderSP reader_sp(m_input_readers.top());
310 
311         if (!reader_sp)
312             break;
313 
314         size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.data(),
315                                                           m_input_reader_data.size());
316         if (bytes_handled)
317         {
318             m_input_reader_data.erase (0, bytes_handled);
319         }
320         else
321         {
322             // No bytes were handled, we might not have reached our
323             // granularity, just return and wait for more data
324             break;
325         }
326     }
327 
328     // Flush out any input readers that are donesvn
329     while (CheckIfTopInputReaderIsDone ())
330         /* Do nothing. */;
331 
332 }
333 
334 void
335 Debugger::PushInputReader (const InputReaderSP& reader_sp)
336 {
337     if (!reader_sp)
338         return;
339     if (!m_input_readers.empty())
340     {
341         // Deactivate the old top reader
342         InputReaderSP top_reader_sp (m_input_readers.top());
343         if (top_reader_sp)
344             top_reader_sp->Notify (eInputReaderDeactivate);
345     }
346     m_input_readers.push (reader_sp);
347     reader_sp->Notify (eInputReaderActivate);
348     ActivateInputReader (reader_sp);
349 }
350 
351 bool
352 Debugger::PopInputReader (const lldb::InputReaderSP& pop_reader_sp)
353 {
354     bool result = false;
355 
356     // The reader on the stop of the stack is done, so let the next
357     // read on the stack referesh its prompt and if there is one...
358     if (!m_input_readers.empty())
359     {
360         InputReaderSP reader_sp(m_input_readers.top());
361 
362         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
363         {
364             m_input_readers.pop ();
365             reader_sp->Notify (eInputReaderDeactivate);
366             reader_sp->Notify (eInputReaderDone);
367             result = true;
368 
369             if (!m_input_readers.empty())
370             {
371                 reader_sp = m_input_readers.top();
372                 if (reader_sp)
373                 {
374                     ActivateInputReader (reader_sp);
375                     reader_sp->Notify (eInputReaderReactivate);
376                 }
377             }
378         }
379     }
380     return result;
381 }
382 
383 bool
384 Debugger::CheckIfTopInputReaderIsDone ()
385 {
386     bool result = false;
387     if (!m_input_readers.empty())
388     {
389         InputReaderSP reader_sp(m_input_readers.top());
390 
391         if (reader_sp && reader_sp->IsDone())
392         {
393             result = true;
394             PopInputReader (reader_sp);
395         }
396     }
397     return result;
398 }
399 
400 void
401 Debugger::ActivateInputReader (const InputReaderSP &reader_sp)
402 {
403     FILE *in_fh = GetInputFileHandle();
404 
405     if (in_fh)
406     {
407         struct termios in_fh_termios;
408         int in_fd = fileno (in_fh);
409         if (::tcgetattr(in_fd, &in_fh_termios) == 0)
410         {
411             if (reader_sp->GetEcho())
412                 in_fh_termios.c_lflag |= ECHO;  // Turn on echoing
413             else
414                 in_fh_termios.c_lflag &= ~ECHO; // Turn off echoing
415 
416             switch (reader_sp->GetGranularity())
417             {
418             case eInputReaderGranularityByte:
419             case eInputReaderGranularityWord:
420                 in_fh_termios.c_lflag &= ~ICANON;   // Get one char at a time
421                 break;
422 
423             case eInputReaderGranularityLine:
424             case eInputReaderGranularityAll:
425                 in_fh_termios.c_lflag |= ICANON;   // Get lines at a time
426                 break;
427 
428             default:
429                 break;
430             }
431             ::tcsetattr (in_fd, TCSANOW, &in_fh_termios);
432         }
433     }
434 }
435