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 "lldb/API/SBProcess.h" 11 12 #include "lldb/lldb-defines.h" 13 #include "lldb/lldb-types.h" 14 15 #include "lldb/Interpreter/Args.h" 16 #include "lldb/Core/DataBufferHeap.h" 17 #include "lldb/Core/DataExtractor.h" 18 #include "lldb/Core/Debugger.h" 19 #include "lldb/Core/Log.h" 20 #include "lldb/Core/State.h" 21 #include "lldb/Core/Stream.h" 22 #include "lldb/Core/StreamFile.h" 23 #include "lldb/Target/Process.h" 24 #include "lldb/Target/RegisterContext.h" 25 #include "lldb/Target/Target.h" 26 #include "lldb/Target/Thread.h" 27 28 // Project includes 29 30 #include "lldb/API/SBBroadcaster.h" 31 #include "lldb/API/SBDebugger.h" 32 #include "lldb/API/SBCommandReturnObject.h" 33 #include "lldb/API/SBEvent.h" 34 #include "lldb/API/SBThread.h" 35 #include "lldb/API/SBStream.h" 36 #include "lldb/API/SBStringList.h" 37 38 using namespace lldb; 39 using namespace lldb_private; 40 41 42 43 SBProcess::SBProcess () : 44 m_opaque_sp() 45 { 46 } 47 48 49 //---------------------------------------------------------------------- 50 // SBProcess constructor 51 //---------------------------------------------------------------------- 52 53 SBProcess::SBProcess (const SBProcess& rhs) : 54 m_opaque_sp (rhs.m_opaque_sp) 55 { 56 } 57 58 59 SBProcess::SBProcess (const lldb::ProcessSP &process_sp) : 60 m_opaque_sp (process_sp) 61 { 62 } 63 64 const SBProcess& 65 SBProcess::operator = (const SBProcess& rhs) 66 { 67 if (this != &rhs) 68 m_opaque_sp = rhs.m_opaque_sp; 69 return *this; 70 } 71 72 //---------------------------------------------------------------------- 73 // Destructor 74 //---------------------------------------------------------------------- 75 SBProcess::~SBProcess() 76 { 77 } 78 79 void 80 SBProcess::SetProcess (const ProcessSP &process_sp) 81 { 82 m_opaque_sp = process_sp; 83 } 84 85 void 86 SBProcess::Clear () 87 { 88 m_opaque_sp.reset(); 89 } 90 91 92 bool 93 SBProcess::IsValid() const 94 { 95 return m_opaque_sp.get() != NULL; 96 } 97 98 99 uint32_t 100 SBProcess::GetNumThreads () 101 { 102 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 103 104 uint32_t num_threads = 0; 105 if (m_opaque_sp) 106 { 107 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 108 const bool can_update = true; 109 num_threads = m_opaque_sp->GetThreadList().GetSize(can_update); 110 } 111 112 if (log) 113 log->Printf ("SBProcess(%p)::GetNumThreads () => %d", m_opaque_sp.get(), num_threads); 114 115 return num_threads; 116 } 117 118 SBThread 119 SBProcess::GetSelectedThread () const 120 { 121 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 122 123 SBThread sb_thread; 124 if (m_opaque_sp) 125 { 126 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 127 sb_thread.SetThread (m_opaque_sp->GetThreadList().GetSelectedThread()); 128 } 129 130 if (log) 131 { 132 log->Printf ("SBProcess(%p)::GetSelectedThread () => SBThread(%p)", m_opaque_sp.get(), sb_thread.get()); 133 } 134 135 return sb_thread; 136 } 137 138 SBTarget 139 SBProcess::GetTarget() const 140 { 141 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 142 143 SBTarget sb_target; 144 if (m_opaque_sp) 145 sb_target = m_opaque_sp->GetTarget().GetSP(); 146 147 if (log) 148 log->Printf ("SBProcess(%p)::GetTarget () => SBTarget(%p)", m_opaque_sp.get(), sb_target.get()); 149 150 return sb_target; 151 } 152 153 154 size_t 155 SBProcess::PutSTDIN (const char *src, size_t src_len) 156 { 157 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 158 159 size_t ret_val = 0; 160 if (m_opaque_sp) 161 { 162 Error error; 163 ret_val = m_opaque_sp->PutSTDIN (src, src_len, error); 164 } 165 166 if (log) 167 log->Printf ("SBProcess(%p)::PutSTDIN (src=\"%s\", src_len=%d) => %d", 168 m_opaque_sp.get(), 169 src, 170 (uint32_t) src_len, 171 ret_val); 172 173 return ret_val; 174 } 175 176 size_t 177 SBProcess::GetSTDOUT (char *dst, size_t dst_len) const 178 { 179 size_t bytes_read = 0; 180 if (m_opaque_sp) 181 { 182 Error error; 183 bytes_read = m_opaque_sp->GetSTDOUT (dst, dst_len, error); 184 } 185 186 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 187 if (log) 188 log->Printf ("SBProcess(%p)::GetSTDOUT (dst=\"%.*s\", dst_len=%zu) => %zu", 189 m_opaque_sp.get(), (int) bytes_read, dst, dst_len, bytes_read); 190 191 return bytes_read; 192 } 193 194 size_t 195 SBProcess::GetSTDERR (char *dst, size_t dst_len) const 196 { 197 size_t bytes_read = 0; 198 if (m_opaque_sp) 199 { 200 Error error; 201 bytes_read = m_opaque_sp->GetSTDERR (dst, dst_len, error); 202 } 203 204 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 205 if (log) 206 log->Printf ("SBProcess(%p)::GetSTDERR (dst=\"%.*s\", dst_len=%zu) => %zu", 207 m_opaque_sp.get(), (int) bytes_read, dst, dst_len, bytes_read); 208 209 return bytes_read; 210 } 211 212 void 213 SBProcess::ReportEventState (const SBEvent &event, FILE *out) const 214 { 215 if (out == NULL) 216 return; 217 218 if (m_opaque_sp) 219 { 220 const StateType event_state = SBProcess::GetStateFromEvent (event); 221 char message[1024]; 222 int message_len = ::snprintf (message, 223 sizeof (message), 224 "Process %d %s\n", 225 m_opaque_sp->GetID(), 226 SBDebugger::StateAsCString (event_state)); 227 228 if (message_len > 0) 229 ::fwrite (message, 1, message_len, out); 230 } 231 } 232 233 void 234 SBProcess::AppendEventStateReport (const SBEvent &event, SBCommandReturnObject &result) 235 { 236 if (m_opaque_sp) 237 { 238 const StateType event_state = SBProcess::GetStateFromEvent (event); 239 char message[1024]; 240 ::snprintf (message, 241 sizeof (message), 242 "Process %d %s\n", 243 m_opaque_sp->GetID(), 244 SBDebugger::StateAsCString (event_state)); 245 246 result.AppendMessage (message); 247 } 248 } 249 250 bool 251 SBProcess::SetSelectedThread (const SBThread &thread) 252 { 253 if (m_opaque_sp) 254 { 255 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 256 return m_opaque_sp->GetThreadList().SetSelectedThreadByID (thread.GetThreadID()); 257 } 258 return false; 259 } 260 261 bool 262 SBProcess::SetSelectedThreadByID (uint32_t tid) 263 { 264 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 265 266 bool ret_val = false; 267 if (m_opaque_sp) 268 { 269 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 270 ret_val = m_opaque_sp->GetThreadList().SetSelectedThreadByID (tid); 271 } 272 273 if (log) 274 log->Printf ("SBProcess(%p)::SetSelectedThreadByID (tid=0x%4.4x) => %s", 275 m_opaque_sp.get(), tid, (ret_val ? "true" : "false")); 276 277 return ret_val; 278 } 279 280 SBThread 281 SBProcess::GetThreadAtIndex (size_t index) 282 { 283 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 284 285 SBThread thread; 286 if (m_opaque_sp) 287 { 288 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 289 thread.SetThread (m_opaque_sp->GetThreadList().GetThreadAtIndex(index)); 290 } 291 292 if (log) 293 { 294 log->Printf ("SBProcess(%p)::GetThreadAtIndex (index=%d) => SBThread(%p)", 295 m_opaque_sp.get(), (uint32_t) index, thread.get()); 296 } 297 298 return thread; 299 } 300 301 StateType 302 SBProcess::GetState () 303 { 304 305 StateType ret_val = eStateInvalid; 306 if (m_opaque_sp) 307 { 308 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 309 ret_val = m_opaque_sp->GetState(); 310 } 311 312 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 313 if (log) 314 log->Printf ("SBProcess(%p)::GetState () => %s", 315 m_opaque_sp.get(), 316 lldb_private::StateAsCString (ret_val)); 317 318 return ret_val; 319 } 320 321 322 int 323 SBProcess::GetExitStatus () 324 { 325 int exit_status = 0; 326 if (m_opaque_sp) 327 { 328 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 329 exit_status = m_opaque_sp->GetExitStatus (); 330 } 331 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 332 if (log) 333 log->Printf ("SBProcess(%p)::GetExitStatus () => %i (0x%8.8x)", 334 m_opaque_sp.get(), exit_status, exit_status); 335 336 return exit_status; 337 } 338 339 const char * 340 SBProcess::GetExitDescription () 341 { 342 const char *exit_desc = NULL; 343 if (m_opaque_sp) 344 { 345 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 346 exit_desc = m_opaque_sp->GetExitDescription (); 347 } 348 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 349 if (log) 350 log->Printf ("SBProcess(%p)::GetExitDescription () => %s", 351 m_opaque_sp.get(), exit_desc); 352 return exit_desc; 353 } 354 355 lldb::pid_t 356 SBProcess::GetProcessID () 357 { 358 lldb::pid_t ret_val = LLDB_INVALID_PROCESS_ID; 359 if (m_opaque_sp) 360 ret_val = m_opaque_sp->GetID(); 361 362 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 363 if (log) 364 log->Printf ("SBProcess(%p)::GetProcessID () => %d", m_opaque_sp.get(), ret_val); 365 366 return ret_val; 367 } 368 369 uint32_t 370 SBProcess::GetAddressByteSize () const 371 { 372 uint32_t size = 0; 373 if (m_opaque_sp) 374 size = m_opaque_sp->GetAddressByteSize(); 375 376 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 377 if (log) 378 log->Printf ("SBProcess(%p)::GetAddressByteSize () => %d", m_opaque_sp.get(), size); 379 380 return size; 381 } 382 383 SBError 384 SBProcess::Continue () 385 { 386 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 387 388 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 389 if (log) 390 log->Printf ("SBProcess(%p)::Continue ()...", m_opaque_sp.get()); 391 392 SBError sb_error; 393 if (IsValid()) 394 { 395 Error error (m_opaque_sp->Resume()); 396 if (error.Success()) 397 { 398 if (m_opaque_sp->GetTarget().GetDebugger().GetAsyncExecution () == false) 399 { 400 if (log) 401 log->Printf ("SBProcess(%p)::Continue () waiting for process to stop...", m_opaque_sp.get()); 402 m_opaque_sp->WaitForProcessToStop (NULL); 403 } 404 } 405 sb_error.SetError(error); 406 } 407 else 408 sb_error.SetErrorString ("SBProcess is invalid"); 409 410 if (log) 411 { 412 SBStream sstr; 413 sb_error.GetDescription (sstr); 414 log->Printf ("SBProcess(%p)::Continue () => SBError (%p): %s", m_opaque_sp.get(), sb_error.get(), sstr.GetData()); 415 } 416 417 return sb_error; 418 } 419 420 421 SBError 422 SBProcess::Destroy () 423 { 424 SBError sb_error; 425 if (m_opaque_sp) 426 { 427 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 428 sb_error.SetError(m_opaque_sp->Destroy()); 429 } 430 else 431 sb_error.SetErrorString ("SBProcess is invalid"); 432 433 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 434 if (log) 435 { 436 SBStream sstr; 437 sb_error.GetDescription (sstr); 438 log->Printf ("SBProcess(%p)::Destroy () => SBError (%p): %s", 439 m_opaque_sp.get(), 440 sb_error.get(), 441 sstr.GetData()); 442 } 443 444 return sb_error; 445 } 446 447 448 SBError 449 SBProcess::Stop () 450 { 451 SBError sb_error; 452 if (IsValid()) 453 { 454 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 455 sb_error.SetError (m_opaque_sp->Halt()); 456 } 457 else 458 sb_error.SetErrorString ("SBProcess is invalid"); 459 460 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 461 if (log) 462 { 463 SBStream sstr; 464 sb_error.GetDescription (sstr); 465 log->Printf ("SBProcess(%p)::Stop () => SBError (%p): %s", 466 m_opaque_sp.get(), 467 sb_error.get(), 468 sstr.GetData()); 469 } 470 471 return sb_error; 472 } 473 474 SBError 475 SBProcess::Kill () 476 { 477 SBError sb_error; 478 if (m_opaque_sp) 479 { 480 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 481 sb_error.SetError (m_opaque_sp->Destroy()); 482 } 483 else 484 sb_error.SetErrorString ("SBProcess is invalid"); 485 486 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 487 if (log) 488 { 489 SBStream sstr; 490 sb_error.GetDescription (sstr); 491 log->Printf ("SBProcess(%p)::Kill () => SBError (%p): %s", 492 m_opaque_sp.get(), 493 sb_error.get(), 494 sstr.GetData()); 495 } 496 497 return sb_error; 498 } 499 500 SBError 501 SBProcess::Detach () 502 { 503 SBError sb_error; 504 if (m_opaque_sp) 505 { 506 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 507 sb_error.SetError (m_opaque_sp->Detach()); 508 } 509 else 510 sb_error.SetErrorString ("SBProcess is invalid"); 511 512 return sb_error; 513 } 514 515 SBError 516 SBProcess::Signal (int signo) 517 { 518 SBError sb_error; 519 if (m_opaque_sp) 520 { 521 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 522 sb_error.SetError (m_opaque_sp->Signal (signo)); 523 } 524 else 525 sb_error.SetErrorString ("SBProcess is invalid"); 526 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 527 if (log) 528 { 529 SBStream sstr; 530 sb_error.GetDescription (sstr); 531 log->Printf ("SBProcess(%p)::Signal (signo=%i) => SBError (%p): %s", 532 m_opaque_sp.get(), 533 signo, 534 sb_error.get(), 535 sstr.GetData()); 536 } 537 return sb_error; 538 } 539 540 SBThread 541 SBProcess::GetThreadByID (tid_t tid) 542 { 543 SBThread sb_thread; 544 if (m_opaque_sp) 545 { 546 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 547 sb_thread.SetThread (m_opaque_sp->GetThreadList().FindThreadByID ((tid_t) tid)); 548 } 549 550 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 551 if (log) 552 { 553 log->Printf ("SBProcess(%p)::GetThreadByID (tid=0x%4.4x) => SBThread (%p)", 554 m_opaque_sp.get(), 555 tid, 556 sb_thread.get()); 557 } 558 559 return sb_thread; 560 } 561 562 StateType 563 SBProcess::GetStateFromEvent (const SBEvent &event) 564 { 565 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 566 567 StateType ret_val = Process::ProcessEventData::GetStateFromEvent (event.get()); 568 569 if (log) 570 log->Printf ("SBProcess::GetStateFromEvent (event.sp=%p) => %s", event.get(), 571 lldb_private::StateAsCString (ret_val)); 572 573 return ret_val; 574 } 575 576 bool 577 SBProcess::GetRestartedFromEvent (const SBEvent &event) 578 { 579 return Process::ProcessEventData::GetRestartedFromEvent (event.get()); 580 } 581 582 SBProcess 583 SBProcess::GetProcessFromEvent (const SBEvent &event) 584 { 585 SBProcess process(Process::ProcessEventData::GetProcessFromEvent (event.get())); 586 return process; 587 } 588 589 590 SBBroadcaster 591 SBProcess::GetBroadcaster () const 592 { 593 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 594 595 SBBroadcaster broadcaster(m_opaque_sp.get(), false); 596 597 if (log) 598 log->Printf ("SBProcess(%p)::GetBroadcaster () => SBBroadcaster (%p)", m_opaque_sp.get(), 599 broadcaster.get()); 600 601 return broadcaster; 602 } 603 604 lldb_private::Process * 605 SBProcess::operator->() const 606 { 607 return m_opaque_sp.get(); 608 } 609 610 size_t 611 SBProcess::ReadMemory (addr_t addr, void *dst, size_t dst_len, SBError &sb_error) 612 { 613 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 614 615 size_t bytes_read = 0; 616 617 if (log) 618 { 619 log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%llx, dst=%p, dst_len=%zu, SBError (%p))...", 620 m_opaque_sp.get(), 621 addr, 622 dst, 623 (uint32_t) dst_len, 624 sb_error.get()); 625 } 626 627 if (m_opaque_sp) 628 { 629 Error error; 630 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 631 bytes_read = m_opaque_sp->ReadMemory (addr, dst, dst_len, error); 632 sb_error.SetError (error); 633 } 634 else 635 { 636 sb_error.SetErrorString ("SBProcess is invalid"); 637 } 638 639 if (log) 640 { 641 SBStream sstr; 642 sb_error.GetDescription (sstr); 643 log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%llx, dst=%p, dst_len=%zu, SBError (%p): %s) => %d", 644 m_opaque_sp.get(), 645 addr, 646 dst, 647 (uint32_t) dst_len, 648 sb_error.get(), 649 sstr.GetData(), 650 (uint32_t) bytes_read); 651 } 652 653 return bytes_read; 654 } 655 656 size_t 657 SBProcess::WriteMemory (addr_t addr, const void *src, size_t src_len, SBError &sb_error) 658 { 659 size_t bytes_written = 0; 660 661 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 662 if (log) 663 { 664 log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%llx, src=%p, dst_len=%zu, SBError (%p))...", 665 m_opaque_sp.get(), 666 addr, 667 src, 668 (uint32_t) src_len, 669 sb_error.get()); 670 } 671 672 if (m_opaque_sp) 673 { 674 Error error; 675 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 676 bytes_written = m_opaque_sp->WriteMemory (addr, src, src_len, error); 677 sb_error.SetError (error); 678 } 679 680 if (log) 681 { 682 SBStream sstr; 683 sb_error.GetDescription (sstr); 684 log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%llx, src=%p, dst_len=%zu, SBError (%p): %s) => %d", 685 m_opaque_sp.get(), 686 addr, 687 src, 688 (uint32_t) src_len, 689 sb_error.get(), 690 sstr.GetData(), 691 (uint32_t) bytes_written); 692 } 693 694 return bytes_written; 695 } 696 697 // Mimic shared pointer... 698 lldb_private::Process * 699 SBProcess::get() const 700 { 701 return m_opaque_sp.get(); 702 } 703 704 bool 705 SBProcess::GetDescription (SBStream &description) 706 { 707 if (m_opaque_sp) 708 { 709 char path[PATH_MAX]; 710 GetTarget().GetExecutable().GetPath (path, sizeof(path)); 711 Module *exe_module = m_opaque_sp->GetTarget().GetExecutableModule ().get(); 712 const char *exe_name = NULL; 713 if (exe_module) 714 exe_name = exe_module->GetFileSpec().GetFilename().AsCString(); 715 716 description.Printf ("SBProcess: pid = %d, state = %s, threads = %d%s%s", 717 m_opaque_sp->GetID(), 718 lldb_private::StateAsCString (GetState()), 719 GetNumThreads(), 720 exe_name ? ", executable = " : "", 721 exe_name ? exe_name : ""); 722 } 723 else 724 description.Printf ("No value"); 725 726 return true; 727 } 728 729 uint32_t 730 SBProcess::LoadImage (lldb::SBFileSpec &sb_image_spec, lldb::SBError &sb_error) 731 { 732 if (m_opaque_sp) 733 { 734 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 735 return m_opaque_sp->LoadImage (*sb_image_spec, sb_error.ref()); 736 } 737 return LLDB_INVALID_IMAGE_TOKEN; 738 } 739 740 lldb::SBError 741 SBProcess::UnloadImage (uint32_t image_token) 742 { 743 lldb::SBError sb_error; 744 if (m_opaque_sp) 745 { 746 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 747 sb_error.SetError (m_opaque_sp->UnloadImage (image_token)); 748 } 749 else 750 sb_error.SetErrorString("invalid process"); 751 return sb_error; 752 } 753 754 755