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