blob: a646e4b30f77addc5f0dd5d0a16ae5cd0b3548ee [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- 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
Eli Friedman7a62c8b2010-06-09 07:44:37 +000010#include "lldb/API/SBProcess.h"
Chris Lattner24943d22010-06-08 16:52:24 +000011
12#include "lldb/lldb-defines.h"
13#include "lldb/lldb-types.h"
14
Jim Ingham84cdc152010-06-15 19:49:27 +000015#include "lldb/Interpreter/Args.h"
Chris Lattner24943d22010-06-08 16:52:24 +000016#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/Thread.h"
23#include "lldb/Target/RegisterContext.h"
24
25// Project includes
26
Eli Friedman7a62c8b2010-06-09 07:44:37 +000027#include "lldb/API/SBBroadcaster.h"
28#include "lldb/API/SBDebugger.h"
29#include "lldb/API/SBCommandReturnObject.h"
30#include "lldb/API/SBEvent.h"
31#include "lldb/API/SBThread.h"
32#include "lldb/API/SBStringList.h"
Chris Lattner24943d22010-06-08 16:52:24 +000033
34using namespace lldb;
35using namespace lldb_private;
36
37
38
39SBProcess::SBProcess () :
40 m_lldb_object_sp()
41{
42}
43
44
45//----------------------------------------------------------------------
46// SBProcess constructor
47//----------------------------------------------------------------------
48
49SBProcess::SBProcess (const SBProcess& rhs) :
50 m_lldb_object_sp (rhs.m_lldb_object_sp)
51{
52}
53
54
55SBProcess::SBProcess (const lldb::ProcessSP &process_sp) :
56 m_lldb_object_sp (process_sp)
57{
58}
59
60//----------------------------------------------------------------------
61// Destructor
62//----------------------------------------------------------------------
63SBProcess::~SBProcess()
64{
65}
66
67void
68SBProcess::SetProcess (const ProcessSP &process_sp)
69{
70 m_lldb_object_sp = process_sp;
71}
72
73void
74SBProcess::Clear ()
75{
76 m_lldb_object_sp.reset();
77}
78
79
80bool
81SBProcess::IsValid() const
82{
83 return m_lldb_object_sp.get() != NULL;
84}
85
86
87uint32_t
88SBProcess::GetNumThreads ()
89{
90 if (m_lldb_object_sp)
91 {
92 const bool can_update = true;
93 return m_lldb_object_sp->GetThreadList().GetSize(can_update);
94 }
95 return 0;
96}
97
98SBThread
99SBProcess::GetCurrentThread () const
100{
101 SBThread sb_thread;
102 if (m_lldb_object_sp)
103 sb_thread.SetThread (m_lldb_object_sp->GetThreadList().GetCurrentThread());
104 return sb_thread;
105}
106
107SBTarget
108SBProcess::GetTarget() const
109{
110 SBTarget sb_target;
111 if (m_lldb_object_sp)
112 sb_target = SBDebugger::FindTargetWithLLDBProcess (m_lldb_object_sp);
113 return sb_target;
114}
115
116
117size_t
118SBProcess::PutSTDIN (const char *src, size_t src_len)
119{
120 if (m_lldb_object_sp != NULL)
121 {
122 Error error;
123 return m_lldb_object_sp->PutSTDIN (src, src_len, error);
124 }
125 else
126 return 0;
127}
128
129size_t
130SBProcess::GetSTDOUT (char *dst, size_t dst_len) const
131{
132 if (m_lldb_object_sp != NULL)
133 {
134 Error error;
135 return m_lldb_object_sp->GetSTDOUT (dst, dst_len, error);
136 }
137 else
138 return 0;
139}
140
141size_t
142SBProcess::GetSTDERR (char *dst, size_t dst_len) const
143{
144 if (m_lldb_object_sp != NULL)
145 {
146 Error error;
147 return m_lldb_object_sp->GetSTDERR (dst, dst_len, error);
148 }
149 else
150 return 0;
151}
152
153void
154SBProcess::ReportCurrentState (const SBEvent &event, FILE *out) const
155{
156 if (out == NULL)
157 return;
158
159 if (m_lldb_object_sp != NULL)
160 {
161 const StateType event_state = SBProcess::GetStateFromEvent (event);
162 char message[1024];
163 int message_len = ::snprintf (message,
164 sizeof (message),
165 "Process %d %s\n",
166 m_lldb_object_sp->GetID(),
167 SBDebugger::StateAsCString (event_state));
168
169 if (message_len > 0)
170 ::fwrite (message, 1, message_len, out);
171 }
172}
173
174void
175SBProcess::AppendCurrentStateReport (const SBEvent &event, SBCommandReturnObject &result)
176{
177 if (m_lldb_object_sp != NULL)
178 {
179 const StateType event_state = SBProcess::GetStateFromEvent (event);
180 char message[1024];
181 ::snprintf (message,
182 sizeof (message),
183 "Process %d %s\n",
184 m_lldb_object_sp->GetID(),
185 SBDebugger::StateAsCString (event_state));
186
187 result.AppendMessage (message);
188 }
189}
190
191bool
192SBProcess::SetCurrentThread (const SBThread &thread)
193{
194 if (m_lldb_object_sp != NULL)
195 return m_lldb_object_sp->GetThreadList().SetCurrentThreadByID (thread.GetThreadID());
196 return false;
197}
198
199bool
200SBProcess::SetCurrentThreadByID (uint32_t tid)
201{
202 if (m_lldb_object_sp != NULL)
203 return m_lldb_object_sp->GetThreadList().SetCurrentThreadByID (tid);
204 return false;
205}
206
207SBThread
208SBProcess::GetThreadAtIndex (size_t index)
209{
210 SBThread thread;
211 if (m_lldb_object_sp)
212 thread.SetThread (m_lldb_object_sp->GetThreadList().GetThreadAtIndex(index));
213 return thread;
214}
215
216StateType
217SBProcess::GetState ()
218{
219 if (m_lldb_object_sp != NULL)
220 return m_lldb_object_sp->GetState();
221 else
222 return eStateInvalid;
223}
224
225
226int
227SBProcess::GetExitStatus ()
228{
229 if (m_lldb_object_sp != NULL)
230 return m_lldb_object_sp->GetExitStatus ();
231 else
232 return 0;
233}
234
235const char *
236SBProcess::GetExitDescription ()
237{
238 if (m_lldb_object_sp != NULL)
239 return m_lldb_object_sp->GetExitDescription ();
240 else
241 return NULL;
242}
243
244lldb::pid_t
245SBProcess::GetProcessID ()
246{
247 if (m_lldb_object_sp)
248 return m_lldb_object_sp->GetID();
249 else
250 return LLDB_INVALID_PROCESS_ID;
251}
252
253uint32_t
254SBProcess::GetAddressByteSize () const
255{
256 if (m_lldb_object_sp)
257 return m_lldb_object_sp->GetAddressByteSize();
258 else
259 return 0;
260}
261
262
263void
264SBProcess::DisplayThreadsInfo (FILE *out, FILE *err, bool only_threads_with_stop_reason)
265{
266 if (m_lldb_object_sp != NULL)
267 {
268 size_t num_thread_infos_dumped = 0;
269 size_t num_threads = GetNumThreads();
270
271 if (out == NULL)
272 out = SBDebugger::GetOutputFileHandle();
273
274 if (err == NULL)
275 err = SBDebugger::GetErrorFileHandle();
276
277 if ((out == NULL) ||(err == NULL))
278 return;
279
280 if (num_threads > 0)
281 {
282 Thread::StopInfo thread_stop_info;
283 SBThread curr_thread (m_lldb_object_sp->GetThreadList().GetCurrentThread());
284 for (int i = 0; i < num_threads; ++i)
285 {
286 SBThread thread (m_lldb_object_sp->GetThreadList().GetThreadAtIndex(i));
287 if (thread.IsValid())
288 {
289 bool is_current_thread = false;
290 StreamFile str (out);
291 if (thread == curr_thread)
292 is_current_thread = true;
293 StopReason thread_stop_reason = eStopReasonNone;
294 if (thread->GetStopInfo (&thread_stop_info))
295 {
296 thread_stop_reason = thread_stop_info.GetStopReason();
297 if (thread_stop_reason == eStopReasonNone)
298 {
299 if (only_threads_with_stop_reason && !is_current_thread)
300 continue;
301 }
302 }
303 ++num_thread_infos_dumped;
304 fprintf (out, " %c thread #%u: tid = 0x%4.4x, pc = 0x%16.16llx",
305 (is_current_thread ? '*' : ' '),
306 thread->GetIndexID(), thread->GetID(), thread->GetRegisterContext()->GetPC());
307
308 StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
309 if (frame_sp)
310 {
311 SymbolContext sc (frame_sp->GetSymbolContext (eSymbolContextEverything));
312 fprintf (out, ", where = ");
313 sc.DumpStopContext (&str, m_lldb_object_sp.get(), frame_sp->GetPC ());
314 }
315
316 if (thread_stop_reason != eStopReasonNone)
317 {
318 fprintf (out, ", stop reason = ");
319 thread_stop_info.Dump (&str);
320 }
321
322 const char *thread_name = thread->GetName();
323 if (thread_name && thread_name[0])
324 fprintf (out, ", thread_name = '%s'", thread_name);
325
326 fprintf (out, "\n");
327
328 SBThread sb_thread (thread);
329 sb_thread.DisplayFramesForCurrentContext (out, err, 0, 1, false, 1);
330 }
331 }
332 }
333 }
334}
335bool
336SBProcess::WaitUntilProcessHasStopped (SBCommandReturnObject &result)
337{
338 bool state_changed = false;
339
340 if (IsValid())
341 {
342 EventSP event_sp;
343 StateType state = m_lldb_object_sp->WaitForStateChangedEvents (NULL, event_sp);
344
345 while (StateIsStoppedState (state))
346 {
347 state = m_lldb_object_sp->WaitForStateChangedEvents (NULL, event_sp);
348 SBEvent event (event_sp);
349 AppendCurrentStateReport (event, result);
350 state_changed = true;
351 }
352 }
353 return state_changed;
354}
355
356SBError
357SBProcess::Continue ()
358{
359 SBError sb_error;
360 if (IsValid())
361 sb_error.SetError(m_lldb_object_sp->Resume());
362 else
363 sb_error.SetErrorString ("SBProcess is invalid");
364
365 return sb_error;
366}
367
368
369SBError
370SBProcess::Destroy ()
371{
372 SBError sb_error;
373 if (m_lldb_object_sp)
374 sb_error.SetError(m_lldb_object_sp->Destroy());
375 else
376 sb_error.SetErrorString ("SBProcess is invalid");
377
378 return sb_error;
379}
380
381
382SBError
383SBProcess::Stop ()
384{
385 SBError sb_error;
386 if (IsValid())
387 sb_error.SetError (m_lldb_object_sp->Halt());
388 else
389 sb_error.SetErrorString ("SBProcess is invalid");
390 return sb_error;
391}
392
393SBError
394SBProcess::Kill ()
395{
396 SBError sb_error;
397 if (m_lldb_object_sp)
398 sb_error.SetError (m_lldb_object_sp->Destroy());
399 else
400 sb_error.SetErrorString ("SBProcess is invalid");
401 return sb_error;
402}
403
404
405SBError
406SBProcess::AttachByName (const char *name, bool wait_for_launch)
407{
408 SBError sb_error;
409 if (m_lldb_object_sp)
410 sb_error.SetError (m_lldb_object_sp->Attach (name, wait_for_launch));
411 else
412 sb_error.SetErrorString ("SBProcess is invalid");
413 return sb_error;
414}
415
416lldb::pid_t
417SBProcess::AttachByPID (lldb::pid_t attach_pid) // DEPRECATED: will be removed in a few builds in favor of SBError AttachByPID(pid_t)
418{
419 Attach (attach_pid);
420 return GetProcessID();
421}
422
423
424SBError
425SBProcess::Attach (lldb::pid_t attach_pid)
426{
427 SBError sb_error;
428 if (m_lldb_object_sp)
429 sb_error.SetError (m_lldb_object_sp->Attach (attach_pid));
430 else
431 sb_error.SetErrorString ("SBProcess is invalid");
432 return sb_error;
433}
434
435SBError
436SBProcess::Detach ()
437{
438 SBError sb_error;
439 if (m_lldb_object_sp)
440 sb_error.SetError (m_lldb_object_sp->Detach());
441 else
442 sb_error.SetErrorString ("SBProcess is invalid");
443
444 return sb_error;
445}
446
447SBError
448SBProcess::Signal (int signal)
449{
450 SBError sb_error;
451 if (m_lldb_object_sp)
452 sb_error.SetError (m_lldb_object_sp->Signal (signal));
453 else
454 sb_error.SetErrorString ("SBProcess is invalid");
455 return sb_error;
456}
457
458void
459SBProcess::ListThreads ()
460{
461 FILE *out = SBDebugger::GetOutputFileHandle();
462 if (out == NULL)
463 return;
464
465 if (m_lldb_object_sp)
466 {
467 size_t num_threads = GetNumThreads ();
468 if (num_threads > 0)
469 {
470 Thread *cur_thread = m_lldb_object_sp->GetThreadList().GetCurrentThread().get();
471 for (int i = 0; i < num_threads; ++i)
472 {
473 Thread *thread = m_lldb_object_sp->GetThreadList().GetThreadAtIndex(i).get();
474 if (thread)
475 {
476 bool is_current_thread = false;
477 if (thread == cur_thread)
478 is_current_thread = true;
479 fprintf (out, " [%u] %c tid = 0x%4.4x, pc = 0x%16.16llx",
480 i,
481 (is_current_thread ? '*' : ' '),
482 thread->GetID(),
483 thread->GetRegisterContext()->GetPC());
484 const char *thread_name = thread->GetName();
485 if (thread_name && thread_name[0])
486 fprintf (out, ", name = %s", thread_name);
487 const char *queue_name = thread->GetQueueName();
488 if (queue_name && queue_name[0])
489 fprintf (out, ", queue = %s", queue_name);
490 fprintf (out, "\n");
491 }
492 }
493 }
494 }
495}
496
497SBThread
498SBProcess::GetThreadByID (tid_t sb_thread_id)
499{
500 SBThread thread;
501 if (m_lldb_object_sp)
502 thread.SetThread (m_lldb_object_sp->GetThreadList().FindThreadByID ((tid_t) sb_thread_id));
503 return thread;
504}
505
506void
507SBProcess::Backtrace (bool all_threads, uint32_t num_frames)
508{
509 if (m_lldb_object_sp)
510 {
511 if (!all_threads)
512 {
513 SBDebugger::UpdateCurrentThread (*this);
514 SBThread cur_thread = GetCurrentThread();
515 if (cur_thread.IsValid())
516 cur_thread.Backtrace (num_frames);
517 }
518 else
519 {
520 int num_threads = GetNumThreads ();
521 for (int i = 0; i < num_threads; ++i)
522 {
523 SBThread sb_thread = GetThreadAtIndex (i);
524 sb_thread.Backtrace (num_frames);
525 }
526 }
527 }
528}
529
530StateType
531SBProcess::GetStateFromEvent (const SBEvent &event)
532{
533 return Process::ProcessEventData::GetStateFromEvent (event.GetLLDBObjectPtr());
534}
535
536
537bool
538SBProcess::GetRestartedFromEvent (const SBEvent &event)
539{
540 return Process::ProcessEventData::GetRestartedFromEvent (event.GetLLDBObjectPtr());
541}
542
543SBProcess
544SBProcess::GetProcessFromEvent (const SBEvent &event)
545{
546 SBProcess process(Process::ProcessEventData::GetProcessFromEvent (event.GetLLDBObjectPtr()));
547 return process;
548}
549
550
551SBBroadcaster
552SBProcess::GetBroadcaster () const
553{
554 SBBroadcaster broadcaster(m_lldb_object_sp.get(), false);
555 return broadcaster;
556}
557
558lldb_private::Process *
559SBProcess::operator->() const
560{
561 return m_lldb_object_sp.get();
562}
563
564size_t
565SBProcess::ReadMemory (addr_t addr, void *dst, size_t dst_len, SBError &sb_error)
566{
567 size_t bytes_read = 0;
568
569 if (IsValid())
570 {
571 Error error;
572 bytes_read = m_lldb_object_sp->ReadMemory (addr, dst, dst_len, error);
573 sb_error.SetError (error);
574 }
575 else
576 {
577 sb_error.SetErrorString ("SBProcess is invalid");
578 }
579
580 return bytes_read;
581}
582
583size_t
584SBProcess::WriteMemory (addr_t addr, const void *src, size_t src_len, SBError &sb_error)
585{
586 size_t bytes_written = 0;
587
588 if (IsValid())
589 {
590 Error error;
591 bytes_written = m_lldb_object_sp->WriteMemory (addr, src, src_len, error);
592 sb_error.SetError (error);
593 }
594
595 return bytes_written;
596}
597
598// Mimic shared pointer...
599lldb_private::Process *
600SBProcess::get() const
601{
602 return m_lldb_object_sp.get();
603}
604