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