1 //===-- SBProcess.cpp -------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/API/SBProcess.h"
11 
12 #include "lldb/lldb-defines.h"
13 #include "lldb/lldb-types.h"
14 
15 #include "lldb/Interpreter/Args.h"
16 #include "lldb/Core/DataBufferHeap.h"
17 #include "lldb/Core/DataExtractor.h"
18 #include "lldb/Core/State.h"
19 #include "lldb/Core/Stream.h"
20 #include "lldb/Core/StreamFile.h"
21 #include "lldb/Target/Process.h"
22 #include "lldb/Target/RegisterContext.h"
23 #include "lldb/Target/Target.h"
24 #include "lldb/Target/Thread.h"
25 
26 // Project includes
27 
28 #include "lldb/API/SBBroadcaster.h"
29 #include "lldb/API/SBDebugger.h"
30 #include "lldb/API/SBCommandReturnObject.h"
31 #include "lldb/API/SBEvent.h"
32 #include "lldb/API/SBThread.h"
33 #include "lldb/API/SBStringList.h"
34 
35 using namespace lldb;
36 using namespace lldb_private;
37 
38 
39 
40 SBProcess::SBProcess () :
41     m_opaque_sp()
42 {
43 }
44 
45 
46 //----------------------------------------------------------------------
47 // SBProcess constructor
48 //----------------------------------------------------------------------
49 
50 SBProcess::SBProcess (const SBProcess& rhs) :
51     m_opaque_sp (rhs.m_opaque_sp)
52 {
53 }
54 
55 
56 SBProcess::SBProcess (const lldb::ProcessSP &process_sp) :
57     m_opaque_sp (process_sp)
58 {
59 }
60 
61 //----------------------------------------------------------------------
62 // Destructor
63 //----------------------------------------------------------------------
64 SBProcess::~SBProcess()
65 {
66 }
67 
68 void
69 SBProcess::SetProcess (const ProcessSP &process_sp)
70 {
71     m_opaque_sp = process_sp;
72 }
73 
74 void
75 SBProcess::Clear ()
76 {
77     m_opaque_sp.reset();
78 }
79 
80 
81 bool
82 SBProcess::IsValid() const
83 {
84     return m_opaque_sp.get() != NULL;
85 }
86 
87 
88 uint32_t
89 SBProcess::GetNumThreads ()
90 {
91     if (m_opaque_sp)
92     {
93         const bool can_update = true;
94         return m_opaque_sp->GetThreadList().GetSize(can_update);
95     }
96     return 0;
97 }
98 
99 SBThread
100 SBProcess::GetCurrentThread () const
101 {
102     SBThread sb_thread;
103     if (m_opaque_sp)
104         sb_thread.SetThread (m_opaque_sp->GetThreadList().GetCurrentThread());
105     return sb_thread;
106 }
107 
108 SBTarget
109 SBProcess::GetTarget() const
110 {
111     SBTarget sb_target;
112     if (m_opaque_sp)
113         sb_target = m_opaque_sp->GetTarget().GetSP();
114     return sb_target;
115 }
116 
117 
118 size_t
119 SBProcess::PutSTDIN (const char *src, size_t src_len)
120 {
121     if (m_opaque_sp != NULL)
122     {
123         Error error;
124         return m_opaque_sp->PutSTDIN (src, src_len, error);
125     }
126     else
127         return 0;
128 }
129 
130 size_t
131 SBProcess::GetSTDOUT (char *dst, size_t dst_len) const
132 {
133     if (m_opaque_sp != NULL)
134     {
135         Error error;
136         return m_opaque_sp->GetSTDOUT (dst, dst_len, error);
137     }
138     else
139         return 0;
140 }
141 
142 size_t
143 SBProcess::GetSTDERR (char *dst, size_t dst_len) const
144 {
145     if (m_opaque_sp != NULL)
146     {
147         Error error;
148         return m_opaque_sp->GetSTDERR (dst, dst_len, error);
149     }
150     else
151         return 0;
152 }
153 
154 void
155 SBProcess::ReportCurrentState (const SBEvent &event, FILE *out) const
156 {
157     if (out == NULL)
158         return;
159 
160     if (m_opaque_sp != NULL)
161     {
162         const StateType event_state = SBProcess::GetStateFromEvent (event);
163         char message[1024];
164         int message_len = ::snprintf (message,
165                                       sizeof (message),
166                                       "Process %d %s\n",
167                                       m_opaque_sp->GetID(),
168                                       SBDebugger::StateAsCString (event_state));
169 
170         if (message_len > 0)
171             ::fwrite (message, 1, message_len, out);
172     }
173 }
174 
175 void
176 SBProcess::AppendCurrentStateReport (const SBEvent &event, SBCommandReturnObject &result)
177 {
178     if (m_opaque_sp != NULL)
179     {
180         const StateType event_state = SBProcess::GetStateFromEvent (event);
181         char message[1024];
182         ::snprintf (message,
183                     sizeof (message),
184                     "Process %d %s\n",
185                     m_opaque_sp->GetID(),
186                     SBDebugger::StateAsCString (event_state));
187 
188         result.AppendMessage (message);
189     }
190 }
191 
192 bool
193 SBProcess::SetCurrentThread (const SBThread &thread)
194 {
195     if (m_opaque_sp != NULL)
196         return m_opaque_sp->GetThreadList().SetCurrentThreadByID (thread.GetThreadID());
197     return false;
198 }
199 
200 bool
201 SBProcess::SetCurrentThreadByID (uint32_t tid)
202 {
203     if (m_opaque_sp != NULL)
204         return m_opaque_sp->GetThreadList().SetCurrentThreadByID (tid);
205     return false;
206 }
207 
208 SBThread
209 SBProcess::GetThreadAtIndex (size_t index)
210 {
211     SBThread thread;
212     if (m_opaque_sp)
213         thread.SetThread (m_opaque_sp->GetThreadList().GetThreadAtIndex(index));
214     return thread;
215 }
216 
217 StateType
218 SBProcess::GetState ()
219 {
220     if (m_opaque_sp != NULL)
221         return m_opaque_sp->GetState();
222     else
223         return eStateInvalid;
224 }
225 
226 
227 int
228 SBProcess::GetExitStatus ()
229 {
230     if (m_opaque_sp != NULL)
231         return m_opaque_sp->GetExitStatus ();
232     else
233         return 0;
234 }
235 
236 const char *
237 SBProcess::GetExitDescription ()
238 {
239     if (m_opaque_sp != NULL)
240         return m_opaque_sp->GetExitDescription ();
241     else
242         return NULL;
243 }
244 
245 lldb::pid_t
246 SBProcess::GetProcessID ()
247 {
248     if (m_opaque_sp)
249         return m_opaque_sp->GetID();
250     else
251         return LLDB_INVALID_PROCESS_ID;
252 }
253 
254 uint32_t
255 SBProcess::GetAddressByteSize () const
256 {
257     if (m_opaque_sp)
258         return m_opaque_sp->GetAddressByteSize();
259     else
260         return 0;
261 }
262 
263 bool
264 SBProcess::WaitUntilProcessHasStopped (SBCommandReturnObject &result)
265 {
266     bool state_changed = false;
267 
268     if (IsValid())
269     {
270         EventSP event_sp;
271         StateType state = m_opaque_sp->WaitForStateChangedEvents (NULL, event_sp);
272 
273         while (StateIsStoppedState (state))
274         {
275             state = m_opaque_sp->WaitForStateChangedEvents (NULL, event_sp);
276             SBEvent event (event_sp);
277             AppendCurrentStateReport (event, result);
278             state_changed = true;
279         }
280     }
281     return state_changed;
282 }
283 
284 SBError
285 SBProcess::Continue ()
286 {
287     SBError sb_error;
288     if (IsValid())
289         sb_error.SetError(m_opaque_sp->Resume());
290     else
291         sb_error.SetErrorString ("SBProcess is invalid");
292 
293     return sb_error;
294 }
295 
296 
297 SBError
298 SBProcess::Destroy ()
299 {
300     SBError sb_error;
301     if (m_opaque_sp)
302         sb_error.SetError(m_opaque_sp->Destroy());
303     else
304         sb_error.SetErrorString ("SBProcess is invalid");
305 
306     return sb_error;
307 }
308 
309 
310 SBError
311 SBProcess::Stop ()
312 {
313     SBError sb_error;
314     if (IsValid())
315         sb_error.SetError (m_opaque_sp->Halt());
316     else
317         sb_error.SetErrorString ("SBProcess is invalid");
318     return sb_error;
319 }
320 
321 SBError
322 SBProcess::Kill ()
323 {
324     SBError sb_error;
325     if (m_opaque_sp)
326         sb_error.SetError (m_opaque_sp->Destroy());
327     else
328         sb_error.SetErrorString ("SBProcess is invalid");
329     return sb_error;
330 }
331 
332 
333 SBError
334 SBProcess::AttachByName (const char *name, bool wait_for_launch)
335 {
336     SBError sb_error;
337     if (m_opaque_sp)
338         sb_error.SetError (m_opaque_sp->Attach (name, wait_for_launch));
339     else
340         sb_error.SetErrorString ("SBProcess is invalid");
341     return sb_error;
342 }
343 
344 lldb::pid_t
345 SBProcess::AttachByPID (lldb::pid_t attach_pid)  // DEPRECATED: will be removed in a few builds in favor of SBError AttachByPID(pid_t)
346 {
347     Attach (attach_pid);
348     return GetProcessID();
349 }
350 
351 
352 SBError
353 SBProcess::Attach (lldb::pid_t attach_pid)
354 {
355     SBError sb_error;
356     if (m_opaque_sp)
357         sb_error.SetError  (m_opaque_sp->Attach (attach_pid));
358     else
359         sb_error.SetErrorString ("SBProcess is invalid");
360     return sb_error;
361 }
362 
363 SBError
364 SBProcess::Detach ()
365 {
366     SBError sb_error;
367     if (m_opaque_sp)
368         sb_error.SetError (m_opaque_sp->Detach());
369     else
370         sb_error.SetErrorString ("SBProcess is invalid");
371 
372     return sb_error;
373 }
374 
375 SBError
376 SBProcess::Signal (int signal)
377 {
378     SBError sb_error;
379     if (m_opaque_sp)
380         sb_error.SetError (m_opaque_sp->Signal (signal));
381     else
382         sb_error.SetErrorString ("SBProcess is invalid");
383     return sb_error;
384 }
385 
386 SBThread
387 SBProcess::GetThreadByID (tid_t sb_thread_id)
388 {
389     SBThread thread;
390     if (m_opaque_sp)
391         thread.SetThread (m_opaque_sp->GetThreadList().FindThreadByID ((tid_t) sb_thread_id));
392     return thread;
393 }
394 
395 StateType
396 SBProcess::GetStateFromEvent (const SBEvent &event)
397 {
398     return Process::ProcessEventData::GetStateFromEvent (event.get());
399 }
400 
401 bool
402 SBProcess::GetRestartedFromEvent (const SBEvent &event)
403 {
404     return Process::ProcessEventData::GetRestartedFromEvent (event.get());
405 }
406 
407 SBProcess
408 SBProcess::GetProcessFromEvent (const SBEvent &event)
409 {
410     SBProcess process(Process::ProcessEventData::GetProcessFromEvent (event.get()));
411     return process;
412 }
413 
414 
415 SBBroadcaster
416 SBProcess::GetBroadcaster () const
417 {
418     SBBroadcaster broadcaster(m_opaque_sp.get(), false);
419     return broadcaster;
420 }
421 
422 lldb_private::Process *
423 SBProcess::operator->() const
424 {
425     return m_opaque_sp.get();
426 }
427 
428 size_t
429 SBProcess::ReadMemory (addr_t addr, void *dst, size_t dst_len, SBError &sb_error)
430 {
431     size_t bytes_read = 0;
432 
433     if (IsValid())
434     {
435         Error error;
436         bytes_read = m_opaque_sp->ReadMemory (addr, dst, dst_len, error);
437         sb_error.SetError (error);
438     }
439     else
440     {
441         sb_error.SetErrorString ("SBProcess is invalid");
442     }
443 
444     return bytes_read;
445 }
446 
447 size_t
448 SBProcess::WriteMemory (addr_t addr, const void *src, size_t src_len, SBError &sb_error)
449 {
450     size_t bytes_written = 0;
451 
452     if (IsValid())
453     {
454         Error error;
455         bytes_written = m_opaque_sp->WriteMemory (addr, src, src_len, error);
456         sb_error.SetError (error);
457     }
458 
459     return bytes_written;
460 }
461 
462 // Mimic shared pointer...
463 lldb_private::Process *
464 SBProcess::get() const
465 {
466     return m_opaque_sp.get();
467 }
468 
469