130fdc8d8SChris Lattner //===-- Debugger.cpp --------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner #include "lldb/lldb-private.h"
1130fdc8d8SChris Lattner #include "lldb/Core/ConnectionFileDescriptor.h"
1230fdc8d8SChris Lattner #include "lldb/Core/Debugger.h"
1330fdc8d8SChris Lattner #include "lldb/Core/InputReader.h"
1430fdc8d8SChris Lattner #include "lldb/Core/State.h"
1530fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
166611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
1730fdc8d8SChris Lattner #include "lldb/Target/TargetList.h"
1830fdc8d8SChris Lattner #include "lldb/Target/Process.h"
1930fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
2030fdc8d8SChris Lattner 
2130fdc8d8SChris Lattner 
2230fdc8d8SChris Lattner using namespace lldb;
2330fdc8d8SChris Lattner using namespace lldb_private;
2430fdc8d8SChris Lattner 
256611103cSGreg Clayton static uint32_t g_shared_debugger_refcount = 0;
2630fdc8d8SChris Lattner 
27ebc1bb27SCaroline Tice static lldb::user_id_t g_unique_id = 1;
28ebc1bb27SCaroline Tice 
2930fdc8d8SChris Lattner void
3030fdc8d8SChris Lattner Debugger::Initialize ()
3130fdc8d8SChris Lattner {
326611103cSGreg Clayton     if (g_shared_debugger_refcount == 0)
3330fdc8d8SChris Lattner         lldb_private::Initialize();
346611103cSGreg Clayton     g_shared_debugger_refcount++;
3530fdc8d8SChris Lattner }
3630fdc8d8SChris Lattner 
3730fdc8d8SChris Lattner void
3830fdc8d8SChris Lattner Debugger::Terminate ()
3930fdc8d8SChris Lattner {
406611103cSGreg Clayton     if (g_shared_debugger_refcount > 0)
416611103cSGreg Clayton     {
4230fdc8d8SChris Lattner         g_shared_debugger_refcount--;
4330fdc8d8SChris Lattner         if (g_shared_debugger_refcount == 0)
4430fdc8d8SChris Lattner         {
4530fdc8d8SChris Lattner             lldb_private::WillTerminate();
466611103cSGreg Clayton             lldb_private::Terminate();
476611103cSGreg Clayton         }
4830fdc8d8SChris Lattner     }
4930fdc8d8SChris Lattner }
5030fdc8d8SChris Lattner 
516611103cSGreg Clayton typedef std::vector<DebuggerSP> DebuggerList;
526611103cSGreg Clayton 
536611103cSGreg Clayton static Mutex &
546611103cSGreg Clayton GetDebuggerListMutex ()
5530fdc8d8SChris Lattner {
566611103cSGreg Clayton     static Mutex g_mutex(Mutex::eMutexTypeRecursive);
576611103cSGreg Clayton     return g_mutex;
5830fdc8d8SChris Lattner }
5930fdc8d8SChris Lattner 
606611103cSGreg Clayton static DebuggerList &
616611103cSGreg Clayton GetDebuggerList()
626611103cSGreg Clayton {
636611103cSGreg Clayton     // hide the static debugger list inside a singleton accessor to avoid
646611103cSGreg Clayton     // global init contructors
656611103cSGreg Clayton     static DebuggerList g_list;
666611103cSGreg Clayton     return g_list;
676611103cSGreg Clayton }
686611103cSGreg Clayton 
696611103cSGreg Clayton 
706611103cSGreg Clayton DebuggerSP
716611103cSGreg Clayton Debugger::CreateInstance ()
726611103cSGreg Clayton {
736611103cSGreg Clayton     DebuggerSP debugger_sp (new Debugger);
746611103cSGreg Clayton     // Scope for locker
756611103cSGreg Clayton     {
766611103cSGreg Clayton         Mutex::Locker locker (GetDebuggerListMutex ());
776611103cSGreg Clayton         GetDebuggerList().push_back(debugger_sp);
786611103cSGreg Clayton     }
796611103cSGreg Clayton     return debugger_sp;
806611103cSGreg Clayton }
816611103cSGreg Clayton 
826611103cSGreg Clayton lldb::DebuggerSP
836611103cSGreg Clayton Debugger::GetSP ()
846611103cSGreg Clayton {
856611103cSGreg Clayton     lldb::DebuggerSP debugger_sp;
866611103cSGreg Clayton 
876611103cSGreg Clayton     Mutex::Locker locker (GetDebuggerListMutex ());
886611103cSGreg Clayton     DebuggerList &debugger_list = GetDebuggerList();
896611103cSGreg Clayton     DebuggerList::iterator pos, end = debugger_list.end();
906611103cSGreg Clayton     for (pos = debugger_list.begin(); pos != end; ++pos)
916611103cSGreg Clayton     {
926611103cSGreg Clayton         if ((*pos).get() == this)
936611103cSGreg Clayton         {
946611103cSGreg Clayton             debugger_sp = *pos;
956611103cSGreg Clayton             break;
966611103cSGreg Clayton         }
976611103cSGreg Clayton     }
986611103cSGreg Clayton     return debugger_sp;
996611103cSGreg Clayton }
1006611103cSGreg Clayton 
1016611103cSGreg Clayton 
1026611103cSGreg Clayton TargetSP
1036611103cSGreg Clayton Debugger::FindTargetWithProcessID (lldb::pid_t pid)
1046611103cSGreg Clayton {
1056611103cSGreg Clayton     lldb::TargetSP target_sp;
1066611103cSGreg Clayton     Mutex::Locker locker (GetDebuggerListMutex ());
1076611103cSGreg Clayton     DebuggerList &debugger_list = GetDebuggerList();
1086611103cSGreg Clayton     DebuggerList::iterator pos, end = debugger_list.end();
1096611103cSGreg Clayton     for (pos = debugger_list.begin(); pos != end; ++pos)
1106611103cSGreg Clayton     {
1116611103cSGreg Clayton         target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
1126611103cSGreg Clayton         if (target_sp)
1136611103cSGreg Clayton             break;
1146611103cSGreg Clayton     }
1156611103cSGreg Clayton     return target_sp;
1166611103cSGreg Clayton }
1176611103cSGreg Clayton 
1186611103cSGreg Clayton 
11930fdc8d8SChris Lattner Debugger::Debugger () :
120ebc1bb27SCaroline Tice     UserID (g_unique_id++),
12130fdc8d8SChris Lattner     m_input_comm("debugger.input"),
12230fdc8d8SChris Lattner     m_input_file (),
12330fdc8d8SChris Lattner     m_output_file (),
12430fdc8d8SChris Lattner     m_error_file (),
12530fdc8d8SChris Lattner     m_target_list (),
12630fdc8d8SChris Lattner     m_listener ("lldb.Debugger"),
12730fdc8d8SChris Lattner     m_source_manager (),
1286611103cSGreg Clayton     m_command_interpreter_ap (new CommandInterpreter (*this, eScriptLanguageDefault, false)),
1296611103cSGreg Clayton     m_exe_ctx (),
13030fdc8d8SChris Lattner     m_input_readers (),
13130fdc8d8SChris Lattner     m_input_reader_data ()
13230fdc8d8SChris Lattner {
1336611103cSGreg Clayton     m_command_interpreter_ap->Initialize ();
13430fdc8d8SChris Lattner }
13530fdc8d8SChris Lattner 
13630fdc8d8SChris Lattner Debugger::~Debugger ()
13730fdc8d8SChris Lattner {
1386611103cSGreg Clayton     int num_targets = m_target_list.GetNumTargets();
1396611103cSGreg Clayton     for (int i = 0; i < num_targets; i++)
1406611103cSGreg Clayton     {
1416611103cSGreg Clayton         ProcessSP process_sp (m_target_list.GetTargetAtIndex (i)->GetProcessSP());
1426611103cSGreg Clayton         if (process_sp)
1436611103cSGreg Clayton             process_sp->Destroy();
1446611103cSGreg Clayton     }
1456611103cSGreg Clayton     DisconnectInput();
14630fdc8d8SChris Lattner }
14730fdc8d8SChris Lattner 
14830fdc8d8SChris Lattner 
14930fdc8d8SChris Lattner bool
15030fdc8d8SChris Lattner Debugger::GetAsyncExecution ()
15130fdc8d8SChris Lattner {
1526611103cSGreg Clayton     return !m_command_interpreter_ap->GetSynchronous();
15330fdc8d8SChris Lattner }
15430fdc8d8SChris Lattner 
15530fdc8d8SChris Lattner void
15630fdc8d8SChris Lattner Debugger::SetAsyncExecution (bool async_execution)
15730fdc8d8SChris Lattner {
1586611103cSGreg Clayton     m_command_interpreter_ap->SetSynchronous (!async_execution);
15930fdc8d8SChris Lattner }
16030fdc8d8SChris Lattner 
16130fdc8d8SChris Lattner void
16230fdc8d8SChris Lattner Debugger::DisconnectInput()
16330fdc8d8SChris Lattner {
16430fdc8d8SChris Lattner     m_input_comm.Clear ();
16530fdc8d8SChris Lattner }
16630fdc8d8SChris Lattner 
16730fdc8d8SChris Lattner void
16830fdc8d8SChris Lattner Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
16930fdc8d8SChris Lattner {
17030fdc8d8SChris Lattner     m_input_file.SetFileHandle (fh, tranfer_ownership);
17130fdc8d8SChris Lattner     if (m_input_file.GetFileHandle() == NULL)
17230fdc8d8SChris Lattner         m_input_file.SetFileHandle (stdin, false);
17330fdc8d8SChris Lattner 
17430fdc8d8SChris Lattner     // Disconnect from any old connection if we had one
17530fdc8d8SChris Lattner     m_input_comm.Disconnect ();
17630fdc8d8SChris Lattner     m_input_comm.SetConnection (new ConnectionFileDescriptor (::fileno (GetInputFileHandle()), true));
17730fdc8d8SChris Lattner     m_input_comm.SetReadThreadBytesReceivedCallback (Debugger::DispatchInputCallback, this);
17830fdc8d8SChris Lattner 
17930fdc8d8SChris Lattner     Error error;
18030fdc8d8SChris Lattner     if (m_input_comm.StartReadThread (&error) == false)
18130fdc8d8SChris Lattner     {
18230fdc8d8SChris Lattner         FILE *err_fh = GetErrorFileHandle();
18330fdc8d8SChris Lattner         if (err_fh)
18430fdc8d8SChris Lattner         {
18530fdc8d8SChris Lattner             ::fprintf (err_fh, "error: failed to main input read thread: %s", error.AsCString() ? error.AsCString() : "unkown error");
18630fdc8d8SChris Lattner             exit(1);
18730fdc8d8SChris Lattner         }
18830fdc8d8SChris Lattner     }
18930fdc8d8SChris Lattner 
19030fdc8d8SChris Lattner }
19130fdc8d8SChris Lattner 
19230fdc8d8SChris Lattner FILE *
19330fdc8d8SChris Lattner Debugger::GetInputFileHandle ()
19430fdc8d8SChris Lattner {
19530fdc8d8SChris Lattner     return m_input_file.GetFileHandle();
19630fdc8d8SChris Lattner }
19730fdc8d8SChris Lattner 
19830fdc8d8SChris Lattner 
19930fdc8d8SChris Lattner void
20030fdc8d8SChris Lattner Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
20130fdc8d8SChris Lattner {
20230fdc8d8SChris Lattner     m_output_file.SetFileHandle (fh, tranfer_ownership);
20330fdc8d8SChris Lattner     if (m_output_file.GetFileHandle() == NULL)
20430fdc8d8SChris Lattner         m_output_file.SetFileHandle (stdin, false);
20530fdc8d8SChris Lattner }
20630fdc8d8SChris Lattner 
20730fdc8d8SChris Lattner FILE *
20830fdc8d8SChris Lattner Debugger::GetOutputFileHandle ()
20930fdc8d8SChris Lattner {
21030fdc8d8SChris Lattner     return m_output_file.GetFileHandle();
21130fdc8d8SChris Lattner }
21230fdc8d8SChris Lattner 
21330fdc8d8SChris Lattner void
21430fdc8d8SChris Lattner Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
21530fdc8d8SChris Lattner {
21630fdc8d8SChris Lattner     m_error_file.SetFileHandle (fh, tranfer_ownership);
21730fdc8d8SChris Lattner     if (m_error_file.GetFileHandle() == NULL)
21830fdc8d8SChris Lattner         m_error_file.SetFileHandle (stdin, false);
21930fdc8d8SChris Lattner }
22030fdc8d8SChris Lattner 
22130fdc8d8SChris Lattner 
22230fdc8d8SChris Lattner FILE *
22330fdc8d8SChris Lattner Debugger::GetErrorFileHandle ()
22430fdc8d8SChris Lattner {
22530fdc8d8SChris Lattner     return m_error_file.GetFileHandle();
22630fdc8d8SChris Lattner }
22730fdc8d8SChris Lattner 
22830fdc8d8SChris Lattner CommandInterpreter &
22930fdc8d8SChris Lattner Debugger::GetCommandInterpreter ()
23030fdc8d8SChris Lattner {
2316611103cSGreg Clayton     assert (m_command_interpreter_ap.get());
2326611103cSGreg Clayton     return *m_command_interpreter_ap;
23330fdc8d8SChris Lattner }
23430fdc8d8SChris Lattner 
23530fdc8d8SChris Lattner Listener &
23630fdc8d8SChris Lattner Debugger::GetListener ()
23730fdc8d8SChris Lattner {
23830fdc8d8SChris Lattner     return m_listener;
23930fdc8d8SChris Lattner }
24030fdc8d8SChris Lattner 
24130fdc8d8SChris Lattner 
24230fdc8d8SChris Lattner TargetSP
243*2976d00aSJim Ingham Debugger::GetSelectedTarget ()
24430fdc8d8SChris Lattner {
245*2976d00aSJim Ingham     return m_target_list.GetSelectedTarget ();
24630fdc8d8SChris Lattner }
24730fdc8d8SChris Lattner 
24830fdc8d8SChris Lattner ExecutionContext
249*2976d00aSJim Ingham Debugger::GetSelectedExecutionContext ()
25030fdc8d8SChris Lattner {
25130fdc8d8SChris Lattner     ExecutionContext exe_ctx;
25230fdc8d8SChris Lattner     exe_ctx.Clear();
25330fdc8d8SChris Lattner 
254*2976d00aSJim Ingham     lldb::TargetSP target_sp = GetSelectedTarget();
25530fdc8d8SChris Lattner     exe_ctx.target = target_sp.get();
25630fdc8d8SChris Lattner 
25730fdc8d8SChris Lattner     if (target_sp)
25830fdc8d8SChris Lattner     {
25930fdc8d8SChris Lattner         exe_ctx.process = target_sp->GetProcessSP().get();
26030fdc8d8SChris Lattner         if (exe_ctx.process && exe_ctx.process->IsRunning() == false)
26130fdc8d8SChris Lattner         {
262*2976d00aSJim Ingham             exe_ctx.thread = exe_ctx.process->GetThreadList().GetSelectedThread().get();
26330fdc8d8SChris Lattner             if (exe_ctx.thread == NULL)
26430fdc8d8SChris Lattner                 exe_ctx.thread = exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
26530fdc8d8SChris Lattner             if (exe_ctx.thread)
26630fdc8d8SChris Lattner             {
267*2976d00aSJim Ingham                 exe_ctx.frame = exe_ctx.thread->GetSelectedFrame().get();
26830fdc8d8SChris Lattner                 if (exe_ctx.frame == NULL)
26930fdc8d8SChris Lattner                     exe_ctx.frame = exe_ctx.thread->GetStackFrameAtIndex (0).get();
27030fdc8d8SChris Lattner             }
27130fdc8d8SChris Lattner         }
27230fdc8d8SChris Lattner     }
27330fdc8d8SChris Lattner     return exe_ctx;
27430fdc8d8SChris Lattner 
27530fdc8d8SChris Lattner }
27630fdc8d8SChris Lattner 
27730fdc8d8SChris Lattner SourceManager &
27830fdc8d8SChris Lattner Debugger::GetSourceManager ()
27930fdc8d8SChris Lattner {
28030fdc8d8SChris Lattner     return m_source_manager;
28130fdc8d8SChris Lattner }
28230fdc8d8SChris Lattner 
28330fdc8d8SChris Lattner 
28430fdc8d8SChris Lattner TargetList&
28530fdc8d8SChris Lattner Debugger::GetTargetList ()
28630fdc8d8SChris Lattner {
28730fdc8d8SChris Lattner     return m_target_list;
28830fdc8d8SChris Lattner }
28930fdc8d8SChris Lattner 
29030fdc8d8SChris Lattner void
29130fdc8d8SChris Lattner Debugger::DispatchInputCallback (void *baton, const void *bytes, size_t bytes_len)
29230fdc8d8SChris Lattner {
29330fdc8d8SChris Lattner     ((Debugger *)baton)->DispatchInput ((char *)bytes, bytes_len);
29430fdc8d8SChris Lattner }
29530fdc8d8SChris Lattner 
29630fdc8d8SChris Lattner 
29730fdc8d8SChris Lattner void
29830fdc8d8SChris Lattner Debugger::DispatchInput (const char *bytes, size_t bytes_len)
29930fdc8d8SChris Lattner {
30030fdc8d8SChris Lattner     if (bytes == NULL || bytes_len == 0)
30130fdc8d8SChris Lattner         return;
30230fdc8d8SChris Lattner 
30330fdc8d8SChris Lattner     // TODO: implement the STDIO to the process as an input reader...
304*2976d00aSJim Ingham     TargetSP target = GetSelectedTarget();
30530fdc8d8SChris Lattner     if (target.get() != NULL)
30630fdc8d8SChris Lattner     {
30730fdc8d8SChris Lattner         ProcessSP process_sp = target->GetProcessSP();
30830fdc8d8SChris Lattner         if (process_sp.get() != NULL
30930fdc8d8SChris Lattner             && StateIsRunningState (process_sp->GetState()))
31030fdc8d8SChris Lattner         {
31130fdc8d8SChris Lattner             Error error;
31230fdc8d8SChris Lattner             if (process_sp->PutSTDIN (bytes, bytes_len, error) == bytes_len)
31330fdc8d8SChris Lattner                 return;
31430fdc8d8SChris Lattner         }
31530fdc8d8SChris Lattner     }
31630fdc8d8SChris Lattner 
31730fdc8d8SChris Lattner     WriteToDefaultReader (bytes, bytes_len);
31830fdc8d8SChris Lattner }
31930fdc8d8SChris Lattner 
32030fdc8d8SChris Lattner void
32130fdc8d8SChris Lattner Debugger::WriteToDefaultReader (const char *bytes, size_t bytes_len)
32230fdc8d8SChris Lattner {
32330fdc8d8SChris Lattner     if (bytes && bytes_len)
32430fdc8d8SChris Lattner         m_input_reader_data.append (bytes, bytes_len);
32530fdc8d8SChris Lattner 
32630fdc8d8SChris Lattner     if (m_input_reader_data.empty())
32730fdc8d8SChris Lattner         return;
32830fdc8d8SChris Lattner 
32930fdc8d8SChris Lattner     while (!m_input_readers.empty() && !m_input_reader_data.empty())
33030fdc8d8SChris Lattner     {
33130fdc8d8SChris Lattner         while (CheckIfTopInputReaderIsDone ())
33230fdc8d8SChris Lattner             /* Do nothing. */;
33330fdc8d8SChris Lattner 
33430fdc8d8SChris Lattner         // Get the input reader from the top of the stack
33530fdc8d8SChris Lattner         InputReaderSP reader_sp(m_input_readers.top());
33630fdc8d8SChris Lattner 
33730fdc8d8SChris Lattner         if (!reader_sp)
33830fdc8d8SChris Lattner             break;
33930fdc8d8SChris Lattner 
340471b31ceSGreg Clayton         size_t bytes_handled = reader_sp->HandleRawBytes (m_input_reader_data.c_str(),
34130fdc8d8SChris Lattner                                                           m_input_reader_data.size());
34230fdc8d8SChris Lattner         if (bytes_handled)
34330fdc8d8SChris Lattner         {
34430fdc8d8SChris Lattner             m_input_reader_data.erase (0, bytes_handled);
34530fdc8d8SChris Lattner         }
34630fdc8d8SChris Lattner         else
34730fdc8d8SChris Lattner         {
34830fdc8d8SChris Lattner             // No bytes were handled, we might not have reached our
34930fdc8d8SChris Lattner             // granularity, just return and wait for more data
35030fdc8d8SChris Lattner             break;
35130fdc8d8SChris Lattner         }
35230fdc8d8SChris Lattner     }
35330fdc8d8SChris Lattner 
35430fdc8d8SChris Lattner     // Flush out any input readers that are donesvn
35530fdc8d8SChris Lattner     while (CheckIfTopInputReaderIsDone ())
35630fdc8d8SChris Lattner         /* Do nothing. */;
35730fdc8d8SChris Lattner 
35830fdc8d8SChris Lattner }
35930fdc8d8SChris Lattner 
36030fdc8d8SChris Lattner void
36130fdc8d8SChris Lattner Debugger::PushInputReader (const InputReaderSP& reader_sp)
36230fdc8d8SChris Lattner {
36330fdc8d8SChris Lattner     if (!reader_sp)
36430fdc8d8SChris Lattner         return;
36530fdc8d8SChris Lattner     if (!m_input_readers.empty())
36630fdc8d8SChris Lattner     {
36730fdc8d8SChris Lattner         // Deactivate the old top reader
36830fdc8d8SChris Lattner         InputReaderSP top_reader_sp (m_input_readers.top());
36930fdc8d8SChris Lattner         if (top_reader_sp)
37030fdc8d8SChris Lattner             top_reader_sp->Notify (eInputReaderDeactivate);
37130fdc8d8SChris Lattner     }
37230fdc8d8SChris Lattner     m_input_readers.push (reader_sp);
37330fdc8d8SChris Lattner     reader_sp->Notify (eInputReaderActivate);
37430fdc8d8SChris Lattner     ActivateInputReader (reader_sp);
37530fdc8d8SChris Lattner }
37630fdc8d8SChris Lattner 
37730fdc8d8SChris Lattner bool
37830fdc8d8SChris Lattner Debugger::PopInputReader (const lldb::InputReaderSP& pop_reader_sp)
37930fdc8d8SChris Lattner {
38030fdc8d8SChris Lattner     bool result = false;
38130fdc8d8SChris Lattner 
38230fdc8d8SChris Lattner     // The reader on the stop of the stack is done, so let the next
38330fdc8d8SChris Lattner     // read on the stack referesh its prompt and if there is one...
38430fdc8d8SChris Lattner     if (!m_input_readers.empty())
38530fdc8d8SChris Lattner     {
38630fdc8d8SChris Lattner         InputReaderSP reader_sp(m_input_readers.top());
38730fdc8d8SChris Lattner 
38830fdc8d8SChris Lattner         if (!pop_reader_sp || pop_reader_sp.get() == reader_sp.get())
38930fdc8d8SChris Lattner         {
39030fdc8d8SChris Lattner             m_input_readers.pop ();
39130fdc8d8SChris Lattner             reader_sp->Notify (eInputReaderDeactivate);
39230fdc8d8SChris Lattner             reader_sp->Notify (eInputReaderDone);
39330fdc8d8SChris Lattner             result = true;
39430fdc8d8SChris Lattner 
39530fdc8d8SChris Lattner             if (!m_input_readers.empty())
39630fdc8d8SChris Lattner             {
39730fdc8d8SChris Lattner                 reader_sp = m_input_readers.top();
39830fdc8d8SChris Lattner                 if (reader_sp)
39930fdc8d8SChris Lattner                 {
40030fdc8d8SChris Lattner                     ActivateInputReader (reader_sp);
40130fdc8d8SChris Lattner                     reader_sp->Notify (eInputReaderReactivate);
40230fdc8d8SChris Lattner                 }
40330fdc8d8SChris Lattner             }
40430fdc8d8SChris Lattner         }
40530fdc8d8SChris Lattner     }
40630fdc8d8SChris Lattner     return result;
40730fdc8d8SChris Lattner }
40830fdc8d8SChris Lattner 
40930fdc8d8SChris Lattner bool
41030fdc8d8SChris Lattner Debugger::CheckIfTopInputReaderIsDone ()
41130fdc8d8SChris Lattner {
41230fdc8d8SChris Lattner     bool result = false;
41330fdc8d8SChris Lattner     if (!m_input_readers.empty())
41430fdc8d8SChris Lattner     {
41530fdc8d8SChris Lattner         InputReaderSP reader_sp(m_input_readers.top());
41630fdc8d8SChris Lattner 
41730fdc8d8SChris Lattner         if (reader_sp && reader_sp->IsDone())
41830fdc8d8SChris Lattner         {
41930fdc8d8SChris Lattner             result = true;
42030fdc8d8SChris Lattner             PopInputReader (reader_sp);
42130fdc8d8SChris Lattner         }
42230fdc8d8SChris Lattner     }
42330fdc8d8SChris Lattner     return result;
42430fdc8d8SChris Lattner }
42530fdc8d8SChris Lattner 
42630fdc8d8SChris Lattner void
42730fdc8d8SChris Lattner Debugger::ActivateInputReader (const InputReaderSP &reader_sp)
42830fdc8d8SChris Lattner {
42930fdc8d8SChris Lattner     FILE *in_fh = GetInputFileHandle();
43030fdc8d8SChris Lattner 
43130fdc8d8SChris Lattner     if (in_fh)
43230fdc8d8SChris Lattner     {
43330fdc8d8SChris Lattner         struct termios in_fh_termios;
43430fdc8d8SChris Lattner         int in_fd = fileno (in_fh);
43530fdc8d8SChris Lattner         if (::tcgetattr(in_fd, &in_fh_termios) == 0)
43630fdc8d8SChris Lattner         {
43730fdc8d8SChris Lattner             if (reader_sp->GetEcho())
43830fdc8d8SChris Lattner                 in_fh_termios.c_lflag |= ECHO;  // Turn on echoing
43930fdc8d8SChris Lattner             else
44030fdc8d8SChris Lattner                 in_fh_termios.c_lflag &= ~ECHO; // Turn off echoing
44130fdc8d8SChris Lattner 
44230fdc8d8SChris Lattner             switch (reader_sp->GetGranularity())
44330fdc8d8SChris Lattner             {
44430fdc8d8SChris Lattner             case eInputReaderGranularityByte:
44530fdc8d8SChris Lattner             case eInputReaderGranularityWord:
44630fdc8d8SChris Lattner                 in_fh_termios.c_lflag &= ~ICANON;   // Get one char at a time
44730fdc8d8SChris Lattner                 break;
44830fdc8d8SChris Lattner 
44930fdc8d8SChris Lattner             case eInputReaderGranularityLine:
45030fdc8d8SChris Lattner             case eInputReaderGranularityAll:
45130fdc8d8SChris Lattner                 in_fh_termios.c_lflag |= ICANON;   // Get lines at a time
45230fdc8d8SChris Lattner                 break;
45330fdc8d8SChris Lattner 
45430fdc8d8SChris Lattner             default:
45530fdc8d8SChris Lattner                 break;
45630fdc8d8SChris Lattner             }
45730fdc8d8SChris Lattner             ::tcsetattr (in_fd, TCSANOW, &in_fh_termios);
45830fdc8d8SChris Lattner         }
45930fdc8d8SChris Lattner     }
46030fdc8d8SChris Lattner }
4616611103cSGreg Clayton 
4626611103cSGreg Clayton void
4636611103cSGreg Clayton Debugger::UpdateExecutionContext (ExecutionContext *override_context)
4646611103cSGreg Clayton {
4656611103cSGreg Clayton     m_exe_ctx.Clear();
4666611103cSGreg Clayton 
4676611103cSGreg Clayton     if (override_context != NULL)
4686611103cSGreg Clayton     {
4696611103cSGreg Clayton         m_exe_ctx.target = override_context->target;
4706611103cSGreg Clayton         m_exe_ctx.process = override_context->process;
4716611103cSGreg Clayton         m_exe_ctx.thread = override_context->thread;
4726611103cSGreg Clayton         m_exe_ctx.frame = override_context->frame;
4736611103cSGreg Clayton     }
4746611103cSGreg Clayton     else
4756611103cSGreg Clayton     {
476*2976d00aSJim Ingham         TargetSP target_sp (GetSelectedTarget());
4776611103cSGreg Clayton         if (target_sp)
4786611103cSGreg Clayton         {
4796611103cSGreg Clayton             m_exe_ctx.target = target_sp.get();
4806611103cSGreg Clayton             m_exe_ctx.process = target_sp->GetProcessSP().get();
4816611103cSGreg Clayton             if (m_exe_ctx.process && m_exe_ctx.process->IsRunning() == false)
4826611103cSGreg Clayton             {
483*2976d00aSJim Ingham                 m_exe_ctx.thread = m_exe_ctx.process->GetThreadList().GetSelectedThread().get();
4846611103cSGreg Clayton                 if (m_exe_ctx.thread == NULL)
4856611103cSGreg Clayton                     m_exe_ctx.thread = m_exe_ctx.process->GetThreadList().GetThreadAtIndex(0).get();
4866611103cSGreg Clayton                 if (m_exe_ctx.thread)
4876611103cSGreg Clayton                 {
488*2976d00aSJim Ingham                     m_exe_ctx.frame = m_exe_ctx.thread->GetSelectedFrame().get();
4896611103cSGreg Clayton                     if (m_exe_ctx.frame == NULL)
4906611103cSGreg Clayton                         m_exe_ctx.frame = m_exe_ctx.thread->GetStackFrameAtIndex (0).get();
4916611103cSGreg Clayton                 }
4926611103cSGreg Clayton             }
4936611103cSGreg Clayton         }
4946611103cSGreg Clayton     }
4956611103cSGreg Clayton }
4966611103cSGreg Clayton 
497ebc1bb27SCaroline Tice DebuggerSP
498ebc1bb27SCaroline Tice Debugger::FindDebuggerWithID (lldb::user_id_t id)
499ebc1bb27SCaroline Tice {
500ebc1bb27SCaroline Tice     lldb::DebuggerSP debugger_sp;
501ebc1bb27SCaroline Tice 
502ebc1bb27SCaroline Tice     Mutex::Locker locker (GetDebuggerListMutex ());
503ebc1bb27SCaroline Tice     DebuggerList &debugger_list = GetDebuggerList();
504ebc1bb27SCaroline Tice     DebuggerList::iterator pos, end = debugger_list.end();
505ebc1bb27SCaroline Tice     for (pos = debugger_list.begin(); pos != end; ++pos)
506ebc1bb27SCaroline Tice     {
507ebc1bb27SCaroline Tice         if ((*pos).get()->GetID() == id)
508ebc1bb27SCaroline Tice         {
509ebc1bb27SCaroline Tice             debugger_sp = *pos;
510ebc1bb27SCaroline Tice             break;
511ebc1bb27SCaroline Tice         }
512ebc1bb27SCaroline Tice     }
513ebc1bb27SCaroline Tice     return debugger_sp;
514ebc1bb27SCaroline Tice }
515