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