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