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