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