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 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 425 426 SBError sb_error; 427 if (m_opaque_sp) 428 sb_error.SetError(m_opaque_sp->Destroy()); 429 else 430 sb_error.SetErrorString ("SBProcess is invalid"); 431 432 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 433 if (log) 434 { 435 SBStream sstr; 436 sb_error.GetDescription (sstr); 437 log->Printf ("SBProcess(%p)::Destroy () => SBError (%p): %s", m_opaque_sp.get(), sb_error.get(), sstr.GetData()); 438 } 439 440 return sb_error; 441 } 442 443 444 SBError 445 SBProcess::Stop () 446 { 447 SBError sb_error; 448 if (IsValid()) 449 { 450 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 451 sb_error.SetError (m_opaque_sp->Halt()); 452 } 453 else 454 sb_error.SetErrorString ("SBProcess is invalid"); 455 456 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 457 if (log) 458 { 459 SBStream sstr; 460 sb_error.GetDescription (sstr); 461 log->Printf ("SBProcess(%p)::Stop () => SBError (%p): %s", 462 m_opaque_sp.get(), 463 sb_error.get(), 464 sstr.GetData()); 465 } 466 467 return sb_error; 468 } 469 470 SBError 471 SBProcess::Kill () 472 { 473 SBError sb_error; 474 if (m_opaque_sp) 475 { 476 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 477 sb_error.SetError (m_opaque_sp->Destroy()); 478 } 479 else 480 sb_error.SetErrorString ("SBProcess is invalid"); 481 482 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 483 if (log) 484 { 485 SBStream sstr; 486 sb_error.GetDescription (sstr); 487 log->Printf ("SBProcess(%p)::Kill () => SBError (%p): %s", 488 m_opaque_sp.get(), 489 sb_error.get(), 490 sstr.GetData()); 491 } 492 493 return sb_error; 494 } 495 496 SBError 497 SBProcess::Detach () 498 { 499 SBError sb_error; 500 if (m_opaque_sp) 501 { 502 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 503 sb_error.SetError (m_opaque_sp->Detach()); 504 } 505 else 506 sb_error.SetErrorString ("SBProcess is invalid"); 507 508 return sb_error; 509 } 510 511 SBError 512 SBProcess::Signal (int signo) 513 { 514 SBError sb_error; 515 if (m_opaque_sp) 516 { 517 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 518 sb_error.SetError (m_opaque_sp->Signal (signo)); 519 } 520 else 521 sb_error.SetErrorString ("SBProcess is invalid"); 522 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 523 if (log) 524 { 525 SBStream sstr; 526 sb_error.GetDescription (sstr); 527 log->Printf ("SBProcess(%p)::Signal (signo=%i) => SBError (%p): %s", 528 m_opaque_sp.get(), 529 signo, 530 sb_error.get(), 531 sstr.GetData()); 532 } 533 return sb_error; 534 } 535 536 SBThread 537 SBProcess::GetThreadByID (tid_t tid) 538 { 539 SBThread sb_thread; 540 if (m_opaque_sp) 541 { 542 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 543 sb_thread.SetThread (m_opaque_sp->GetThreadList().FindThreadByID ((tid_t) tid)); 544 } 545 546 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 547 if (log) 548 { 549 log->Printf ("SBProcess(%p)::GetThreadByID (tid=0x%4.4x) => SBThread (%p)", 550 m_opaque_sp.get(), 551 tid, 552 sb_thread.get()); 553 } 554 555 return sb_thread; 556 } 557 558 StateType 559 SBProcess::GetStateFromEvent (const SBEvent &event) 560 { 561 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 562 563 StateType ret_val = Process::ProcessEventData::GetStateFromEvent (event.get()); 564 565 if (log) 566 log->Printf ("SBProcess::GetStateFromEvent (event.sp=%p) => %s", event.get(), 567 lldb_private::StateAsCString (ret_val)); 568 569 return ret_val; 570 } 571 572 bool 573 SBProcess::GetRestartedFromEvent (const SBEvent &event) 574 { 575 return Process::ProcessEventData::GetRestartedFromEvent (event.get()); 576 } 577 578 SBProcess 579 SBProcess::GetProcessFromEvent (const SBEvent &event) 580 { 581 SBProcess process(Process::ProcessEventData::GetProcessFromEvent (event.get())); 582 return process; 583 } 584 585 586 SBBroadcaster 587 SBProcess::GetBroadcaster () const 588 { 589 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 590 591 SBBroadcaster broadcaster(m_opaque_sp.get(), false); 592 593 if (log) 594 log->Printf ("SBProcess(%p)::GetBroadcaster () => SBBroadcaster (%p)", m_opaque_sp.get(), 595 broadcaster.get()); 596 597 return broadcaster; 598 } 599 600 lldb_private::Process * 601 SBProcess::operator->() const 602 { 603 return m_opaque_sp.get(); 604 } 605 606 size_t 607 SBProcess::ReadMemory (addr_t addr, void *dst, size_t dst_len, SBError &sb_error) 608 { 609 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 610 611 size_t bytes_read = 0; 612 613 if (log) 614 { 615 log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%llx, dst=%p, dst_len=%zu, SBError (%p))...", 616 m_opaque_sp.get(), 617 addr, 618 dst, 619 (uint32_t) dst_len, 620 sb_error.get()); 621 } 622 623 if (m_opaque_sp) 624 { 625 Error error; 626 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 627 bytes_read = m_opaque_sp->ReadMemory (addr, dst, dst_len, error); 628 sb_error.SetError (error); 629 } 630 else 631 { 632 sb_error.SetErrorString ("SBProcess is invalid"); 633 } 634 635 if (log) 636 { 637 SBStream sstr; 638 sb_error.GetDescription (sstr); 639 log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%llx, dst=%p, dst_len=%zu, SBError (%p): %s) => %d", 640 m_opaque_sp.get(), 641 addr, 642 dst, 643 (uint32_t) dst_len, 644 sb_error.get(), 645 sstr.GetData(), 646 (uint32_t) bytes_read); 647 } 648 649 return bytes_read; 650 } 651 652 size_t 653 SBProcess::WriteMemory (addr_t addr, const void *src, size_t src_len, SBError &sb_error) 654 { 655 size_t bytes_written = 0; 656 657 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 658 if (log) 659 { 660 log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%llx, src=%p, dst_len=%zu, SBError (%p))...", 661 m_opaque_sp.get(), 662 addr, 663 src, 664 (uint32_t) src_len, 665 sb_error.get()); 666 } 667 668 if (m_opaque_sp) 669 { 670 Error error; 671 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 672 bytes_written = m_opaque_sp->WriteMemory (addr, src, src_len, error); 673 sb_error.SetError (error); 674 } 675 676 if (log) 677 { 678 SBStream sstr; 679 sb_error.GetDescription (sstr); 680 log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%llx, src=%p, dst_len=%zu, SBError (%p): %s) => %d", 681 m_opaque_sp.get(), 682 addr, 683 src, 684 (uint32_t) src_len, 685 sb_error.get(), 686 sstr.GetData(), 687 (uint32_t) bytes_written); 688 } 689 690 return bytes_written; 691 } 692 693 // Mimic shared pointer... 694 lldb_private::Process * 695 SBProcess::get() const 696 { 697 return m_opaque_sp.get(); 698 } 699 700 bool 701 SBProcess::GetDescription (SBStream &description) 702 { 703 if (m_opaque_sp) 704 { 705 char path[PATH_MAX]; 706 GetTarget().GetExecutable().GetPath (path, sizeof(path)); 707 Module *exe_module = m_opaque_sp->GetTarget().GetExecutableModule ().get(); 708 const char *exe_name = NULL; 709 if (exe_module) 710 exe_name = exe_module->GetFileSpec().GetFilename().AsCString(); 711 712 description.Printf ("SBProcess: pid = %d, state = %s, threads = %d%s%s", 713 m_opaque_sp->GetID(), 714 lldb_private::StateAsCString (GetState()), 715 GetNumThreads(), 716 exe_name ? ", executable = " : "", 717 exe_name ? exe_name : ""); 718 } 719 else 720 description.Printf ("No value"); 721 722 return true; 723 } 724 725 uint32_t 726 SBProcess::LoadImage (lldb::SBFileSpec &sb_image_spec, lldb::SBError &sb_error) 727 { 728 if (m_opaque_sp) 729 { 730 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 731 return m_opaque_sp->LoadImage (*sb_image_spec, sb_error.ref()); 732 } 733 return LLDB_INVALID_IMAGE_TOKEN; 734 } 735 736 lldb::SBError 737 SBProcess::UnloadImage (uint32_t image_token) 738 { 739 lldb::SBError sb_error; 740 if (m_opaque_sp) 741 { 742 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 743 sb_error.SetError (m_opaque_sp->UnloadImage (image_token)); 744 } 745 else 746 sb_error.SetErrorString("invalid process"); 747 return sb_error; 748 } 749 750 751