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/lldb-python.h"
11 
12 #include "lldb/API/SBProcess.h"
13 
14 // C Includes
15 #include <inttypes.h>
16 
17 #include "lldb/lldb-defines.h"
18 #include "lldb/lldb-types.h"
19 
20 #include "lldb/Interpreter/Args.h"
21 #include "lldb/Core/Debugger.h"
22 #include "lldb/Core/Log.h"
23 #include "lldb/Core/Module.h"
24 #include "lldb/Core/State.h"
25 #include "lldb/Core/Stream.h"
26 #include "lldb/Core/StreamFile.h"
27 #include "lldb/Target/Process.h"
28 #include "lldb/Target/RegisterContext.h"
29 #include "lldb/Target/SystemRuntime.h"
30 #include "lldb/Target/Target.h"
31 #include "lldb/Target/Thread.h"
32 
33 // Project includes
34 
35 #include "lldb/API/SBBroadcaster.h"
36 #include "lldb/API/SBCommandReturnObject.h"
37 #include "lldb/API/SBDebugger.h"
38 #include "lldb/API/SBEvent.h"
39 #include "lldb/API/SBFileSpec.h"
40 #include "lldb/API/SBThread.h"
41 #include "lldb/API/SBThreadCollection.h"
42 #include "lldb/API/SBStream.h"
43 #include "lldb/API/SBStringList.h"
44 #include "lldb/API/SBUnixSignals.h"
45 
46 using namespace lldb;
47 using namespace lldb_private;
48 
49 
50 SBProcess::SBProcess () :
51     m_opaque_wp()
52 {
53 }
54 
55 
56 //----------------------------------------------------------------------
57 // SBProcess constructor
58 //----------------------------------------------------------------------
59 
60 SBProcess::SBProcess (const SBProcess& rhs) :
61     m_opaque_wp (rhs.m_opaque_wp)
62 {
63 }
64 
65 
66 SBProcess::SBProcess (const lldb::ProcessSP &process_sp) :
67     m_opaque_wp (process_sp)
68 {
69 }
70 
71 const SBProcess&
72 SBProcess::operator = (const SBProcess& rhs)
73 {
74     if (this != &rhs)
75         m_opaque_wp = rhs.m_opaque_wp;
76     return *this;
77 }
78 
79 //----------------------------------------------------------------------
80 // Destructor
81 //----------------------------------------------------------------------
82 SBProcess::~SBProcess()
83 {
84 }
85 
86 const char *
87 SBProcess::GetBroadcasterClassName ()
88 {
89     return Process::GetStaticBroadcasterClass().AsCString();
90 }
91 
92 const char *
93 SBProcess::GetPluginName ()
94 {
95     ProcessSP process_sp(GetSP());
96     if (process_sp)
97     {
98         return process_sp->GetPluginName().GetCString();
99     }
100     return "<Unknown>";
101 }
102 
103 const char *
104 SBProcess::GetShortPluginName ()
105 {
106     ProcessSP process_sp(GetSP());
107     if (process_sp)
108     {
109         return process_sp->GetPluginName().GetCString();
110     }
111     return "<Unknown>";
112 }
113 
114 
115 lldb::ProcessSP
116 SBProcess::GetSP() const
117 {
118     return m_opaque_wp.lock();
119 }
120 
121 void
122 SBProcess::SetSP (const ProcessSP &process_sp)
123 {
124     m_opaque_wp = process_sp;
125 }
126 
127 void
128 SBProcess::Clear ()
129 {
130     m_opaque_wp.reset();
131 }
132 
133 
134 bool
135 SBProcess::IsValid() const
136 {
137     ProcessSP process_sp(m_opaque_wp.lock());
138     return ((bool) process_sp && process_sp->IsValid());
139 }
140 
141 bool
142 SBProcess::RemoteLaunch (char const **argv,
143                          char const **envp,
144                          const char *stdin_path,
145                          const char *stdout_path,
146                          const char *stderr_path,
147                          const char *working_directory,
148                          uint32_t launch_flags,
149                          bool stop_at_entry,
150                          lldb::SBError& error)
151 {
152     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
153     if (log)
154         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))...",
155                      static_cast<void*>(m_opaque_wp.lock().get()),
156                      static_cast<void*>(argv), static_cast<void*>(envp),
157                      stdin_path ? stdin_path : "NULL",
158                      stdout_path ? stdout_path : "NULL",
159                      stderr_path ? stderr_path : "NULL",
160                      working_directory ? working_directory : "NULL",
161                      launch_flags, stop_at_entry,
162                      static_cast<void*>(error.get()));
163 
164     ProcessSP process_sp(GetSP());
165     if (process_sp)
166     {
167         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
168         if (process_sp->GetState() == eStateConnected)
169         {
170             if (stop_at_entry)
171                 launch_flags |= eLaunchFlagStopAtEntry;
172             ProcessLaunchInfo launch_info (stdin_path,
173                                            stdout_path,
174                                            stderr_path,
175                                            working_directory,
176                                            launch_flags);
177             Module *exe_module = process_sp->GetTarget().GetExecutableModulePointer();
178             if (exe_module)
179                 launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
180             if (argv)
181                 launch_info.GetArguments().AppendArguments (argv);
182             if (envp)
183                 launch_info.GetEnvironmentEntries ().SetArguments (envp);
184             error.SetError (process_sp->Launch (launch_info));
185         }
186         else
187         {
188             error.SetErrorString ("must be in eStateConnected to call RemoteLaunch");
189         }
190     }
191     else
192     {
193         error.SetErrorString ("unable to attach pid");
194     }
195 
196     if (log) {
197         SBStream sstr;
198         error.GetDescription (sstr);
199         log->Printf ("SBProcess(%p)::RemoteLaunch (...) => SBError (%p): %s",
200                      static_cast<void*>(process_sp.get()),
201                      static_cast<void*>(error.get()), sstr.GetData());
202     }
203 
204     return error.Success();
205 }
206 
207 bool
208 SBProcess::RemoteAttachToProcessWithID (lldb::pid_t pid, lldb::SBError& error)
209 {
210     ProcessSP process_sp(GetSP());
211     if (process_sp)
212     {
213         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
214         if (process_sp->GetState() == eStateConnected)
215         {
216             ProcessAttachInfo attach_info;
217             attach_info.SetProcessID (pid);
218             error.SetError (process_sp->Attach (attach_info));
219         }
220         else
221         {
222             error.SetErrorString ("must be in eStateConnected to call RemoteAttachToProcessWithID");
223         }
224     }
225     else
226     {
227         error.SetErrorString ("unable to attach pid");
228     }
229 
230     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
231     if (log) {
232         SBStream sstr;
233         error.GetDescription (sstr);
234         log->Printf ("SBProcess(%p)::RemoteAttachToProcessWithID (%" PRIu64 ") => SBError (%p): %s",
235                      static_cast<void*>(process_sp.get()), pid,
236                      static_cast<void*>(error.get()), sstr.GetData());
237     }
238 
239     return error.Success();
240 }
241 
242 
243 uint32_t
244 SBProcess::GetNumThreads ()
245 {
246     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
247 
248     uint32_t num_threads = 0;
249     ProcessSP process_sp(GetSP());
250     if (process_sp)
251     {
252         Process::StopLocker stop_locker;
253 
254         const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock());
255         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
256         num_threads = process_sp->GetThreadList().GetSize(can_update);
257     }
258 
259     if (log)
260         log->Printf ("SBProcess(%p)::GetNumThreads () => %d",
261                      static_cast<void*>(process_sp.get()), num_threads);
262 
263     return num_threads;
264 }
265 
266 SBThread
267 SBProcess::GetSelectedThread () const
268 {
269     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
270 
271     SBThread sb_thread;
272     ThreadSP thread_sp;
273     ProcessSP process_sp(GetSP());
274     if (process_sp)
275     {
276         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
277         thread_sp = process_sp->GetThreadList().GetSelectedThread();
278         sb_thread.SetThread (thread_sp);
279     }
280 
281     if (log)
282         log->Printf ("SBProcess(%p)::GetSelectedThread () => SBThread(%p)",
283                      static_cast<void*>(process_sp.get()),
284                      static_cast<void*>(thread_sp.get()));
285 
286     return sb_thread;
287 }
288 
289 SBThread
290 SBProcess::CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context)
291 {
292     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
293 
294     SBThread sb_thread;
295     ThreadSP thread_sp;
296     ProcessSP process_sp(GetSP());
297     if (process_sp)
298     {
299         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
300         thread_sp = process_sp->CreateOSPluginThread(tid, context);
301         sb_thread.SetThread (thread_sp);
302     }
303 
304     if (log)
305         log->Printf ("SBProcess(%p)::CreateOSPluginThread (tid=0x%" PRIx64 ", context=0x%" PRIx64 ") => SBThread(%p)",
306                      static_cast<void*>(process_sp.get()), tid, context,
307                      static_cast<void*>(thread_sp.get()));
308 
309     return sb_thread;
310 }
311 
312 SBTarget
313 SBProcess::GetTarget() const
314 {
315     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
316 
317     SBTarget sb_target;
318     TargetSP target_sp;
319     ProcessSP process_sp(GetSP());
320     if (process_sp)
321     {
322         target_sp = process_sp->GetTarget().shared_from_this();
323         sb_target.SetSP (target_sp);
324     }
325 
326     if (log)
327         log->Printf ("SBProcess(%p)::GetTarget () => SBTarget(%p)",
328                      static_cast<void*>(process_sp.get()),
329                      static_cast<void*>(target_sp.get()));
330 
331     return sb_target;
332 }
333 
334 
335 size_t
336 SBProcess::PutSTDIN (const char *src, size_t src_len)
337 {
338     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
339 
340     size_t ret_val = 0;
341     ProcessSP process_sp(GetSP());
342     if (process_sp)
343     {
344         Error error;
345         ret_val =  process_sp->PutSTDIN (src, src_len, error);
346     }
347 
348     if (log)
349         log->Printf("SBProcess(%p)::PutSTDIN (src=\"%s\", src_len=%" PRIu64 ") => %" PRIu64,
350                      static_cast<void*>(process_sp.get()), src,
351                      static_cast<uint64_t>(src_len),
352                      static_cast<uint64_t>(ret_val));
353 
354     return ret_val;
355 }
356 
357 size_t
358 SBProcess::GetSTDOUT (char *dst, size_t dst_len) const
359 {
360     size_t bytes_read = 0;
361     ProcessSP process_sp(GetSP());
362     if (process_sp)
363     {
364         Error error;
365         bytes_read = process_sp->GetSTDOUT (dst, dst_len, error);
366     }
367 
368     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
369     if (log)
370         log->Printf ("SBProcess(%p)::GetSTDOUT (dst=\"%.*s\", dst_len=%" PRIu64 ") => %" PRIu64,
371                      static_cast<void*>(process_sp.get()),
372                      static_cast<int>(bytes_read), dst,
373                      static_cast<uint64_t>(dst_len),
374                      static_cast<uint64_t>(bytes_read));
375 
376     return bytes_read;
377 }
378 
379 size_t
380 SBProcess::GetSTDERR (char *dst, size_t dst_len) const
381 {
382     size_t bytes_read = 0;
383     ProcessSP process_sp(GetSP());
384     if (process_sp)
385     {
386         Error error;
387         bytes_read = process_sp->GetSTDERR (dst, dst_len, error);
388     }
389 
390     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
391     if (log)
392         log->Printf ("SBProcess(%p)::GetSTDERR (dst=\"%.*s\", dst_len=%" PRIu64 ") => %" PRIu64,
393                      static_cast<void*>(process_sp.get()),
394                      static_cast<int>(bytes_read), dst,
395                      static_cast<uint64_t>(dst_len),
396                      static_cast<uint64_t>(bytes_read));
397 
398     return bytes_read;
399 }
400 
401 size_t
402 SBProcess::GetAsyncProfileData(char *dst, size_t dst_len) const
403 {
404     size_t bytes_read = 0;
405     ProcessSP process_sp(GetSP());
406     if (process_sp)
407     {
408         Error error;
409         bytes_read = process_sp->GetAsyncProfileData (dst, dst_len, error);
410     }
411 
412     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
413     if (log)
414         log->Printf ("SBProcess(%p)::GetProfileData (dst=\"%.*s\", dst_len=%" PRIu64 ") => %" PRIu64,
415                      static_cast<void*>(process_sp.get()),
416                      static_cast<int>(bytes_read), dst,
417                      static_cast<uint64_t>(dst_len),
418                      static_cast<uint64_t>(bytes_read));
419 
420     return bytes_read;
421 }
422 
423 void
424 SBProcess::ReportEventState (const SBEvent &event, FILE *out) const
425 {
426     if (out == NULL)
427         return;
428 
429     ProcessSP process_sp(GetSP());
430     if (process_sp)
431     {
432         const StateType event_state = SBProcess::GetStateFromEvent (event);
433         char message[1024];
434         int message_len = ::snprintf (message,
435                                       sizeof (message),
436                                       "Process %" PRIu64 " %s\n",
437                                       process_sp->GetID(),
438                                       SBDebugger::StateAsCString (event_state));
439 
440         if (message_len > 0)
441             ::fwrite (message, 1, message_len, out);
442     }
443 }
444 
445 void
446 SBProcess::AppendEventStateReport (const SBEvent &event, SBCommandReturnObject &result)
447 {
448     ProcessSP process_sp(GetSP());
449     if (process_sp)
450     {
451         const StateType event_state = SBProcess::GetStateFromEvent (event);
452         char message[1024];
453         ::snprintf (message,
454                     sizeof (message),
455                     "Process %" PRIu64 " %s\n",
456                     process_sp->GetID(),
457                     SBDebugger::StateAsCString (event_state));
458 
459         result.AppendMessage (message);
460     }
461 }
462 
463 bool
464 SBProcess::SetSelectedThread (const SBThread &thread)
465 {
466     ProcessSP process_sp(GetSP());
467     if (process_sp)
468     {
469         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
470         return process_sp->GetThreadList().SetSelectedThreadByID (thread.GetThreadID());
471     }
472     return false;
473 }
474 
475 bool
476 SBProcess::SetSelectedThreadByID (lldb::tid_t tid)
477 {
478     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
479 
480     bool ret_val = false;
481     ProcessSP process_sp(GetSP());
482     if (process_sp)
483     {
484         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
485         ret_val = process_sp->GetThreadList().SetSelectedThreadByID (tid);
486     }
487 
488     if (log)
489         log->Printf ("SBProcess(%p)::SetSelectedThreadByID (tid=0x%4.4" PRIx64 ") => %s",
490                      static_cast<void*>(process_sp.get()), tid,
491                      (ret_val ? "true" : "false"));
492 
493     return ret_val;
494 }
495 
496 bool
497 SBProcess::SetSelectedThreadByIndexID (uint32_t index_id)
498 {
499     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
500 
501     bool ret_val = false;
502     ProcessSP process_sp(GetSP());
503     if (process_sp)
504     {
505         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
506         ret_val = process_sp->GetThreadList().SetSelectedThreadByIndexID (index_id);
507     }
508 
509     if (log)
510         log->Printf ("SBProcess(%p)::SetSelectedThreadByID (tid=0x%x) => %s",
511                      static_cast<void*>(process_sp.get()), index_id,
512                      (ret_val ? "true" : "false"));
513 
514     return ret_val;
515 }
516 
517 SBThread
518 SBProcess::GetThreadAtIndex (size_t index)
519 {
520     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
521 
522     SBThread sb_thread;
523     ThreadSP thread_sp;
524     ProcessSP process_sp(GetSP());
525     if (process_sp)
526     {
527         Process::StopLocker stop_locker;
528         const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock());
529         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
530         thread_sp = process_sp->GetThreadList().GetThreadAtIndex(index, can_update);
531         sb_thread.SetThread (thread_sp);
532     }
533 
534     if (log)
535         log->Printf ("SBProcess(%p)::GetThreadAtIndex (index=%d) => SBThread(%p)",
536                      static_cast<void*>(process_sp.get()),
537                      static_cast<uint32_t>(index),
538                      static_cast<void*>(thread_sp.get()));
539 
540     return sb_thread;
541 }
542 
543 uint32_t
544 SBProcess::GetNumQueues ()
545 {
546     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
547 
548     uint32_t num_queues = 0;
549     ProcessSP process_sp(GetSP());
550     if (process_sp)
551     {
552         Process::StopLocker stop_locker;
553 
554         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
555         num_queues = process_sp->GetQueueList().GetSize();
556     }
557 
558     if (log)
559         log->Printf ("SBProcess(%p)::GetNumQueues () => %d",
560                      static_cast<void*>(process_sp.get()), num_queues);
561 
562     return num_queues;
563 }
564 
565 SBQueue
566 SBProcess::GetQueueAtIndex (size_t index)
567 {
568     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
569 
570     SBQueue sb_queue;
571     QueueSP queue_sp;
572     ProcessSP process_sp(GetSP());
573     if (process_sp)
574     {
575         Process::StopLocker stop_locker;
576         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
577         queue_sp = process_sp->GetQueueList().GetQueueAtIndex(index);
578         sb_queue.SetQueue (queue_sp);
579     }
580 
581     if (log)
582         log->Printf ("SBProcess(%p)::GetQueueAtIndex (index=%d) => SBQueue(%p)",
583                      static_cast<void*>(process_sp.get()),
584                      static_cast<uint32_t>(index),
585                      static_cast<void*>(queue_sp.get()));
586 
587     return sb_queue;
588 }
589 
590 
591 uint32_t
592 SBProcess::GetStopID(bool include_expression_stops)
593 {
594     ProcessSP process_sp(GetSP());
595     if (process_sp)
596     {
597         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
598         if (include_expression_stops)
599             return process_sp->GetStopID();
600         else
601             return process_sp->GetLastNaturalStopID();
602     }
603     return 0;
604 }
605 
606 StateType
607 SBProcess::GetState ()
608 {
609 
610     StateType ret_val = eStateInvalid;
611     ProcessSP process_sp(GetSP());
612     if (process_sp)
613     {
614         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
615         ret_val = process_sp->GetState();
616     }
617 
618     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
619     if (log)
620         log->Printf ("SBProcess(%p)::GetState () => %s",
621                      static_cast<void*>(process_sp.get()),
622                      lldb_private::StateAsCString (ret_val));
623 
624     return ret_val;
625 }
626 
627 
628 int
629 SBProcess::GetExitStatus ()
630 {
631     int exit_status = 0;
632     ProcessSP process_sp(GetSP());
633     if (process_sp)
634     {
635         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
636         exit_status = process_sp->GetExitStatus ();
637     }
638     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
639     if (log)
640         log->Printf ("SBProcess(%p)::GetExitStatus () => %i (0x%8.8x)",
641                      static_cast<void*>(process_sp.get()), exit_status,
642                      exit_status);
643 
644     return exit_status;
645 }
646 
647 const char *
648 SBProcess::GetExitDescription ()
649 {
650     const char *exit_desc = NULL;
651     ProcessSP process_sp(GetSP());
652     if (process_sp)
653     {
654         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
655         exit_desc = process_sp->GetExitDescription ();
656     }
657     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
658     if (log)
659         log->Printf ("SBProcess(%p)::GetExitDescription () => %s",
660                      static_cast<void*>(process_sp.get()), exit_desc);
661     return exit_desc;
662 }
663 
664 lldb::pid_t
665 SBProcess::GetProcessID ()
666 {
667     lldb::pid_t ret_val = LLDB_INVALID_PROCESS_ID;
668     ProcessSP process_sp(GetSP());
669     if (process_sp)
670         ret_val = process_sp->GetID();
671 
672     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
673     if (log)
674         log->Printf ("SBProcess(%p)::GetProcessID () => %" PRIu64,
675                      static_cast<void*>(process_sp.get()), ret_val);
676 
677     return ret_val;
678 }
679 
680 uint32_t
681 SBProcess::GetUniqueID()
682 {
683     uint32_t ret_val = 0;
684     ProcessSP process_sp(GetSP());
685     if (process_sp)
686         ret_val = process_sp->GetUniqueID();
687     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
688     if (log)
689         log->Printf ("SBProcess(%p)::GetUniqueID () => %" PRIu32,
690                      static_cast<void*>(process_sp.get()), ret_val);
691     return ret_val;
692 }
693 
694 ByteOrder
695 SBProcess::GetByteOrder () const
696 {
697     ByteOrder byteOrder = eByteOrderInvalid;
698     ProcessSP process_sp(GetSP());
699     if (process_sp)
700         byteOrder = process_sp->GetTarget().GetArchitecture().GetByteOrder();
701 
702     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
703     if (log)
704         log->Printf ("SBProcess(%p)::GetByteOrder () => %d",
705                      static_cast<void*>(process_sp.get()), byteOrder);
706 
707     return byteOrder;
708 }
709 
710 uint32_t
711 SBProcess::GetAddressByteSize () const
712 {
713     uint32_t size = 0;
714     ProcessSP process_sp(GetSP());
715     if (process_sp)
716         size =  process_sp->GetTarget().GetArchitecture().GetAddressByteSize();
717 
718     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
719     if (log)
720         log->Printf ("SBProcess(%p)::GetAddressByteSize () => %d",
721                      static_cast<void*>(process_sp.get()), size);
722 
723     return size;
724 }
725 
726 SBError
727 SBProcess::Continue ()
728 {
729     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
730 
731     SBError sb_error;
732     ProcessSP process_sp(GetSP());
733 
734     if (log)
735         log->Printf ("SBProcess(%p)::Continue ()...",
736                      static_cast<void*>(process_sp.get()));
737 
738     if (process_sp)
739     {
740         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
741 
742         if (process_sp->GetTarget().GetDebugger().GetAsyncExecution ())
743             sb_error.ref() = process_sp->Resume ();
744         else
745             sb_error.ref() = process_sp->ResumeSynchronous (NULL);
746     }
747     else
748         sb_error.SetErrorString ("SBProcess is invalid");
749 
750     if (log)
751     {
752         SBStream sstr;
753         sb_error.GetDescription (sstr);
754         log->Printf ("SBProcess(%p)::Continue () => SBError (%p): %s",
755                      static_cast<void*>(process_sp.get()),
756                      static_cast<void*>(sb_error.get()), sstr.GetData());
757     }
758 
759     return sb_error;
760 }
761 
762 
763 SBError
764 SBProcess::Destroy ()
765 {
766     SBError sb_error;
767     ProcessSP process_sp(GetSP());
768     if (process_sp)
769     {
770         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
771         sb_error.SetError(process_sp->Destroy(false));
772     }
773     else
774         sb_error.SetErrorString ("SBProcess is invalid");
775 
776     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
777     if (log)
778     {
779         SBStream sstr;
780         sb_error.GetDescription (sstr);
781         log->Printf ("SBProcess(%p)::Destroy () => SBError (%p): %s",
782                      static_cast<void*>(process_sp.get()),
783                      static_cast<void*>(sb_error.get()), sstr.GetData());
784     }
785 
786     return sb_error;
787 }
788 
789 
790 SBError
791 SBProcess::Stop ()
792 {
793     SBError sb_error;
794     ProcessSP process_sp(GetSP());
795     if (process_sp)
796     {
797         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
798         sb_error.SetError (process_sp->Halt());
799     }
800     else
801         sb_error.SetErrorString ("SBProcess is invalid");
802 
803     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
804     if (log)
805     {
806         SBStream sstr;
807         sb_error.GetDescription (sstr);
808         log->Printf ("SBProcess(%p)::Stop () => SBError (%p): %s",
809                      static_cast<void*>(process_sp.get()),
810                      static_cast<void*>(sb_error.get()), sstr.GetData());
811     }
812 
813     return sb_error;
814 }
815 
816 SBError
817 SBProcess::Kill ()
818 {
819     SBError sb_error;
820     ProcessSP process_sp(GetSP());
821     if (process_sp)
822     {
823         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
824         sb_error.SetError (process_sp->Destroy(true));
825     }
826     else
827         sb_error.SetErrorString ("SBProcess is invalid");
828 
829     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
830     if (log)
831     {
832         SBStream sstr;
833         sb_error.GetDescription (sstr);
834         log->Printf ("SBProcess(%p)::Kill () => SBError (%p): %s",
835                      static_cast<void*>(process_sp.get()),
836                      static_cast<void*>(sb_error.get()), sstr.GetData());
837     }
838 
839     return sb_error;
840 }
841 
842 SBError
843 SBProcess::Detach ()
844 {
845     // FIXME: This should come from a process default.
846     bool keep_stopped = false;
847     return Detach (keep_stopped);
848 }
849 
850 SBError
851 SBProcess::Detach (bool keep_stopped)
852 {
853     SBError sb_error;
854     ProcessSP process_sp(GetSP());
855     if (process_sp)
856     {
857         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
858         sb_error.SetError (process_sp->Detach(keep_stopped));
859     }
860     else
861         sb_error.SetErrorString ("SBProcess is invalid");
862 
863     return sb_error;
864 }
865 
866 SBError
867 SBProcess::Signal (int signo)
868 {
869     SBError sb_error;
870     ProcessSP process_sp(GetSP());
871     if (process_sp)
872     {
873         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
874         sb_error.SetError (process_sp->Signal (signo));
875     }
876     else
877         sb_error.SetErrorString ("SBProcess is invalid");
878     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
879     if (log)
880     {
881         SBStream sstr;
882         sb_error.GetDescription (sstr);
883         log->Printf ("SBProcess(%p)::Signal (signo=%i) => SBError (%p): %s",
884                      static_cast<void*>(process_sp.get()), signo,
885                      static_cast<void*>(sb_error.get()), sstr.GetData());
886     }
887     return sb_error;
888 }
889 
890 SBUnixSignals
891 SBProcess::GetUnixSignals()
892 {
893     SBUnixSignals sb_unix_signals;
894     ProcessSP process_sp(GetSP());
895     if (process_sp)
896     {
897         sb_unix_signals.SetSP(process_sp);
898     }
899 
900     return sb_unix_signals;
901 }
902 
903 void
904 SBProcess::SendAsyncInterrupt ()
905 {
906     ProcessSP process_sp(GetSP());
907     if (process_sp)
908     {
909         process_sp->SendAsyncInterrupt ();
910     }
911 }
912 
913 SBThread
914 SBProcess::GetThreadByID (tid_t tid)
915 {
916     SBThread sb_thread;
917     ThreadSP thread_sp;
918     ProcessSP process_sp(GetSP());
919     if (process_sp)
920     {
921         Process::StopLocker stop_locker;
922         const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock());
923         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
924         thread_sp = process_sp->GetThreadList().FindThreadByID (tid, can_update);
925         sb_thread.SetThread (thread_sp);
926     }
927 
928     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
929     if (log)
930         log->Printf ("SBProcess(%p)::GetThreadByID (tid=0x%4.4" PRIx64 ") => SBThread (%p)",
931                      static_cast<void*>(process_sp.get()), tid,
932                      static_cast<void*>(thread_sp.get()));
933 
934     return sb_thread;
935 }
936 
937 SBThread
938 SBProcess::GetThreadByIndexID (uint32_t index_id)
939 {
940     SBThread sb_thread;
941     ThreadSP thread_sp;
942     ProcessSP process_sp(GetSP());
943     if (process_sp)
944     {
945         Process::StopLocker stop_locker;
946         const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock());
947         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
948         thread_sp = process_sp->GetThreadList().FindThreadByIndexID (index_id, can_update);
949         sb_thread.SetThread (thread_sp);
950     }
951 
952     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
953     if (log)
954         log->Printf ("SBProcess(%p)::GetThreadByID (tid=0x%x) => SBThread (%p)",
955                      static_cast<void*>(process_sp.get()), index_id,
956                      static_cast<void*>(thread_sp.get()));
957 
958     return sb_thread;
959 }
960 
961 StateType
962 SBProcess::GetStateFromEvent (const SBEvent &event)
963 {
964     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
965 
966     StateType ret_val = Process::ProcessEventData::GetStateFromEvent (event.get());
967 
968     if (log)
969         log->Printf ("SBProcess::GetStateFromEvent (event.sp=%p) => %s",
970                      static_cast<void*>(event.get()),
971                      lldb_private::StateAsCString (ret_val));
972 
973     return ret_val;
974 }
975 
976 bool
977 SBProcess::GetRestartedFromEvent (const SBEvent &event)
978 {
979     return Process::ProcessEventData::GetRestartedFromEvent (event.get());
980 }
981 
982 size_t
983 SBProcess::GetNumRestartedReasonsFromEvent (const lldb::SBEvent &event)
984 {
985     return Process::ProcessEventData::GetNumRestartedReasons(event.get());
986 }
987 
988 const char *
989 SBProcess::GetRestartedReasonAtIndexFromEvent (const lldb::SBEvent &event, size_t idx)
990 {
991     return Process::ProcessEventData::GetRestartedReasonAtIndex(event.get(), idx);
992 }
993 
994 SBProcess
995 SBProcess::GetProcessFromEvent (const SBEvent &event)
996 {
997     SBProcess process(Process::ProcessEventData::GetProcessFromEvent (event.get()));
998     return process;
999 }
1000 
1001 bool
1002 SBProcess::GetInterruptedFromEvent (const SBEvent &event)
1003 {
1004     return Process::ProcessEventData::GetInterruptedFromEvent(event.get());
1005 }
1006 
1007 bool
1008 SBProcess::EventIsProcessEvent (const SBEvent &event)
1009 {
1010     return event.GetBroadcasterClass() == SBProcess::GetBroadcasterClass();
1011 }
1012 
1013 SBBroadcaster
1014 SBProcess::GetBroadcaster () const
1015 {
1016     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1017 
1018     ProcessSP process_sp(GetSP());
1019 
1020     SBBroadcaster broadcaster(process_sp.get(), false);
1021 
1022     if (log)
1023         log->Printf ("SBProcess(%p)::GetBroadcaster () => SBBroadcaster (%p)",
1024                      static_cast<void*>(process_sp.get()),
1025                      static_cast<void*>(broadcaster.get()));
1026 
1027     return broadcaster;
1028 }
1029 
1030 const char *
1031 SBProcess::GetBroadcasterClass ()
1032 {
1033     return Process::GetStaticBroadcasterClass().AsCString();
1034 }
1035 
1036 size_t
1037 SBProcess::ReadMemory (addr_t addr, void *dst, size_t dst_len, SBError &sb_error)
1038 {
1039     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1040 
1041     size_t bytes_read = 0;
1042 
1043     ProcessSP process_sp(GetSP());
1044 
1045     if (log)
1046         log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%" PRIx64 ", dst=%p, dst_len=%" PRIu64 ", SBError (%p))...",
1047                      static_cast<void*>(process_sp.get()), addr,
1048                      static_cast<void*>(dst), static_cast<uint64_t>(dst_len),
1049                      static_cast<void*>(sb_error.get()));
1050 
1051     if (process_sp)
1052     {
1053         Process::StopLocker stop_locker;
1054         if (stop_locker.TryLock(&process_sp->GetRunLock()))
1055         {
1056             Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
1057             bytes_read = process_sp->ReadMemory (addr, dst, dst_len, sb_error.ref());
1058         }
1059         else
1060         {
1061             if (log)
1062                 log->Printf ("SBProcess(%p)::ReadMemory() => error: process is running",
1063                              static_cast<void*>(process_sp.get()));
1064             sb_error.SetErrorString("process is running");
1065         }
1066     }
1067     else
1068     {
1069         sb_error.SetErrorString ("SBProcess is invalid");
1070     }
1071 
1072     if (log)
1073     {
1074         SBStream sstr;
1075         sb_error.GetDescription (sstr);
1076         log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%" PRIx64 ", dst=%p, dst_len=%" PRIu64 ", SBError (%p): %s) => %" PRIu64,
1077                      static_cast<void*>(process_sp.get()), addr,
1078                      static_cast<void*>(dst), static_cast<uint64_t>(dst_len),
1079                      static_cast<void*>(sb_error.get()), sstr.GetData(),
1080                      static_cast<uint64_t>(bytes_read));
1081     }
1082 
1083     return bytes_read;
1084 }
1085 
1086 size_t
1087 SBProcess::ReadCStringFromMemory (addr_t addr, void *buf, size_t size, lldb::SBError &sb_error)
1088 {
1089     size_t bytes_read = 0;
1090     ProcessSP process_sp(GetSP());
1091     if (process_sp)
1092     {
1093         Process::StopLocker stop_locker;
1094         if (stop_locker.TryLock(&process_sp->GetRunLock()))
1095         {
1096             Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
1097             bytes_read = process_sp->ReadCStringFromMemory (addr, (char *)buf, size, sb_error.ref());
1098         }
1099         else
1100         {
1101             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1102             if (log)
1103                 log->Printf ("SBProcess(%p)::ReadCStringFromMemory() => error: process is running",
1104                              static_cast<void*>(process_sp.get()));
1105             sb_error.SetErrorString("process is running");
1106         }
1107     }
1108     else
1109     {
1110         sb_error.SetErrorString ("SBProcess is invalid");
1111     }
1112     return bytes_read;
1113 }
1114 
1115 uint64_t
1116 SBProcess::ReadUnsignedFromMemory (addr_t addr, uint32_t byte_size, lldb::SBError &sb_error)
1117 {
1118     uint64_t value = 0;
1119     ProcessSP process_sp(GetSP());
1120     if (process_sp)
1121     {
1122         Process::StopLocker stop_locker;
1123         if (stop_locker.TryLock(&process_sp->GetRunLock()))
1124         {
1125             Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
1126             value = process_sp->ReadUnsignedIntegerFromMemory (addr, byte_size, 0, sb_error.ref());
1127         }
1128         else
1129         {
1130             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1131             if (log)
1132                 log->Printf ("SBProcess(%p)::ReadUnsignedFromMemory() => error: process is running",
1133                              static_cast<void*>(process_sp.get()));
1134             sb_error.SetErrorString("process is running");
1135         }
1136     }
1137     else
1138     {
1139         sb_error.SetErrorString ("SBProcess is invalid");
1140     }
1141     return value;
1142 }
1143 
1144 lldb::addr_t
1145 SBProcess::ReadPointerFromMemory (addr_t addr, lldb::SBError &sb_error)
1146 {
1147     lldb::addr_t ptr = LLDB_INVALID_ADDRESS;
1148     ProcessSP process_sp(GetSP());
1149     if (process_sp)
1150     {
1151         Process::StopLocker stop_locker;
1152         if (stop_locker.TryLock(&process_sp->GetRunLock()))
1153         {
1154             Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
1155             ptr = process_sp->ReadPointerFromMemory (addr, sb_error.ref());
1156         }
1157         else
1158         {
1159             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1160             if (log)
1161                 log->Printf ("SBProcess(%p)::ReadPointerFromMemory() => error: process is running",
1162                              static_cast<void*>(process_sp.get()));
1163             sb_error.SetErrorString("process is running");
1164         }
1165     }
1166     else
1167     {
1168         sb_error.SetErrorString ("SBProcess is invalid");
1169     }
1170     return ptr;
1171 }
1172 
1173 size_t
1174 SBProcess::WriteMemory (addr_t addr, const void *src, size_t src_len, SBError &sb_error)
1175 {
1176     size_t bytes_written = 0;
1177 
1178     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1179 
1180     ProcessSP process_sp(GetSP());
1181 
1182     if (log)
1183         log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%" PRIx64 ", src=%p, src_len=%" PRIu64 ", SBError (%p))...",
1184                      static_cast<void*>(process_sp.get()), addr,
1185                      static_cast<const void*>(src),
1186                      static_cast<uint64_t>(src_len),
1187                      static_cast<void*>(sb_error.get()));
1188 
1189     if (process_sp)
1190     {
1191         Process::StopLocker stop_locker;
1192         if (stop_locker.TryLock(&process_sp->GetRunLock()))
1193         {
1194             Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
1195             bytes_written = process_sp->WriteMemory (addr, src, src_len, sb_error.ref());
1196         }
1197         else
1198         {
1199             if (log)
1200                 log->Printf ("SBProcess(%p)::WriteMemory() => error: process is running",
1201                              static_cast<void*>(process_sp.get()));
1202             sb_error.SetErrorString("process is running");
1203         }
1204     }
1205 
1206     if (log)
1207     {
1208         SBStream sstr;
1209         sb_error.GetDescription (sstr);
1210         log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%" PRIx64 ", src=%p, src_len=%" PRIu64 ", SBError (%p): %s) => %" PRIu64,
1211                      static_cast<void*>(process_sp.get()), addr,
1212                      static_cast<const void*>(src),
1213                      static_cast<uint64_t>(src_len),
1214                      static_cast<void*>(sb_error.get()), sstr.GetData(),
1215                      static_cast<uint64_t>(bytes_written));
1216     }
1217 
1218     return bytes_written;
1219 }
1220 
1221 bool
1222 SBProcess::GetDescription (SBStream &description)
1223 {
1224     Stream &strm = description.ref();
1225 
1226     ProcessSP process_sp(GetSP());
1227     if (process_sp)
1228     {
1229         char path[PATH_MAX];
1230         GetTarget().GetExecutable().GetPath (path, sizeof(path));
1231         Module *exe_module = process_sp->GetTarget().GetExecutableModulePointer();
1232         const char *exe_name = NULL;
1233         if (exe_module)
1234             exe_name = exe_module->GetFileSpec().GetFilename().AsCString();
1235 
1236         strm.Printf ("SBProcess: pid = %" PRIu64 ", state = %s, threads = %d%s%s",
1237                      process_sp->GetID(),
1238                      lldb_private::StateAsCString (GetState()),
1239                      GetNumThreads(),
1240                      exe_name ? ", executable = " : "",
1241                      exe_name ? exe_name : "");
1242     }
1243     else
1244         strm.PutCString ("No value");
1245 
1246     return true;
1247 }
1248 
1249 uint32_t
1250 SBProcess::GetNumSupportedHardwareWatchpoints (lldb::SBError &sb_error) const
1251 {
1252     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1253 
1254     uint32_t num = 0;
1255     ProcessSP process_sp(GetSP());
1256     if (process_sp)
1257     {
1258         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
1259         sb_error.SetError(process_sp->GetWatchpointSupportInfo (num));
1260         if (log)
1261             log->Printf ("SBProcess(%p)::GetNumSupportedHardwareWatchpoints () => %u",
1262                          static_cast<void*>(process_sp.get()), num);
1263     }
1264     else
1265     {
1266         sb_error.SetErrorString ("SBProcess is invalid");
1267     }
1268     return num;
1269 }
1270 
1271 uint32_t
1272 SBProcess::LoadImage (lldb::SBFileSpec &sb_image_spec, lldb::SBError &sb_error)
1273 {
1274     ProcessSP process_sp(GetSP());
1275     if (process_sp)
1276     {
1277         Process::StopLocker stop_locker;
1278         if (stop_locker.TryLock(&process_sp->GetRunLock()))
1279         {
1280             Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
1281             return process_sp->LoadImage (*sb_image_spec, sb_error.ref());
1282         }
1283         else
1284         {
1285             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1286             if (log)
1287                 log->Printf ("SBProcess(%p)::LoadImage() => error: process is running",
1288                              static_cast<void*>(process_sp.get()));
1289             sb_error.SetErrorString("process is running");
1290         }
1291     }
1292     return LLDB_INVALID_IMAGE_TOKEN;
1293 }
1294 
1295 lldb::SBError
1296 SBProcess::UnloadImage (uint32_t image_token)
1297 {
1298     lldb::SBError sb_error;
1299     ProcessSP process_sp(GetSP());
1300     if (process_sp)
1301     {
1302         Process::StopLocker stop_locker;
1303         if (stop_locker.TryLock(&process_sp->GetRunLock()))
1304         {
1305             Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
1306             sb_error.SetError (process_sp->UnloadImage (image_token));
1307         }
1308         else
1309         {
1310             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1311             if (log)
1312                 log->Printf ("SBProcess(%p)::UnloadImage() => error: process is running",
1313                              static_cast<void*>(process_sp.get()));
1314             sb_error.SetErrorString("process is running");
1315         }
1316     }
1317     else
1318         sb_error.SetErrorString("invalid process");
1319     return sb_error;
1320 }
1321 
1322 lldb::SBError
1323 SBProcess::SendEventData (const char *event_data)
1324 {
1325     lldb::SBError sb_error;
1326     ProcessSP process_sp(GetSP());
1327     if (process_sp)
1328     {
1329         Process::StopLocker stop_locker;
1330         if (stop_locker.TryLock(&process_sp->GetRunLock()))
1331         {
1332             Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
1333             sb_error.SetError (process_sp->SendEventData (event_data));
1334         }
1335         else
1336         {
1337             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1338             if (log)
1339                 log->Printf ("SBProcess(%p)::SendEventData() => error: process is running",
1340                              static_cast<void*>(process_sp.get()));
1341             sb_error.SetErrorString("process is running");
1342         }
1343     }
1344     else
1345         sb_error.SetErrorString("invalid process");
1346     return sb_error;
1347 }
1348 
1349 uint32_t
1350 SBProcess::GetNumExtendedBacktraceTypes ()
1351 {
1352     ProcessSP process_sp(GetSP());
1353     if (process_sp && process_sp->GetSystemRuntime())
1354     {
1355         SystemRuntime *runtime = process_sp->GetSystemRuntime();
1356         return runtime->GetExtendedBacktraceTypes().size();
1357     }
1358     return 0;
1359 }
1360 
1361 const char *
1362 SBProcess::GetExtendedBacktraceTypeAtIndex (uint32_t idx)
1363 {
1364     ProcessSP process_sp(GetSP());
1365     if (process_sp && process_sp->GetSystemRuntime())
1366     {
1367         SystemRuntime *runtime = process_sp->GetSystemRuntime();
1368         const std::vector<ConstString> &names = runtime->GetExtendedBacktraceTypes();
1369         if (idx < names.size())
1370         {
1371             return names[idx].AsCString();
1372         }
1373         else
1374         {
1375             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1376             if (log)
1377                 log->Printf("SBProcess(%p)::GetExtendedBacktraceTypeAtIndex() => error: requested extended backtrace name out of bounds",
1378                             static_cast<void*>(process_sp.get()));
1379         }
1380     }
1381     return NULL;
1382 }
1383 
1384 SBThreadCollection
1385 SBProcess::GetHistoryThreads (addr_t addr)
1386 {
1387     ProcessSP process_sp(GetSP());
1388     SBThreadCollection threads;
1389     if (process_sp)
1390     {
1391         threads = SBThreadCollection(process_sp->GetHistoryThreads(addr));
1392     }
1393     return threads;
1394 }
1395 
1396 bool
1397 SBProcess::IsInstrumentationRuntimePresent(InstrumentationRuntimeType type)
1398 {
1399     ProcessSP process_sp(GetSP());
1400     if (! process_sp)
1401         return false;
1402 
1403     InstrumentationRuntimeSP runtime_sp = process_sp->GetInstrumentationRuntime(type);
1404 
1405     if (! runtime_sp.get())
1406         return false;
1407 
1408     return runtime_sp->IsActive();
1409 }
1410