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 bool 99 SBProcess::RemoteLaunch (char const **argv, 100 char const **envp, 101 const char *stdin_path, 102 const char *stdout_path, 103 const char *stderr_path, 104 const char *working_directory, 105 uint32_t launch_flags, 106 bool stop_at_entry, 107 lldb::SBError& error) 108 { 109 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 110 if (log) { 111 log->Printf ("SBProcess(%p)::RemoteLaunch (argv=%p, envp=%p, stdin=%s, stdout=%s, stderr=%s, working-dir=%s, launch_flags=0x%x, stop_at_entry=%i, &error (%p))...", 112 m_opaque_sp.get(), 113 argv, 114 envp, 115 stdin_path ? stdin_path : "NULL", 116 stdout_path ? stdout_path : "NULL", 117 stderr_path ? stderr_path : "NULL", 118 working_directory ? working_directory : "NULL", 119 launch_flags, 120 stop_at_entry, 121 error.get()); 122 } 123 124 if (m_opaque_sp) 125 { 126 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 127 if (m_opaque_sp->GetState() == eStateConnected) 128 { 129 if (stop_at_entry) 130 launch_flags |= eLaunchFlagStopAtEntry; 131 ProcessLaunchInfo launch_info (stdin_path, 132 stdout_path, 133 stderr_path, 134 working_directory, 135 launch_flags); 136 Module *exe_module = m_opaque_sp->GetTarget().GetExecutableModulePointer(); 137 if (exe_module) 138 launch_info.SetExecutableFile(exe_module->GetFileSpec(), true); 139 if (argv) 140 launch_info.GetArguments().AppendArguments (argv); 141 if (envp) 142 launch_info.GetEnvironmentEntries ().SetArguments (envp); 143 error.SetError (m_opaque_sp->Launch (launch_info)); 144 } 145 else 146 { 147 error.SetErrorString ("must be in eStateConnected to call RemoteLaunch"); 148 } 149 } 150 else 151 { 152 error.SetErrorString ("unable to attach pid"); 153 } 154 155 if (log) { 156 SBStream sstr; 157 error.GetDescription (sstr); 158 log->Printf ("SBProcess(%p)::RemoteLaunch (...) => SBError (%p): %s", m_opaque_sp.get(), error.get(), sstr.GetData()); 159 } 160 161 return error.Success(); 162 } 163 164 bool 165 SBProcess::RemoteAttachToProcessWithID (lldb::pid_t pid, lldb::SBError& error) 166 { 167 if (m_opaque_sp) 168 { 169 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 170 if (m_opaque_sp->GetState() == eStateConnected) 171 { 172 error.SetError (m_opaque_sp->Attach (pid)); 173 } 174 else 175 { 176 error.SetErrorString ("must be in eStateConnected to call RemoteAttachToProcessWithID"); 177 } 178 } 179 else 180 { 181 error.SetErrorString ("unable to attach pid"); 182 } 183 184 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 185 if (log) { 186 SBStream sstr; 187 error.GetDescription (sstr); 188 log->Printf ("SBProcess(%p)::RemoteAttachToProcessWithID (%d) => SBError (%p): %s", m_opaque_sp.get(), pid, error.get(), sstr.GetData()); 189 } 190 191 return error.Success(); 192 } 193 194 195 uint32_t 196 SBProcess::GetNumThreads () 197 { 198 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 199 200 uint32_t num_threads = 0; 201 if (m_opaque_sp) 202 { 203 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 204 const bool can_update = true; 205 num_threads = m_opaque_sp->GetThreadList().GetSize(can_update); 206 } 207 208 if (log) 209 log->Printf ("SBProcess(%p)::GetNumThreads () => %d", m_opaque_sp.get(), num_threads); 210 211 return num_threads; 212 } 213 214 SBThread 215 SBProcess::GetSelectedThread () const 216 { 217 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 218 219 SBThread sb_thread; 220 if (m_opaque_sp) 221 { 222 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 223 sb_thread.SetThread (m_opaque_sp->GetThreadList().GetSelectedThread()); 224 } 225 226 if (log) 227 { 228 log->Printf ("SBProcess(%p)::GetSelectedThread () => SBThread(%p)", m_opaque_sp.get(), sb_thread.get()); 229 } 230 231 return sb_thread; 232 } 233 234 SBTarget 235 SBProcess::GetTarget() const 236 { 237 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 238 239 SBTarget sb_target; 240 if (m_opaque_sp) 241 sb_target = m_opaque_sp->GetTarget().GetSP(); 242 243 if (log) 244 log->Printf ("SBProcess(%p)::GetTarget () => SBTarget(%p)", m_opaque_sp.get(), sb_target.get()); 245 246 return sb_target; 247 } 248 249 250 size_t 251 SBProcess::PutSTDIN (const char *src, size_t src_len) 252 { 253 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 254 255 size_t ret_val = 0; 256 if (m_opaque_sp) 257 { 258 Error error; 259 ret_val = m_opaque_sp->PutSTDIN (src, src_len, error); 260 } 261 262 if (log) 263 log->Printf ("SBProcess(%p)::PutSTDIN (src=\"%s\", src_len=%d) => %lu", 264 m_opaque_sp.get(), 265 src, 266 (uint32_t) src_len, 267 ret_val); 268 269 return ret_val; 270 } 271 272 size_t 273 SBProcess::GetSTDOUT (char *dst, size_t dst_len) const 274 { 275 size_t bytes_read = 0; 276 if (m_opaque_sp) 277 { 278 Error error; 279 bytes_read = m_opaque_sp->GetSTDOUT (dst, dst_len, error); 280 } 281 282 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 283 if (log) 284 log->Printf ("SBProcess(%p)::GetSTDOUT (dst=\"%.*s\", dst_len=%zu) => %zu", 285 m_opaque_sp.get(), (int) bytes_read, dst, dst_len, bytes_read); 286 287 return bytes_read; 288 } 289 290 size_t 291 SBProcess::GetSTDERR (char *dst, size_t dst_len) const 292 { 293 size_t bytes_read = 0; 294 if (m_opaque_sp) 295 { 296 Error error; 297 bytes_read = m_opaque_sp->GetSTDERR (dst, dst_len, error); 298 } 299 300 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 301 if (log) 302 log->Printf ("SBProcess(%p)::GetSTDERR (dst=\"%.*s\", dst_len=%zu) => %zu", 303 m_opaque_sp.get(), (int) bytes_read, dst, dst_len, bytes_read); 304 305 return bytes_read; 306 } 307 308 void 309 SBProcess::ReportEventState (const SBEvent &event, FILE *out) const 310 { 311 if (out == NULL) 312 return; 313 314 if (m_opaque_sp) 315 { 316 const StateType event_state = SBProcess::GetStateFromEvent (event); 317 char message[1024]; 318 int message_len = ::snprintf (message, 319 sizeof (message), 320 "Process %llu %s\n", 321 m_opaque_sp->GetID(), 322 SBDebugger::StateAsCString (event_state)); 323 324 if (message_len > 0) 325 ::fwrite (message, 1, message_len, out); 326 } 327 } 328 329 void 330 SBProcess::AppendEventStateReport (const SBEvent &event, SBCommandReturnObject &result) 331 { 332 if (m_opaque_sp) 333 { 334 const StateType event_state = SBProcess::GetStateFromEvent (event); 335 char message[1024]; 336 ::snprintf (message, 337 sizeof (message), 338 "Process %llu %s\n", 339 m_opaque_sp->GetID(), 340 SBDebugger::StateAsCString (event_state)); 341 342 result.AppendMessage (message); 343 } 344 } 345 346 bool 347 SBProcess::SetSelectedThread (const SBThread &thread) 348 { 349 if (m_opaque_sp) 350 { 351 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 352 return m_opaque_sp->GetThreadList().SetSelectedThreadByID (thread.GetThreadID()); 353 } 354 return false; 355 } 356 357 bool 358 SBProcess::SetSelectedThreadByID (uint32_t tid) 359 { 360 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 361 362 bool ret_val = false; 363 if (m_opaque_sp) 364 { 365 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 366 ret_val = m_opaque_sp->GetThreadList().SetSelectedThreadByID (tid); 367 } 368 369 if (log) 370 log->Printf ("SBProcess(%p)::SetSelectedThreadByID (tid=0x%4.4x) => %s", 371 m_opaque_sp.get(), tid, (ret_val ? "true" : "false")); 372 373 return ret_val; 374 } 375 376 SBThread 377 SBProcess::GetThreadAtIndex (size_t index) 378 { 379 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 380 381 SBThread thread; 382 if (m_opaque_sp) 383 { 384 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 385 thread.SetThread (m_opaque_sp->GetThreadList().GetThreadAtIndex(index)); 386 } 387 388 if (log) 389 { 390 log->Printf ("SBProcess(%p)::GetThreadAtIndex (index=%d) => SBThread(%p)", 391 m_opaque_sp.get(), (uint32_t) index, thread.get()); 392 } 393 394 return thread; 395 } 396 397 StateType 398 SBProcess::GetState () 399 { 400 401 StateType ret_val = eStateInvalid; 402 if (m_opaque_sp) 403 { 404 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 405 ret_val = m_opaque_sp->GetState(); 406 } 407 408 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 409 if (log) 410 log->Printf ("SBProcess(%p)::GetState () => %s", 411 m_opaque_sp.get(), 412 lldb_private::StateAsCString (ret_val)); 413 414 return ret_val; 415 } 416 417 418 int 419 SBProcess::GetExitStatus () 420 { 421 int exit_status = 0; 422 if (m_opaque_sp) 423 { 424 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 425 exit_status = m_opaque_sp->GetExitStatus (); 426 } 427 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 428 if (log) 429 log->Printf ("SBProcess(%p)::GetExitStatus () => %i (0x%8.8x)", 430 m_opaque_sp.get(), exit_status, exit_status); 431 432 return exit_status; 433 } 434 435 const char * 436 SBProcess::GetExitDescription () 437 { 438 const char *exit_desc = NULL; 439 if (m_opaque_sp) 440 { 441 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 442 exit_desc = m_opaque_sp->GetExitDescription (); 443 } 444 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 445 if (log) 446 log->Printf ("SBProcess(%p)::GetExitDescription () => %s", 447 m_opaque_sp.get(), exit_desc); 448 return exit_desc; 449 } 450 451 lldb::pid_t 452 SBProcess::GetProcessID () 453 { 454 lldb::pid_t ret_val = LLDB_INVALID_PROCESS_ID; 455 if (m_opaque_sp) 456 ret_val = m_opaque_sp->GetID(); 457 458 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 459 if (log) 460 log->Printf ("SBProcess(%p)::GetProcessID () => %d", m_opaque_sp.get(), ret_val); 461 462 return ret_val; 463 } 464 465 ByteOrder 466 SBProcess::GetByteOrder () const 467 { 468 ByteOrder byteOrder = eByteOrderInvalid; 469 if (m_opaque_sp) 470 byteOrder = m_opaque_sp->GetTarget().GetArchitecture().GetByteOrder(); 471 472 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 473 if (log) 474 log->Printf ("SBProcess(%p)::GetByteOrder () => %d", m_opaque_sp.get(), byteOrder); 475 476 return byteOrder; 477 } 478 479 uint32_t 480 SBProcess::GetAddressByteSize () const 481 { 482 uint32_t size = 0; 483 if (m_opaque_sp) 484 size = m_opaque_sp->GetTarget().GetArchitecture().GetAddressByteSize(); 485 486 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 487 if (log) 488 log->Printf ("SBProcess(%p)::GetAddressByteSize () => %d", m_opaque_sp.get(), size); 489 490 return size; 491 } 492 493 SBError 494 SBProcess::Continue () 495 { 496 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 497 if (log) 498 log->Printf ("SBProcess(%p)::Continue ()...", m_opaque_sp.get()); 499 500 SBError sb_error; 501 if (m_opaque_sp) 502 { 503 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 504 505 Error error (m_opaque_sp->Resume()); 506 if (error.Success()) 507 { 508 if (m_opaque_sp->GetTarget().GetDebugger().GetAsyncExecution () == false) 509 { 510 if (log) 511 log->Printf ("SBProcess(%p)::Continue () waiting for process to stop...", m_opaque_sp.get()); 512 m_opaque_sp->WaitForProcessToStop (NULL); 513 } 514 } 515 sb_error.SetError(error); 516 } 517 else 518 sb_error.SetErrorString ("SBProcess is invalid"); 519 520 if (log) 521 { 522 SBStream sstr; 523 sb_error.GetDescription (sstr); 524 log->Printf ("SBProcess(%p)::Continue () => SBError (%p): %s", m_opaque_sp.get(), sb_error.get(), sstr.GetData()); 525 } 526 527 return sb_error; 528 } 529 530 531 SBError 532 SBProcess::Destroy () 533 { 534 SBError sb_error; 535 if (m_opaque_sp) 536 { 537 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 538 sb_error.SetError(m_opaque_sp->Destroy()); 539 } 540 else 541 sb_error.SetErrorString ("SBProcess is invalid"); 542 543 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 544 if (log) 545 { 546 SBStream sstr; 547 sb_error.GetDescription (sstr); 548 log->Printf ("SBProcess(%p)::Destroy () => SBError (%p): %s", 549 m_opaque_sp.get(), 550 sb_error.get(), 551 sstr.GetData()); 552 } 553 554 return sb_error; 555 } 556 557 558 SBError 559 SBProcess::Stop () 560 { 561 SBError sb_error; 562 if (m_opaque_sp) 563 { 564 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 565 sb_error.SetError (m_opaque_sp->Halt()); 566 } 567 else 568 sb_error.SetErrorString ("SBProcess is invalid"); 569 570 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 571 if (log) 572 { 573 SBStream sstr; 574 sb_error.GetDescription (sstr); 575 log->Printf ("SBProcess(%p)::Stop () => SBError (%p): %s", 576 m_opaque_sp.get(), 577 sb_error.get(), 578 sstr.GetData()); 579 } 580 581 return sb_error; 582 } 583 584 SBError 585 SBProcess::Kill () 586 { 587 SBError sb_error; 588 if (m_opaque_sp) 589 { 590 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 591 sb_error.SetError (m_opaque_sp->Destroy()); 592 } 593 else 594 sb_error.SetErrorString ("SBProcess is invalid"); 595 596 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 597 if (log) 598 { 599 SBStream sstr; 600 sb_error.GetDescription (sstr); 601 log->Printf ("SBProcess(%p)::Kill () => SBError (%p): %s", 602 m_opaque_sp.get(), 603 sb_error.get(), 604 sstr.GetData()); 605 } 606 607 return sb_error; 608 } 609 610 SBError 611 SBProcess::Detach () 612 { 613 SBError sb_error; 614 if (m_opaque_sp) 615 { 616 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 617 sb_error.SetError (m_opaque_sp->Detach()); 618 } 619 else 620 sb_error.SetErrorString ("SBProcess is invalid"); 621 622 return sb_error; 623 } 624 625 SBError 626 SBProcess::Signal (int signo) 627 { 628 SBError sb_error; 629 if (m_opaque_sp) 630 { 631 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 632 sb_error.SetError (m_opaque_sp->Signal (signo)); 633 } 634 else 635 sb_error.SetErrorString ("SBProcess is invalid"); 636 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 637 if (log) 638 { 639 SBStream sstr; 640 sb_error.GetDescription (sstr); 641 log->Printf ("SBProcess(%p)::Signal (signo=%i) => SBError (%p): %s", 642 m_opaque_sp.get(), 643 signo, 644 sb_error.get(), 645 sstr.GetData()); 646 } 647 return sb_error; 648 } 649 650 SBThread 651 SBProcess::GetThreadByID (tid_t tid) 652 { 653 SBThread sb_thread; 654 if (m_opaque_sp) 655 { 656 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 657 sb_thread.SetThread (m_opaque_sp->GetThreadList().FindThreadByID ((tid_t) tid)); 658 } 659 660 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 661 if (log) 662 { 663 log->Printf ("SBProcess(%p)::GetThreadByID (tid=0x%4.4x) => SBThread (%p)", 664 m_opaque_sp.get(), 665 tid, 666 sb_thread.get()); 667 } 668 669 return sb_thread; 670 } 671 672 StateType 673 SBProcess::GetStateFromEvent (const SBEvent &event) 674 { 675 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 676 677 StateType ret_val = Process::ProcessEventData::GetStateFromEvent (event.get()); 678 679 if (log) 680 log->Printf ("SBProcess::GetStateFromEvent (event.sp=%p) => %s", event.get(), 681 lldb_private::StateAsCString (ret_val)); 682 683 return ret_val; 684 } 685 686 bool 687 SBProcess::GetRestartedFromEvent (const SBEvent &event) 688 { 689 return Process::ProcessEventData::GetRestartedFromEvent (event.get()); 690 } 691 692 SBProcess 693 SBProcess::GetProcessFromEvent (const SBEvent &event) 694 { 695 SBProcess process(Process::ProcessEventData::GetProcessFromEvent (event.get())); 696 return process; 697 } 698 699 700 SBBroadcaster 701 SBProcess::GetBroadcaster () const 702 { 703 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 704 705 SBBroadcaster broadcaster(m_opaque_sp.get(), false); 706 707 if (log) 708 log->Printf ("SBProcess(%p)::GetBroadcaster () => SBBroadcaster (%p)", m_opaque_sp.get(), 709 broadcaster.get()); 710 711 return broadcaster; 712 } 713 714 lldb_private::Process * 715 SBProcess::operator->() const 716 { 717 return m_opaque_sp.get(); 718 } 719 720 size_t 721 SBProcess::ReadMemory (addr_t addr, void *dst, size_t dst_len, SBError &sb_error) 722 { 723 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 724 725 size_t bytes_read = 0; 726 727 if (log) 728 { 729 log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%llx, dst=%p, dst_len=%zu, SBError (%p))...", 730 m_opaque_sp.get(), 731 addr, 732 dst, 733 (uint32_t) dst_len, 734 sb_error.get()); 735 } 736 737 if (m_opaque_sp) 738 { 739 Error error; 740 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 741 bytes_read = m_opaque_sp->ReadMemory (addr, dst, dst_len, error); 742 sb_error.SetError (error); 743 } 744 else 745 { 746 sb_error.SetErrorString ("SBProcess is invalid"); 747 } 748 749 if (log) 750 { 751 SBStream sstr; 752 sb_error.GetDescription (sstr); 753 log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%llx, dst=%p, dst_len=%zu, SBError (%p): %s) => %d", 754 m_opaque_sp.get(), 755 addr, 756 dst, 757 (uint32_t) dst_len, 758 sb_error.get(), 759 sstr.GetData(), 760 (uint32_t) bytes_read); 761 } 762 763 return bytes_read; 764 } 765 766 size_t 767 SBProcess::WriteMemory (addr_t addr, const void *src, size_t src_len, SBError &sb_error) 768 { 769 size_t bytes_written = 0; 770 771 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); 772 if (log) 773 { 774 log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%llx, src=%p, dst_len=%zu, SBError (%p))...", 775 m_opaque_sp.get(), 776 addr, 777 src, 778 (uint32_t) src_len, 779 sb_error.get()); 780 } 781 782 if (m_opaque_sp) 783 { 784 Error error; 785 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 786 bytes_written = m_opaque_sp->WriteMemory (addr, src, src_len, error); 787 sb_error.SetError (error); 788 } 789 790 if (log) 791 { 792 SBStream sstr; 793 sb_error.GetDescription (sstr); 794 log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%llx, src=%p, dst_len=%zu, SBError (%p): %s) => %d", 795 m_opaque_sp.get(), 796 addr, 797 src, 798 (uint32_t) src_len, 799 sb_error.get(), 800 sstr.GetData(), 801 (uint32_t) bytes_written); 802 } 803 804 return bytes_written; 805 } 806 807 // Mimic shared pointer... 808 lldb_private::Process * 809 SBProcess::get() const 810 { 811 return m_opaque_sp.get(); 812 } 813 814 bool 815 SBProcess::GetDescription (SBStream &description) 816 { 817 if (m_opaque_sp) 818 { 819 char path[PATH_MAX]; 820 GetTarget().GetExecutable().GetPath (path, sizeof(path)); 821 Module *exe_module = m_opaque_sp->GetTarget().GetExecutableModulePointer(); 822 const char *exe_name = NULL; 823 if (exe_module) 824 exe_name = exe_module->GetFileSpec().GetFilename().AsCString(); 825 826 description.Printf ("SBProcess: pid = %llu, state = %s, threads = %d%s%s", 827 m_opaque_sp->GetID(), 828 lldb_private::StateAsCString (GetState()), 829 GetNumThreads(), 830 exe_name ? ", executable = " : "", 831 exe_name ? exe_name : ""); 832 } 833 else 834 description.Printf ("No value"); 835 836 return true; 837 } 838 839 uint32_t 840 SBProcess::LoadImage (lldb::SBFileSpec &sb_image_spec, lldb::SBError &sb_error) 841 { 842 if (m_opaque_sp) 843 { 844 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 845 return m_opaque_sp->LoadImage (*sb_image_spec, sb_error.ref()); 846 } 847 return LLDB_INVALID_IMAGE_TOKEN; 848 } 849 850 lldb::SBError 851 SBProcess::UnloadImage (uint32_t image_token) 852 { 853 lldb::SBError sb_error; 854 if (m_opaque_sp) 855 { 856 Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); 857 sb_error.SetError (m_opaque_sp->UnloadImage (image_token)); 858 } 859 else 860 sb_error.SetErrorString("invalid process"); 861 return sb_error; 862 } 863 864 865