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());
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());
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::EventIsProcessEvent (const SBEvent &event)
1003 {
1004     return event.GetBroadcasterClass() == SBProcess::GetBroadcasterClass();
1005 }
1006 
1007 SBBroadcaster
1008 SBProcess::GetBroadcaster () const
1009 {
1010     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1011 
1012     ProcessSP process_sp(GetSP());
1013 
1014     SBBroadcaster broadcaster(process_sp.get(), false);
1015 
1016     if (log)
1017         log->Printf ("SBProcess(%p)::GetBroadcaster () => SBBroadcaster (%p)",
1018                      static_cast<void*>(process_sp.get()),
1019                      static_cast<void*>(broadcaster.get()));
1020 
1021     return broadcaster;
1022 }
1023 
1024 const char *
1025 SBProcess::GetBroadcasterClass ()
1026 {
1027     return Process::GetStaticBroadcasterClass().AsCString();
1028 }
1029 
1030 size_t
1031 SBProcess::ReadMemory (addr_t addr, void *dst, size_t dst_len, SBError &sb_error)
1032 {
1033     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1034 
1035     size_t bytes_read = 0;
1036 
1037     ProcessSP process_sp(GetSP());
1038 
1039     if (log)
1040         log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%" PRIx64 ", dst=%p, dst_len=%" PRIu64 ", SBError (%p))...",
1041                      static_cast<void*>(process_sp.get()), addr,
1042                      static_cast<void*>(dst), static_cast<uint64_t>(dst_len),
1043                      static_cast<void*>(sb_error.get()));
1044 
1045     if (process_sp)
1046     {
1047         Process::StopLocker stop_locker;
1048         if (stop_locker.TryLock(&process_sp->GetRunLock()))
1049         {
1050             Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
1051             bytes_read = process_sp->ReadMemory (addr, dst, dst_len, sb_error.ref());
1052         }
1053         else
1054         {
1055             if (log)
1056                 log->Printf ("SBProcess(%p)::ReadMemory() => error: process is running",
1057                              static_cast<void*>(process_sp.get()));
1058             sb_error.SetErrorString("process is running");
1059         }
1060     }
1061     else
1062     {
1063         sb_error.SetErrorString ("SBProcess is invalid");
1064     }
1065 
1066     if (log)
1067     {
1068         SBStream sstr;
1069         sb_error.GetDescription (sstr);
1070         log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%" PRIx64 ", dst=%p, dst_len=%" PRIu64 ", SBError (%p): %s) => %" PRIu64,
1071                      static_cast<void*>(process_sp.get()), addr,
1072                      static_cast<void*>(dst), static_cast<uint64_t>(dst_len),
1073                      static_cast<void*>(sb_error.get()), sstr.GetData(),
1074                      static_cast<uint64_t>(bytes_read));
1075     }
1076 
1077     return bytes_read;
1078 }
1079 
1080 size_t
1081 SBProcess::ReadCStringFromMemory (addr_t addr, void *buf, size_t size, lldb::SBError &sb_error)
1082 {
1083     size_t bytes_read = 0;
1084     ProcessSP process_sp(GetSP());
1085     if (process_sp)
1086     {
1087         Process::StopLocker stop_locker;
1088         if (stop_locker.TryLock(&process_sp->GetRunLock()))
1089         {
1090             Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
1091             bytes_read = process_sp->ReadCStringFromMemory (addr, (char *)buf, size, sb_error.ref());
1092         }
1093         else
1094         {
1095             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1096             if (log)
1097                 log->Printf ("SBProcess(%p)::ReadCStringFromMemory() => error: process is running",
1098                              static_cast<void*>(process_sp.get()));
1099             sb_error.SetErrorString("process is running");
1100         }
1101     }
1102     else
1103     {
1104         sb_error.SetErrorString ("SBProcess is invalid");
1105     }
1106     return bytes_read;
1107 }
1108 
1109 uint64_t
1110 SBProcess::ReadUnsignedFromMemory (addr_t addr, uint32_t byte_size, lldb::SBError &sb_error)
1111 {
1112     uint64_t value = 0;
1113     ProcessSP process_sp(GetSP());
1114     if (process_sp)
1115     {
1116         Process::StopLocker stop_locker;
1117         if (stop_locker.TryLock(&process_sp->GetRunLock()))
1118         {
1119             Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
1120             value = process_sp->ReadUnsignedIntegerFromMemory (addr, byte_size, 0, sb_error.ref());
1121         }
1122         else
1123         {
1124             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1125             if (log)
1126                 log->Printf ("SBProcess(%p)::ReadUnsignedFromMemory() => error: process is running",
1127                              static_cast<void*>(process_sp.get()));
1128             sb_error.SetErrorString("process is running");
1129         }
1130     }
1131     else
1132     {
1133         sb_error.SetErrorString ("SBProcess is invalid");
1134     }
1135     return value;
1136 }
1137 
1138 lldb::addr_t
1139 SBProcess::ReadPointerFromMemory (addr_t addr, lldb::SBError &sb_error)
1140 {
1141     lldb::addr_t ptr = LLDB_INVALID_ADDRESS;
1142     ProcessSP process_sp(GetSP());
1143     if (process_sp)
1144     {
1145         Process::StopLocker stop_locker;
1146         if (stop_locker.TryLock(&process_sp->GetRunLock()))
1147         {
1148             Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
1149             ptr = process_sp->ReadPointerFromMemory (addr, sb_error.ref());
1150         }
1151         else
1152         {
1153             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1154             if (log)
1155                 log->Printf ("SBProcess(%p)::ReadPointerFromMemory() => error: process is running",
1156                              static_cast<void*>(process_sp.get()));
1157             sb_error.SetErrorString("process is running");
1158         }
1159     }
1160     else
1161     {
1162         sb_error.SetErrorString ("SBProcess is invalid");
1163     }
1164     return ptr;
1165 }
1166 
1167 size_t
1168 SBProcess::WriteMemory (addr_t addr, const void *src, size_t src_len, SBError &sb_error)
1169 {
1170     size_t bytes_written = 0;
1171 
1172     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1173 
1174     ProcessSP process_sp(GetSP());
1175 
1176     if (log)
1177         log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%" PRIx64 ", src=%p, src_len=%" PRIu64 ", SBError (%p))...",
1178                      static_cast<void*>(process_sp.get()), addr,
1179                      static_cast<const void*>(src),
1180                      static_cast<uint64_t>(src_len),
1181                      static_cast<void*>(sb_error.get()));
1182 
1183     if (process_sp)
1184     {
1185         Process::StopLocker stop_locker;
1186         if (stop_locker.TryLock(&process_sp->GetRunLock()))
1187         {
1188             Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
1189             bytes_written = process_sp->WriteMemory (addr, src, src_len, sb_error.ref());
1190         }
1191         else
1192         {
1193             if (log)
1194                 log->Printf ("SBProcess(%p)::WriteMemory() => error: process is running",
1195                              static_cast<void*>(process_sp.get()));
1196             sb_error.SetErrorString("process is running");
1197         }
1198     }
1199 
1200     if (log)
1201     {
1202         SBStream sstr;
1203         sb_error.GetDescription (sstr);
1204         log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%" PRIx64 ", src=%p, src_len=%" PRIu64 ", SBError (%p): %s) => %" PRIu64,
1205                      static_cast<void*>(process_sp.get()), addr,
1206                      static_cast<const void*>(src),
1207                      static_cast<uint64_t>(src_len),
1208                      static_cast<void*>(sb_error.get()), sstr.GetData(),
1209                      static_cast<uint64_t>(bytes_written));
1210     }
1211 
1212     return bytes_written;
1213 }
1214 
1215 bool
1216 SBProcess::GetDescription (SBStream &description)
1217 {
1218     Stream &strm = description.ref();
1219 
1220     ProcessSP process_sp(GetSP());
1221     if (process_sp)
1222     {
1223         char path[PATH_MAX];
1224         GetTarget().GetExecutable().GetPath (path, sizeof(path));
1225         Module *exe_module = process_sp->GetTarget().GetExecutableModulePointer();
1226         const char *exe_name = NULL;
1227         if (exe_module)
1228             exe_name = exe_module->GetFileSpec().GetFilename().AsCString();
1229 
1230         strm.Printf ("SBProcess: pid = %" PRIu64 ", state = %s, threads = %d%s%s",
1231                      process_sp->GetID(),
1232                      lldb_private::StateAsCString (GetState()),
1233                      GetNumThreads(),
1234                      exe_name ? ", executable = " : "",
1235                      exe_name ? exe_name : "");
1236     }
1237     else
1238         strm.PutCString ("No value");
1239 
1240     return true;
1241 }
1242 
1243 uint32_t
1244 SBProcess::GetNumSupportedHardwareWatchpoints (lldb::SBError &sb_error) const
1245 {
1246     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1247 
1248     uint32_t num = 0;
1249     ProcessSP process_sp(GetSP());
1250     if (process_sp)
1251     {
1252         Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
1253         sb_error.SetError(process_sp->GetWatchpointSupportInfo (num));
1254         if (log)
1255             log->Printf ("SBProcess(%p)::GetNumSupportedHardwareWatchpoints () => %u",
1256                          static_cast<void*>(process_sp.get()), num);
1257     }
1258     else
1259     {
1260         sb_error.SetErrorString ("SBProcess is invalid");
1261     }
1262     return num;
1263 }
1264 
1265 uint32_t
1266 SBProcess::LoadImage (lldb::SBFileSpec &sb_image_spec, lldb::SBError &sb_error)
1267 {
1268     ProcessSP process_sp(GetSP());
1269     if (process_sp)
1270     {
1271         Process::StopLocker stop_locker;
1272         if (stop_locker.TryLock(&process_sp->GetRunLock()))
1273         {
1274             Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
1275             return process_sp->LoadImage (*sb_image_spec, sb_error.ref());
1276         }
1277         else
1278         {
1279             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1280             if (log)
1281                 log->Printf ("SBProcess(%p)::LoadImage() => error: process is running",
1282                              static_cast<void*>(process_sp.get()));
1283             sb_error.SetErrorString("process is running");
1284         }
1285     }
1286     return LLDB_INVALID_IMAGE_TOKEN;
1287 }
1288 
1289 lldb::SBError
1290 SBProcess::UnloadImage (uint32_t image_token)
1291 {
1292     lldb::SBError sb_error;
1293     ProcessSP process_sp(GetSP());
1294     if (process_sp)
1295     {
1296         Process::StopLocker stop_locker;
1297         if (stop_locker.TryLock(&process_sp->GetRunLock()))
1298         {
1299             Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
1300             sb_error.SetError (process_sp->UnloadImage (image_token));
1301         }
1302         else
1303         {
1304             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1305             if (log)
1306                 log->Printf ("SBProcess(%p)::UnloadImage() => error: process is running",
1307                              static_cast<void*>(process_sp.get()));
1308             sb_error.SetErrorString("process is running");
1309         }
1310     }
1311     else
1312         sb_error.SetErrorString("invalid process");
1313     return sb_error;
1314 }
1315 
1316 lldb::SBError
1317 SBProcess::SendEventData (const char *event_data)
1318 {
1319     lldb::SBError sb_error;
1320     ProcessSP process_sp(GetSP());
1321     if (process_sp)
1322     {
1323         Process::StopLocker stop_locker;
1324         if (stop_locker.TryLock(&process_sp->GetRunLock()))
1325         {
1326             Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
1327             sb_error.SetError (process_sp->SendEventData (event_data));
1328         }
1329         else
1330         {
1331             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1332             if (log)
1333                 log->Printf ("SBProcess(%p)::SendEventData() => error: process is running",
1334                              static_cast<void*>(process_sp.get()));
1335             sb_error.SetErrorString("process is running");
1336         }
1337     }
1338     else
1339         sb_error.SetErrorString("invalid process");
1340     return sb_error;
1341 }
1342 
1343 uint32_t
1344 SBProcess::GetNumExtendedBacktraceTypes ()
1345 {
1346     ProcessSP process_sp(GetSP());
1347     if (process_sp && process_sp->GetSystemRuntime())
1348     {
1349         SystemRuntime *runtime = process_sp->GetSystemRuntime();
1350         return runtime->GetExtendedBacktraceTypes().size();
1351     }
1352     return 0;
1353 }
1354 
1355 const char *
1356 SBProcess::GetExtendedBacktraceTypeAtIndex (uint32_t idx)
1357 {
1358     ProcessSP process_sp(GetSP());
1359     if (process_sp && process_sp->GetSystemRuntime())
1360     {
1361         SystemRuntime *runtime = process_sp->GetSystemRuntime();
1362         const std::vector<ConstString> &names = runtime->GetExtendedBacktraceTypes();
1363         if (idx < names.size())
1364         {
1365             return names[idx].AsCString();
1366         }
1367         else
1368         {
1369             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1370             if (log)
1371                 log->Printf("SBProcess(%p)::GetExtendedBacktraceTypeAtIndex() => error: requested extended backtrace name out of bounds",
1372                             static_cast<void*>(process_sp.get()));
1373         }
1374     }
1375     return NULL;
1376 }
1377 
1378 SBThreadCollection
1379 SBProcess::GetHistoryThreads (addr_t addr)
1380 {
1381     ProcessSP process_sp(GetSP());
1382     SBThreadCollection threads;
1383     if (process_sp)
1384     {
1385         threads = SBThreadCollection(process_sp->GetHistoryThreads(addr));
1386     }
1387     return threads;
1388 }
1389 
1390 bool
1391 SBProcess::IsInstrumentationRuntimePresent(InstrumentationRuntimeType type)
1392 {
1393     ProcessSP process_sp(GetSP());
1394     if (! process_sp)
1395         return false;
1396 
1397     InstrumentationRuntimeSP runtime_sp = process_sp->GetInstrumentationRuntime(type);
1398 
1399     if (! runtime_sp.get())
1400         return false;
1401 
1402     return runtime_sp->IsActive();
1403 }
1404