1 //===-- SBProcess.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 "SBProcess.h" 11 12 #include "lldb/lldb-defines.h" 13 #include "lldb/lldb-types.h" 14 15 #include "lldb/Core/Args.h" 16 #include "lldb/Core/DataBufferHeap.h" 17 #include "lldb/Core/DataExtractor.h" 18 #include "lldb/Core/State.h" 19 #include "lldb/Core/Stream.h" 20 #include "lldb/Core/StreamFile.h" 21 #include "lldb/Target/Process.h" 22 #include "lldb/Target/Thread.h" 23 #include "lldb/Target/RegisterContext.h" 24 25 // Project includes 26 27 #include "SBBroadcaster.h" 28 #include "SBDebugger.h" 29 #include "SBCommandReturnObject.h" 30 #include "SBEvent.h" 31 #include "SBThread.h" 32 #include "SBStringList.h" 33 34 using namespace lldb; 35 using namespace lldb_private; 36 37 38 39 SBProcess::SBProcess () : 40 m_lldb_object_sp() 41 { 42 } 43 44 45 //---------------------------------------------------------------------- 46 // SBProcess constructor 47 //---------------------------------------------------------------------- 48 49 SBProcess::SBProcess (const SBProcess& rhs) : 50 m_lldb_object_sp (rhs.m_lldb_object_sp) 51 { 52 } 53 54 55 SBProcess::SBProcess (const lldb::ProcessSP &process_sp) : 56 m_lldb_object_sp (process_sp) 57 { 58 } 59 60 //---------------------------------------------------------------------- 61 // Destructor 62 //---------------------------------------------------------------------- 63 SBProcess::~SBProcess() 64 { 65 } 66 67 void 68 SBProcess::SetProcess (const ProcessSP &process_sp) 69 { 70 m_lldb_object_sp = process_sp; 71 } 72 73 void 74 SBProcess::Clear () 75 { 76 m_lldb_object_sp.reset(); 77 } 78 79 80 bool 81 SBProcess::IsValid() const 82 { 83 return m_lldb_object_sp.get() != NULL; 84 } 85 86 87 uint32_t 88 SBProcess::GetNumThreads () 89 { 90 if (m_lldb_object_sp) 91 { 92 const bool can_update = true; 93 return m_lldb_object_sp->GetThreadList().GetSize(can_update); 94 } 95 return 0; 96 } 97 98 SBThread 99 SBProcess::GetCurrentThread () const 100 { 101 SBThread sb_thread; 102 if (m_lldb_object_sp) 103 sb_thread.SetThread (m_lldb_object_sp->GetThreadList().GetCurrentThread()); 104 return sb_thread; 105 } 106 107 SBTarget 108 SBProcess::GetTarget() const 109 { 110 SBTarget sb_target; 111 if (m_lldb_object_sp) 112 sb_target = SBDebugger::FindTargetWithLLDBProcess (m_lldb_object_sp); 113 return sb_target; 114 } 115 116 117 size_t 118 SBProcess::PutSTDIN (const char *src, size_t src_len) 119 { 120 if (m_lldb_object_sp != NULL) 121 { 122 Error error; 123 return m_lldb_object_sp->PutSTDIN (src, src_len, error); 124 } 125 else 126 return 0; 127 } 128 129 size_t 130 SBProcess::GetSTDOUT (char *dst, size_t dst_len) const 131 { 132 if (m_lldb_object_sp != NULL) 133 { 134 Error error; 135 return m_lldb_object_sp->GetSTDOUT (dst, dst_len, error); 136 } 137 else 138 return 0; 139 } 140 141 size_t 142 SBProcess::GetSTDERR (char *dst, size_t dst_len) const 143 { 144 if (m_lldb_object_sp != NULL) 145 { 146 Error error; 147 return m_lldb_object_sp->GetSTDERR (dst, dst_len, error); 148 } 149 else 150 return 0; 151 } 152 153 void 154 SBProcess::ReportCurrentState (const SBEvent &event, FILE *out) const 155 { 156 if (out == NULL) 157 return; 158 159 if (m_lldb_object_sp != NULL) 160 { 161 const StateType event_state = SBProcess::GetStateFromEvent (event); 162 char message[1024]; 163 int message_len = ::snprintf (message, 164 sizeof (message), 165 "Process %d %s\n", 166 m_lldb_object_sp->GetID(), 167 SBDebugger::StateAsCString (event_state)); 168 169 if (message_len > 0) 170 ::fwrite (message, 1, message_len, out); 171 } 172 } 173 174 void 175 SBProcess::AppendCurrentStateReport (const SBEvent &event, SBCommandReturnObject &result) 176 { 177 if (m_lldb_object_sp != NULL) 178 { 179 const StateType event_state = SBProcess::GetStateFromEvent (event); 180 char message[1024]; 181 ::snprintf (message, 182 sizeof (message), 183 "Process %d %s\n", 184 m_lldb_object_sp->GetID(), 185 SBDebugger::StateAsCString (event_state)); 186 187 result.AppendMessage (message); 188 } 189 } 190 191 bool 192 SBProcess::SetCurrentThread (const SBThread &thread) 193 { 194 if (m_lldb_object_sp != NULL) 195 return m_lldb_object_sp->GetThreadList().SetCurrentThreadByID (thread.GetThreadID()); 196 return false; 197 } 198 199 bool 200 SBProcess::SetCurrentThreadByID (uint32_t tid) 201 { 202 if (m_lldb_object_sp != NULL) 203 return m_lldb_object_sp->GetThreadList().SetCurrentThreadByID (tid); 204 return false; 205 } 206 207 SBThread 208 SBProcess::GetThreadAtIndex (size_t index) 209 { 210 SBThread thread; 211 if (m_lldb_object_sp) 212 thread.SetThread (m_lldb_object_sp->GetThreadList().GetThreadAtIndex(index)); 213 return thread; 214 } 215 216 StateType 217 SBProcess::GetState () 218 { 219 if (m_lldb_object_sp != NULL) 220 return m_lldb_object_sp->GetState(); 221 else 222 return eStateInvalid; 223 } 224 225 226 int 227 SBProcess::GetExitStatus () 228 { 229 if (m_lldb_object_sp != NULL) 230 return m_lldb_object_sp->GetExitStatus (); 231 else 232 return 0; 233 } 234 235 const char * 236 SBProcess::GetExitDescription () 237 { 238 if (m_lldb_object_sp != NULL) 239 return m_lldb_object_sp->GetExitDescription (); 240 else 241 return NULL; 242 } 243 244 lldb::pid_t 245 SBProcess::GetProcessID () 246 { 247 if (m_lldb_object_sp) 248 return m_lldb_object_sp->GetID(); 249 else 250 return LLDB_INVALID_PROCESS_ID; 251 } 252 253 uint32_t 254 SBProcess::GetAddressByteSize () const 255 { 256 if (m_lldb_object_sp) 257 return m_lldb_object_sp->GetAddressByteSize(); 258 else 259 return 0; 260 } 261 262 263 void 264 SBProcess::DisplayThreadsInfo (FILE *out, FILE *err, bool only_threads_with_stop_reason) 265 { 266 if (m_lldb_object_sp != NULL) 267 { 268 size_t num_thread_infos_dumped = 0; 269 size_t num_threads = GetNumThreads(); 270 271 if (out == NULL) 272 out = SBDebugger::GetOutputFileHandle(); 273 274 if (err == NULL) 275 err = SBDebugger::GetErrorFileHandle(); 276 277 if ((out == NULL) ||(err == NULL)) 278 return; 279 280 if (num_threads > 0) 281 { 282 Thread::StopInfo thread_stop_info; 283 SBThread curr_thread (m_lldb_object_sp->GetThreadList().GetCurrentThread()); 284 for (int i = 0; i < num_threads; ++i) 285 { 286 SBThread thread (m_lldb_object_sp->GetThreadList().GetThreadAtIndex(i)); 287 if (thread.IsValid()) 288 { 289 bool is_current_thread = false; 290 StreamFile str (out); 291 if (thread == curr_thread) 292 is_current_thread = true; 293 StopReason thread_stop_reason = eStopReasonNone; 294 if (thread->GetStopInfo (&thread_stop_info)) 295 { 296 thread_stop_reason = thread_stop_info.GetStopReason(); 297 if (thread_stop_reason == eStopReasonNone) 298 { 299 if (only_threads_with_stop_reason && !is_current_thread) 300 continue; 301 } 302 } 303 ++num_thread_infos_dumped; 304 fprintf (out, " %c thread #%u: tid = 0x%4.4x, pc = 0x%16.16llx", 305 (is_current_thread ? '*' : ' '), 306 thread->GetIndexID(), thread->GetID(), thread->GetRegisterContext()->GetPC()); 307 308 StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0)); 309 if (frame_sp) 310 { 311 SymbolContext sc (frame_sp->GetSymbolContext (eSymbolContextEverything)); 312 fprintf (out, ", where = "); 313 sc.DumpStopContext (&str, m_lldb_object_sp.get(), frame_sp->GetPC ()); 314 } 315 316 if (thread_stop_reason != eStopReasonNone) 317 { 318 fprintf (out, ", stop reason = "); 319 thread_stop_info.Dump (&str); 320 } 321 322 const char *thread_name = thread->GetName(); 323 if (thread_name && thread_name[0]) 324 fprintf (out, ", thread_name = '%s'", thread_name); 325 326 fprintf (out, "\n"); 327 328 SBThread sb_thread (thread); 329 sb_thread.DisplayFramesForCurrentContext (out, err, 0, 1, false, 1); 330 } 331 } 332 } 333 } 334 } 335 bool 336 SBProcess::WaitUntilProcessHasStopped (SBCommandReturnObject &result) 337 { 338 bool state_changed = false; 339 340 if (IsValid()) 341 { 342 EventSP event_sp; 343 StateType state = m_lldb_object_sp->WaitForStateChangedEvents (NULL, event_sp); 344 345 while (StateIsStoppedState (state)) 346 { 347 state = m_lldb_object_sp->WaitForStateChangedEvents (NULL, event_sp); 348 SBEvent event (event_sp); 349 AppendCurrentStateReport (event, result); 350 state_changed = true; 351 } 352 } 353 return state_changed; 354 } 355 356 SBError 357 SBProcess::Continue () 358 { 359 SBError sb_error; 360 if (IsValid()) 361 sb_error.SetError(m_lldb_object_sp->Resume()); 362 else 363 sb_error.SetErrorString ("SBProcess is invalid"); 364 365 return sb_error; 366 } 367 368 369 SBError 370 SBProcess::Destroy () 371 { 372 SBError sb_error; 373 if (m_lldb_object_sp) 374 sb_error.SetError(m_lldb_object_sp->Destroy()); 375 else 376 sb_error.SetErrorString ("SBProcess is invalid"); 377 378 return sb_error; 379 } 380 381 382 SBError 383 SBProcess::Stop () 384 { 385 SBError sb_error; 386 if (IsValid()) 387 sb_error.SetError (m_lldb_object_sp->Halt()); 388 else 389 sb_error.SetErrorString ("SBProcess is invalid"); 390 return sb_error; 391 } 392 393 SBError 394 SBProcess::Kill () 395 { 396 SBError sb_error; 397 if (m_lldb_object_sp) 398 sb_error.SetError (m_lldb_object_sp->Destroy()); 399 else 400 sb_error.SetErrorString ("SBProcess is invalid"); 401 return sb_error; 402 } 403 404 405 SBError 406 SBProcess::AttachByName (const char *name, bool wait_for_launch) 407 { 408 SBError sb_error; 409 if (m_lldb_object_sp) 410 sb_error.SetError (m_lldb_object_sp->Attach (name, wait_for_launch)); 411 else 412 sb_error.SetErrorString ("SBProcess is invalid"); 413 return sb_error; 414 } 415 416 lldb::pid_t 417 SBProcess::AttachByPID (lldb::pid_t attach_pid) // DEPRECATED: will be removed in a few builds in favor of SBError AttachByPID(pid_t) 418 { 419 Attach (attach_pid); 420 return GetProcessID(); 421 } 422 423 424 SBError 425 SBProcess::Attach (lldb::pid_t attach_pid) 426 { 427 SBError sb_error; 428 if (m_lldb_object_sp) 429 sb_error.SetError (m_lldb_object_sp->Attach (attach_pid)); 430 else 431 sb_error.SetErrorString ("SBProcess is invalid"); 432 return sb_error; 433 } 434 435 SBError 436 SBProcess::Detach () 437 { 438 SBError sb_error; 439 if (m_lldb_object_sp) 440 sb_error.SetError (m_lldb_object_sp->Detach()); 441 else 442 sb_error.SetErrorString ("SBProcess is invalid"); 443 444 return sb_error; 445 } 446 447 SBError 448 SBProcess::Signal (int signal) 449 { 450 SBError sb_error; 451 if (m_lldb_object_sp) 452 sb_error.SetError (m_lldb_object_sp->Signal (signal)); 453 else 454 sb_error.SetErrorString ("SBProcess is invalid"); 455 return sb_error; 456 } 457 458 void 459 SBProcess::ListThreads () 460 { 461 FILE *out = SBDebugger::GetOutputFileHandle(); 462 if (out == NULL) 463 return; 464 465 if (m_lldb_object_sp) 466 { 467 size_t num_threads = GetNumThreads (); 468 if (num_threads > 0) 469 { 470 Thread *cur_thread = m_lldb_object_sp->GetThreadList().GetCurrentThread().get(); 471 for (int i = 0; i < num_threads; ++i) 472 { 473 Thread *thread = m_lldb_object_sp->GetThreadList().GetThreadAtIndex(i).get(); 474 if (thread) 475 { 476 bool is_current_thread = false; 477 if (thread == cur_thread) 478 is_current_thread = true; 479 fprintf (out, " [%u] %c tid = 0x%4.4x, pc = 0x%16.16llx", 480 i, 481 (is_current_thread ? '*' : ' '), 482 thread->GetID(), 483 thread->GetRegisterContext()->GetPC()); 484 const char *thread_name = thread->GetName(); 485 if (thread_name && thread_name[0]) 486 fprintf (out, ", name = %s", thread_name); 487 const char *queue_name = thread->GetQueueName(); 488 if (queue_name && queue_name[0]) 489 fprintf (out, ", queue = %s", queue_name); 490 fprintf (out, "\n"); 491 } 492 } 493 } 494 } 495 } 496 497 SBThread 498 SBProcess::GetThreadByID (tid_t sb_thread_id) 499 { 500 SBThread thread; 501 if (m_lldb_object_sp) 502 thread.SetThread (m_lldb_object_sp->GetThreadList().FindThreadByID ((tid_t) sb_thread_id)); 503 return thread; 504 } 505 506 void 507 SBProcess::Backtrace (bool all_threads, uint32_t num_frames) 508 { 509 if (m_lldb_object_sp) 510 { 511 if (!all_threads) 512 { 513 SBDebugger::UpdateCurrentThread (*this); 514 SBThread cur_thread = GetCurrentThread(); 515 if (cur_thread.IsValid()) 516 cur_thread.Backtrace (num_frames); 517 } 518 else 519 { 520 int num_threads = GetNumThreads (); 521 for (int i = 0; i < num_threads; ++i) 522 { 523 SBThread sb_thread = GetThreadAtIndex (i); 524 sb_thread.Backtrace (num_frames); 525 } 526 } 527 } 528 } 529 530 StateType 531 SBProcess::GetStateFromEvent (const SBEvent &event) 532 { 533 return Process::ProcessEventData::GetStateFromEvent (event.GetLLDBObjectPtr()); 534 } 535 536 537 bool 538 SBProcess::GetRestartedFromEvent (const SBEvent &event) 539 { 540 return Process::ProcessEventData::GetRestartedFromEvent (event.GetLLDBObjectPtr()); 541 } 542 543 SBProcess 544 SBProcess::GetProcessFromEvent (const SBEvent &event) 545 { 546 SBProcess process(Process::ProcessEventData::GetProcessFromEvent (event.GetLLDBObjectPtr())); 547 return process; 548 } 549 550 551 SBBroadcaster 552 SBProcess::GetBroadcaster () const 553 { 554 SBBroadcaster broadcaster(m_lldb_object_sp.get(), false); 555 return broadcaster; 556 } 557 558 lldb_private::Process * 559 SBProcess::operator->() const 560 { 561 return m_lldb_object_sp.get(); 562 } 563 564 size_t 565 SBProcess::ReadMemory (addr_t addr, void *dst, size_t dst_len, SBError &sb_error) 566 { 567 size_t bytes_read = 0; 568 569 if (IsValid()) 570 { 571 Error error; 572 bytes_read = m_lldb_object_sp->ReadMemory (addr, dst, dst_len, error); 573 sb_error.SetError (error); 574 } 575 else 576 { 577 sb_error.SetErrorString ("SBProcess is invalid"); 578 } 579 580 return bytes_read; 581 } 582 583 size_t 584 SBProcess::WriteMemory (addr_t addr, const void *src, size_t src_len, SBError &sb_error) 585 { 586 size_t bytes_written = 0; 587 588 if (IsValid()) 589 { 590 Error error; 591 bytes_written = m_lldb_object_sp->WriteMemory (addr, src, src_len, error); 592 sb_error.SetError (error); 593 } 594 595 return bytes_written; 596 } 597 598 // Mimic shared pointer... 599 lldb_private::Process * 600 SBProcess::get() const 601 { 602 return m_lldb_object_sp.get(); 603 } 604 605