SBProcess.cpp revision c833295baeec641086f536e78050388af36784f8
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
35using namespace lldb;
36using namespace lldb_private;
37
38
39
40SBProcess::SBProcess () :
41    m_opaque_sp()
42{
43}
44
45
46//----------------------------------------------------------------------
47// SBProcess constructor
48//----------------------------------------------------------------------
49
50SBProcess::SBProcess (const SBProcess& rhs) :
51    m_opaque_sp (rhs.m_opaque_sp)
52{
53}
54
55
56SBProcess::SBProcess (const lldb::ProcessSP &process_sp) :
57    m_opaque_sp (process_sp)
58{
59}
60
61//----------------------------------------------------------------------
62// Destructor
63//----------------------------------------------------------------------
64SBProcess::~SBProcess()
65{
66}
67
68void
69SBProcess::SetProcess (const ProcessSP &process_sp)
70{
71    m_opaque_sp = process_sp;
72}
73
74void
75SBProcess::Clear ()
76{
77    m_opaque_sp.reset();
78}
79
80
81bool
82SBProcess::IsValid() const
83{
84    return m_opaque_sp.get() != NULL;
85}
86
87
88uint32_t
89SBProcess::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
99SBThread
100SBProcess::GetSelectedThread () const
101{
102    SBThread sb_thread;
103    if (m_opaque_sp)
104        sb_thread.SetThread (m_opaque_sp->GetThreadList().GetSelectedThread());
105    return sb_thread;
106}
107
108SBTarget
109SBProcess::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
118size_t
119SBProcess::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
130size_t
131SBProcess::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
142size_t
143SBProcess::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
154void
155SBProcess::ReportEventState (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
175void
176SBProcess::AppendEventStateReport (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
192bool
193SBProcess::SetSelectedThread (const SBThread &thread)
194{
195    if (m_opaque_sp != NULL)
196        return m_opaque_sp->GetThreadList().SetSelectedThreadByID (thread.GetThreadID());
197    return false;
198}
199
200bool
201SBProcess::SetSelectedThreadByID (uint32_t tid)
202{
203    if (m_opaque_sp != NULL)
204        return m_opaque_sp->GetThreadList().SetSelectedThreadByID (tid);
205    return false;
206}
207
208SBThread
209SBProcess::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
217StateType
218SBProcess::GetState ()
219{
220    if (m_opaque_sp != NULL)
221        return m_opaque_sp->GetState();
222    else
223        return eStateInvalid;
224}
225
226
227int
228SBProcess::GetExitStatus ()
229{
230    if (m_opaque_sp != NULL)
231        return m_opaque_sp->GetExitStatus ();
232    else
233        return 0;
234}
235
236const char *
237SBProcess::GetExitDescription ()
238{
239    if (m_opaque_sp != NULL)
240        return m_opaque_sp->GetExitDescription ();
241    else
242        return NULL;
243}
244
245lldb::pid_t
246SBProcess::GetProcessID ()
247{
248    if (m_opaque_sp)
249        return m_opaque_sp->GetID();
250    else
251        return LLDB_INVALID_PROCESS_ID;
252}
253
254uint32_t
255SBProcess::GetAddressByteSize () const
256{
257    if (m_opaque_sp)
258        return m_opaque_sp->GetAddressByteSize();
259    else
260        return 0;
261}
262
263bool
264SBProcess::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            AppendEventStateReport (event, result);
278            state_changed = true;
279        }
280    }
281    return state_changed;
282}
283
284SBError
285SBProcess::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
297SBError
298SBProcess::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
310SBError
311SBProcess::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
321SBError
322SBProcess::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
333SBError
334SBProcess::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
344lldb::pid_t
345SBProcess::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
352SBError
353SBProcess::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
363SBError
364SBProcess::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
375SBError
376SBProcess::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
386SBThread
387SBProcess::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
395StateType
396SBProcess::GetStateFromEvent (const SBEvent &event)
397{
398    return Process::ProcessEventData::GetStateFromEvent (event.get());
399}
400
401bool
402SBProcess::GetRestartedFromEvent (const SBEvent &event)
403{
404    return Process::ProcessEventData::GetRestartedFromEvent (event.get());
405}
406
407SBProcess
408SBProcess::GetProcessFromEvent (const SBEvent &event)
409{
410    SBProcess process(Process::ProcessEventData::GetProcessFromEvent (event.get()));
411    return process;
412}
413
414
415SBBroadcaster
416SBProcess::GetBroadcaster () const
417{
418    SBBroadcaster broadcaster(m_opaque_sp.get(), false);
419    return broadcaster;
420}
421
422lldb_private::Process *
423SBProcess::operator->() const
424{
425    return m_opaque_sp.get();
426}
427
428size_t
429SBProcess::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
447size_t
448SBProcess::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...
463lldb_private::Process *
464SBProcess::get() const
465{
466    return m_opaque_sp.get();
467}
468
469