1 //===-- SBThread.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/SBThread.h"
13
14 #include "lldb/API/SBSymbolContext.h"
15 #include "lldb/API/SBFileSpec.h"
16 #include "lldb/API/SBStream.h"
17 #include "lldb/Breakpoint/BreakpointLocation.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/Interpreter/CommandInterpreter.h"
23 #include "lldb/Target/Thread.h"
24 #include "lldb/Target/Process.h"
25 #include "lldb/Symbol/SymbolContext.h"
26 #include "lldb/Symbol/CompileUnit.h"
27 #include "lldb/Target/StopInfo.h"
28 #include "lldb/Target/Target.h"
29 #include "lldb/Target/ThreadPlan.h"
30 #include "lldb/Target/ThreadPlanStepInstruction.h"
31 #include "lldb/Target/ThreadPlanStepOut.h"
32 #include "lldb/Target/ThreadPlanStepRange.h"
33 #include "lldb/Target/ThreadPlanStepInRange.h"
34
35
36 #include "lldb/API/SBAddress.h"
37 #include "lldb/API/SBDebugger.h"
38 #include "lldb/API/SBEvent.h"
39 #include "lldb/API/SBFrame.h"
40 #include "lldb/API/SBProcess.h"
41 #include "lldb/API/SBValue.h"
42
43 using namespace lldb;
44 using namespace lldb_private;
45
46 const char *
GetBroadcasterClassName()47 SBThread::GetBroadcasterClassName ()
48 {
49 return Thread::GetStaticBroadcasterClass().AsCString();
50 }
51
52 //----------------------------------------------------------------------
53 // Constructors
54 //----------------------------------------------------------------------
SBThread()55 SBThread::SBThread () :
56 m_opaque_sp (new ExecutionContextRef())
57 {
58 }
59
SBThread(const ThreadSP & lldb_object_sp)60 SBThread::SBThread (const ThreadSP& lldb_object_sp) :
61 m_opaque_sp (new ExecutionContextRef(lldb_object_sp))
62 {
63 }
64
SBThread(const SBThread & rhs)65 SBThread::SBThread (const SBThread &rhs) :
66 m_opaque_sp (new ExecutionContextRef(*rhs.m_opaque_sp))
67 {
68
69 }
70
71 //----------------------------------------------------------------------
72 // Assignment operator
73 //----------------------------------------------------------------------
74
75 const lldb::SBThread &
operator =(const SBThread & rhs)76 SBThread::operator = (const SBThread &rhs)
77 {
78 if (this != &rhs)
79 *m_opaque_sp = *rhs.m_opaque_sp;
80 return *this;
81 }
82
83 //----------------------------------------------------------------------
84 // Destructor
85 //----------------------------------------------------------------------
~SBThread()86 SBThread::~SBThread()
87 {
88 }
89
90 bool
IsValid() const91 SBThread::IsValid() const
92 {
93 return m_opaque_sp->GetThreadSP().get() != NULL;
94 }
95
96 void
Clear()97 SBThread::Clear ()
98 {
99 m_opaque_sp->Clear();
100 }
101
102
103 StopReason
GetStopReason()104 SBThread::GetStopReason()
105 {
106 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
107
108 StopReason reason = eStopReasonInvalid;
109 Mutex::Locker api_locker;
110 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
111
112 if (exe_ctx.HasThreadScope())
113 {
114 Process::StopLocker stop_locker;
115 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
116 {
117 return exe_ctx.GetThreadPtr()->GetStopReason();
118 }
119 else
120 {
121 if (log)
122 log->Printf ("SBThread(%p)::GetStopReason() => error: process is running", exe_ctx.GetThreadPtr());
123 }
124 }
125
126 if (log)
127 log->Printf ("SBThread(%p)::GetStopReason () => %s", exe_ctx.GetThreadPtr(),
128 Thread::StopReasonAsCString (reason));
129
130 return reason;
131 }
132
133 size_t
GetStopReasonDataCount()134 SBThread::GetStopReasonDataCount ()
135 {
136 Mutex::Locker api_locker;
137 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
138
139 if (exe_ctx.HasThreadScope())
140 {
141 Process::StopLocker stop_locker;
142 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
143 {
144 StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
145 if (stop_info_sp)
146 {
147 StopReason reason = stop_info_sp->GetStopReason();
148 switch (reason)
149 {
150 case eStopReasonInvalid:
151 case eStopReasonNone:
152 case eStopReasonTrace:
153 case eStopReasonExec:
154 case eStopReasonPlanComplete:
155 case eStopReasonThreadExiting:
156 // There is no data for these stop reasons.
157 return 0;
158
159 case eStopReasonBreakpoint:
160 {
161 break_id_t site_id = stop_info_sp->GetValue();
162 lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
163 if (bp_site_sp)
164 return bp_site_sp->GetNumberOfOwners () * 2;
165 else
166 return 0; // Breakpoint must have cleared itself...
167 }
168 break;
169
170 case eStopReasonWatchpoint:
171 return 1;
172
173 case eStopReasonSignal:
174 return 1;
175
176 case eStopReasonException:
177 return 1;
178 }
179 }
180 }
181 else
182 {
183 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
184 if (log)
185 log->Printf ("SBThread(%p)::GetStopReasonDataCount() => error: process is running", exe_ctx.GetThreadPtr());
186 }
187 }
188 return 0;
189 }
190
191 uint64_t
GetStopReasonDataAtIndex(uint32_t idx)192 SBThread::GetStopReasonDataAtIndex (uint32_t idx)
193 {
194 Mutex::Locker api_locker;
195 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
196
197 if (exe_ctx.HasThreadScope())
198 {
199 Process::StopLocker stop_locker;
200 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
201 {
202 Thread *thread = exe_ctx.GetThreadPtr();
203 StopInfoSP stop_info_sp = thread->GetStopInfo ();
204 if (stop_info_sp)
205 {
206 StopReason reason = stop_info_sp->GetStopReason();
207 switch (reason)
208 {
209 case eStopReasonInvalid:
210 case eStopReasonNone:
211 case eStopReasonTrace:
212 case eStopReasonExec:
213 case eStopReasonPlanComplete:
214 case eStopReasonThreadExiting:
215 // There is no data for these stop reasons.
216 return 0;
217
218 case eStopReasonBreakpoint:
219 {
220 break_id_t site_id = stop_info_sp->GetValue();
221 lldb::BreakpointSiteSP bp_site_sp (exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID (site_id));
222 if (bp_site_sp)
223 {
224 uint32_t bp_index = idx / 2;
225 BreakpointLocationSP bp_loc_sp (bp_site_sp->GetOwnerAtIndex (bp_index));
226 if (bp_loc_sp)
227 {
228 if (bp_index & 1)
229 {
230 // Odd idx, return the breakpoint location ID
231 return bp_loc_sp->GetID();
232 }
233 else
234 {
235 // Even idx, return the breakpoint ID
236 return bp_loc_sp->GetBreakpoint().GetID();
237 }
238 }
239 }
240 return LLDB_INVALID_BREAK_ID;
241 }
242 break;
243
244 case eStopReasonWatchpoint:
245 return stop_info_sp->GetValue();
246
247 case eStopReasonSignal:
248 return stop_info_sp->GetValue();
249
250 case eStopReasonException:
251 return stop_info_sp->GetValue();
252 }
253 }
254 }
255 else
256 {
257 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
258 if (log)
259 log->Printf ("SBThread(%p)::GetStopReasonDataAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
260 }
261 }
262 return 0;
263 }
264
265 size_t
GetStopDescription(char * dst,size_t dst_len)266 SBThread::GetStopDescription (char *dst, size_t dst_len)
267 {
268 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
269
270 Mutex::Locker api_locker;
271 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
272
273 if (exe_ctx.HasThreadScope())
274 {
275 Process::StopLocker stop_locker;
276 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
277 {
278
279 StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
280 if (stop_info_sp)
281 {
282 const char *stop_desc = stop_info_sp->GetDescription();
283 if (stop_desc)
284 {
285 if (log)
286 log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
287 exe_ctx.GetThreadPtr(), stop_desc);
288 if (dst)
289 return ::snprintf (dst, dst_len, "%s", stop_desc);
290 else
291 {
292 // NULL dst passed in, return the length needed to contain the description
293 return ::strlen (stop_desc) + 1; // Include the NULL byte for size
294 }
295 }
296 else
297 {
298 size_t stop_desc_len = 0;
299 switch (stop_info_sp->GetStopReason())
300 {
301 case eStopReasonTrace:
302 case eStopReasonPlanComplete:
303 {
304 static char trace_desc[] = "step";
305 stop_desc = trace_desc;
306 stop_desc_len = sizeof(trace_desc); // Include the NULL byte for size
307 }
308 break;
309
310 case eStopReasonBreakpoint:
311 {
312 static char bp_desc[] = "breakpoint hit";
313 stop_desc = bp_desc;
314 stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
315 }
316 break;
317
318 case eStopReasonWatchpoint:
319 {
320 static char wp_desc[] = "watchpoint hit";
321 stop_desc = wp_desc;
322 stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
323 }
324 break;
325
326 case eStopReasonSignal:
327 {
328 stop_desc = exe_ctx.GetProcessPtr()->GetUnixSignals ().GetSignalAsCString (stop_info_sp->GetValue());
329 if (stop_desc == NULL || stop_desc[0] == '\0')
330 {
331 static char signal_desc[] = "signal";
332 stop_desc = signal_desc;
333 stop_desc_len = sizeof(signal_desc); // Include the NULL byte for size
334 }
335 }
336 break;
337
338 case eStopReasonException:
339 {
340 char exc_desc[] = "exception";
341 stop_desc = exc_desc;
342 stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
343 }
344 break;
345
346 case eStopReasonExec:
347 {
348 char exc_desc[] = "exec";
349 stop_desc = exc_desc;
350 stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
351 }
352 break;
353
354 case eStopReasonThreadExiting:
355 {
356 char limbo_desc[] = "thread exiting";
357 stop_desc = limbo_desc;
358 stop_desc_len = sizeof(limbo_desc);
359 }
360 break;
361 default:
362 break;
363 }
364
365 if (stop_desc && stop_desc[0])
366 {
367 if (log)
368 log->Printf ("SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
369 exe_ctx.GetThreadPtr(), stop_desc);
370
371 if (dst)
372 return ::snprintf (dst, dst_len, "%s", stop_desc) + 1; // Include the NULL byte
373
374 if (stop_desc_len == 0)
375 stop_desc_len = ::strlen (stop_desc) + 1; // Include the NULL byte
376
377 return stop_desc_len;
378 }
379 }
380 }
381 }
382 else
383 {
384 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
385 if (log)
386 log->Printf ("SBThread(%p)::GetStopDescription() => error: process is running", exe_ctx.GetThreadPtr());
387 }
388 }
389 if (dst)
390 *dst = 0;
391 return 0;
392 }
393
394 SBValue
GetStopReturnValue()395 SBThread::GetStopReturnValue ()
396 {
397 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
398 ValueObjectSP return_valobj_sp;
399 Mutex::Locker api_locker;
400 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
401
402 if (exe_ctx.HasThreadScope())
403 {
404 Process::StopLocker stop_locker;
405 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
406 {
407 StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo ();
408 if (stop_info_sp)
409 {
410 return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
411 }
412 }
413 else
414 {
415 if (log)
416 log->Printf ("SBThread(%p)::GetStopReturnValue() => error: process is running", exe_ctx.GetThreadPtr());
417 }
418 }
419
420 if (log)
421 log->Printf ("SBThread(%p)::GetStopReturnValue () => %s", exe_ctx.GetThreadPtr(),
422 return_valobj_sp.get()
423 ? return_valobj_sp->GetValueAsCString()
424 : "<no return value>");
425
426 return SBValue (return_valobj_sp);
427 }
428
429 void
SetThread(const ThreadSP & lldb_object_sp)430 SBThread::SetThread (const ThreadSP& lldb_object_sp)
431 {
432 m_opaque_sp->SetThreadSP (lldb_object_sp);
433 }
434
435
436 lldb::tid_t
GetThreadID() const437 SBThread::GetThreadID () const
438 {
439 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
440 if (thread_sp)
441 return thread_sp->GetID();
442 return LLDB_INVALID_THREAD_ID;
443 }
444
445 uint32_t
GetIndexID() const446 SBThread::GetIndexID () const
447 {
448 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
449 if (thread_sp)
450 return thread_sp->GetIndexID();
451 return LLDB_INVALID_INDEX32;
452 }
453
454 const char *
GetName() const455 SBThread::GetName () const
456 {
457 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
458 const char *name = NULL;
459 Mutex::Locker api_locker;
460 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
461
462 if (exe_ctx.HasThreadScope())
463 {
464 Process::StopLocker stop_locker;
465 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
466 {
467 name = exe_ctx.GetThreadPtr()->GetName();
468 }
469 else
470 {
471 if (log)
472 log->Printf ("SBThread(%p)::GetName() => error: process is running", exe_ctx.GetThreadPtr());
473 }
474 }
475
476 if (log)
477 log->Printf ("SBThread(%p)::GetName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
478
479 return name;
480 }
481
482 const char *
GetQueueName() const483 SBThread::GetQueueName () const
484 {
485 const char *name = NULL;
486 Mutex::Locker api_locker;
487 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
488
489 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
490 if (exe_ctx.HasThreadScope())
491 {
492 Process::StopLocker stop_locker;
493 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
494 {
495 name = exe_ctx.GetThreadPtr()->GetQueueName();
496 }
497 else
498 {
499 if (log)
500 log->Printf ("SBThread(%p)::GetQueueName() => error: process is running", exe_ctx.GetThreadPtr());
501 }
502 }
503
504 if (log)
505 log->Printf ("SBThread(%p)::GetQueueName () => %s", exe_ctx.GetThreadPtr(), name ? name : "NULL");
506
507 return name;
508 }
509
510 SBError
ResumeNewPlan(ExecutionContext & exe_ctx,ThreadPlan * new_plan)511 SBThread::ResumeNewPlan (ExecutionContext &exe_ctx, ThreadPlan *new_plan)
512 {
513 SBError sb_error;
514
515 Process *process = exe_ctx.GetProcessPtr();
516 if (!process)
517 {
518 sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
519 return sb_error;
520 }
521
522 Thread *thread = exe_ctx.GetThreadPtr();
523 if (!thread)
524 {
525 sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
526 return sb_error;
527 }
528
529 // User level plans should be Master Plans so they can be interrupted, other plans executed, and
530 // then a "continue" will resume the plan.
531 if (new_plan != NULL)
532 {
533 new_plan->SetIsMasterPlan(true);
534 new_plan->SetOkayToDiscard(false);
535 }
536
537 // Why do we need to set the current thread by ID here???
538 process->GetThreadList().SetSelectedThreadByID (thread->GetID());
539 sb_error.ref() = process->Resume();
540
541 if (sb_error.Success())
542 {
543 // If we are doing synchronous mode, then wait for the
544 // process to stop yet again!
545 if (process->GetTarget().GetDebugger().GetAsyncExecution () == false)
546 process->WaitForProcessToStop (NULL);
547 }
548
549 return sb_error;
550 }
551
552 void
StepOver(lldb::RunMode stop_other_threads)553 SBThread::StepOver (lldb::RunMode stop_other_threads)
554 {
555 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
556
557 Mutex::Locker api_locker;
558 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
559
560
561 if (log)
562 log->Printf ("SBThread(%p)::StepOver (stop_other_threads='%s')", exe_ctx.GetThreadPtr(),
563 Thread::RunModeAsCString (stop_other_threads));
564
565 if (exe_ctx.HasThreadScope())
566 {
567 Thread *thread = exe_ctx.GetThreadPtr();
568 bool abort_other_plans = false;
569 StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
570
571 ThreadPlanSP new_plan_sp;
572 if (frame_sp)
573 {
574 if (frame_sp->HasDebugInformation ())
575 {
576 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
577 new_plan_sp = thread->QueueThreadPlanForStepOverRange (abort_other_plans,
578 sc.line_entry.range,
579 sc,
580 stop_other_threads);
581 }
582 else
583 {
584 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (true,
585 abort_other_plans,
586 stop_other_threads);
587 }
588 }
589
590 // This returns an error, we should use it!
591 ResumeNewPlan (exe_ctx, new_plan_sp.get());
592 }
593 }
594
595 void
StepInto(lldb::RunMode stop_other_threads)596 SBThread::StepInto (lldb::RunMode stop_other_threads)
597 {
598 StepInto (NULL, stop_other_threads);
599 }
600
601 void
StepInto(const char * target_name,lldb::RunMode stop_other_threads)602 SBThread::StepInto (const char *target_name, lldb::RunMode stop_other_threads)
603 {
604 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
605
606 Mutex::Locker api_locker;
607 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
608
609 if (log)
610 log->Printf ("SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
611 exe_ctx.GetThreadPtr(),
612 target_name? target_name: "<NULL>",
613 Thread::RunModeAsCString (stop_other_threads));
614
615 if (exe_ctx.HasThreadScope())
616 {
617 bool abort_other_plans = false;
618
619 Thread *thread = exe_ctx.GetThreadPtr();
620 StackFrameSP frame_sp(thread->GetStackFrameAtIndex (0));
621 ThreadPlanSP new_plan_sp;
622
623 if (frame_sp && frame_sp->HasDebugInformation ())
624 {
625 bool avoid_code_without_debug_info = true;
626 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
627 new_plan_sp = thread->QueueThreadPlanForStepInRange (abort_other_plans,
628 sc.line_entry.range,
629 sc,
630 target_name,
631 stop_other_threads,
632 avoid_code_without_debug_info);
633 }
634 else
635 {
636 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction (false,
637 abort_other_plans,
638 stop_other_threads);
639 }
640
641 // This returns an error, we should use it!
642 ResumeNewPlan (exe_ctx, new_plan_sp.get());
643 }
644 }
645
646 void
StepOut()647 SBThread::StepOut ()
648 {
649 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
650
651 Mutex::Locker api_locker;
652 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
653
654
655 if (log)
656 log->Printf ("SBThread(%p)::StepOut ()", exe_ctx.GetThreadPtr());
657
658 if (exe_ctx.HasThreadScope())
659 {
660 bool abort_other_plans = false;
661 bool stop_other_threads = false;
662
663 Thread *thread = exe_ctx.GetThreadPtr();
664
665 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
666 NULL,
667 false,
668 stop_other_threads,
669 eVoteYes,
670 eVoteNoOpinion,
671 0));
672
673 // This returns an error, we should use it!
674 ResumeNewPlan (exe_ctx, new_plan_sp.get());
675 }
676 }
677
678 void
StepOutOfFrame(lldb::SBFrame & sb_frame)679 SBThread::StepOutOfFrame (lldb::SBFrame &sb_frame)
680 {
681 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
682
683 Mutex::Locker api_locker;
684 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
685
686 StackFrameSP frame_sp (sb_frame.GetFrameSP());
687 if (log)
688 {
689 SBStream frame_desc_strm;
690 sb_frame.GetDescription (frame_desc_strm);
691 log->Printf ("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)", exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
692 }
693
694 if (exe_ctx.HasThreadScope())
695 {
696 bool abort_other_plans = false;
697 bool stop_other_threads = false;
698 Thread *thread = exe_ctx.GetThreadPtr();
699
700 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut (abort_other_plans,
701 NULL,
702 false,
703 stop_other_threads,
704 eVoteYes,
705 eVoteNoOpinion,
706 frame_sp->GetFrameIndex()));
707
708 // This returns an error, we should use it!
709 ResumeNewPlan (exe_ctx, new_plan_sp.get());
710 }
711 }
712
713 void
StepInstruction(bool step_over)714 SBThread::StepInstruction (bool step_over)
715 {
716 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
717
718 Mutex::Locker api_locker;
719 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
720
721
722
723 if (log)
724 log->Printf ("SBThread(%p)::StepInstruction (step_over=%i)", exe_ctx.GetThreadPtr(), step_over);
725
726 if (exe_ctx.HasThreadScope())
727 {
728 Thread *thread = exe_ctx.GetThreadPtr();
729 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction (step_over, true, true));
730
731 // This returns an error, we should use it!
732 ResumeNewPlan (exe_ctx, new_plan_sp.get());
733 }
734 }
735
736 void
RunToAddress(lldb::addr_t addr)737 SBThread::RunToAddress (lldb::addr_t addr)
738 {
739 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
740
741 Mutex::Locker api_locker;
742 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
743
744
745 if (log)
746 log->Printf ("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")", exe_ctx.GetThreadPtr(), addr);
747
748 if (exe_ctx.HasThreadScope())
749 {
750 bool abort_other_plans = false;
751 bool stop_other_threads = true;
752
753 Address target_addr (addr);
754
755 Thread *thread = exe_ctx.GetThreadPtr();
756
757 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress (abort_other_plans, target_addr, stop_other_threads));
758
759 // This returns an error, we should use it!
760 ResumeNewPlan (exe_ctx, new_plan_sp.get());
761 }
762 }
763
764 SBError
StepOverUntil(lldb::SBFrame & sb_frame,lldb::SBFileSpec & sb_file_spec,uint32_t line)765 SBThread::StepOverUntil (lldb::SBFrame &sb_frame,
766 lldb::SBFileSpec &sb_file_spec,
767 uint32_t line)
768 {
769 SBError sb_error;
770 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
771 char path[PATH_MAX];
772
773 Mutex::Locker api_locker;
774 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
775
776 StackFrameSP frame_sp (sb_frame.GetFrameSP());
777
778 if (log)
779 {
780 SBStream frame_desc_strm;
781 sb_frame.GetDescription (frame_desc_strm);
782 sb_file_spec->GetPath (path, sizeof(path));
783 log->Printf ("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, file+line = %s:%u)",
784 exe_ctx.GetThreadPtr(),
785 frame_sp.get(),
786 frame_desc_strm.GetData(),
787 path, line);
788 }
789
790 if (exe_ctx.HasThreadScope())
791 {
792 Target *target = exe_ctx.GetTargetPtr();
793 Thread *thread = exe_ctx.GetThreadPtr();
794
795 if (line == 0)
796 {
797 sb_error.SetErrorString("invalid line argument");
798 return sb_error;
799 }
800
801 if (!frame_sp)
802 {
803 frame_sp = thread->GetSelectedFrame ();
804 if (!frame_sp)
805 frame_sp = thread->GetStackFrameAtIndex (0);
806 }
807
808 SymbolContext frame_sc;
809 if (!frame_sp)
810 {
811 sb_error.SetErrorString("no valid frames in thread to step");
812 return sb_error;
813 }
814
815 // If we have a frame, get its line
816 frame_sc = frame_sp->GetSymbolContext (eSymbolContextCompUnit |
817 eSymbolContextFunction |
818 eSymbolContextLineEntry |
819 eSymbolContextSymbol );
820
821 if (frame_sc.comp_unit == NULL)
822 {
823 sb_error.SetErrorStringWithFormat("frame %u doesn't have debug information", frame_sp->GetFrameIndex());
824 return sb_error;
825 }
826
827 FileSpec step_file_spec;
828 if (sb_file_spec.IsValid())
829 {
830 // The file spec passed in was valid, so use it
831 step_file_spec = sb_file_spec.ref();
832 }
833 else
834 {
835 if (frame_sc.line_entry.IsValid())
836 step_file_spec = frame_sc.line_entry.file;
837 else
838 {
839 sb_error.SetErrorString("invalid file argument or no file for frame");
840 return sb_error;
841 }
842 }
843
844 // Grab the current function, then we will make sure the "until" address is
845 // within the function. We discard addresses that are out of the current
846 // function, and then if there are no addresses remaining, give an appropriate
847 // error message.
848
849 bool all_in_function = true;
850 AddressRange fun_range = frame_sc.function->GetAddressRange();
851
852 std::vector<addr_t> step_over_until_addrs;
853 const bool abort_other_plans = false;
854 const bool stop_other_threads = false;
855 const bool check_inlines = true;
856 const bool exact = false;
857
858 SymbolContextList sc_list;
859 const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext (step_file_spec,
860 line,
861 check_inlines,
862 exact,
863 eSymbolContextLineEntry,
864 sc_list);
865 if (num_matches > 0)
866 {
867 SymbolContext sc;
868 for (uint32_t i=0; i<num_matches; ++i)
869 {
870 if (sc_list.GetContextAtIndex(i, sc))
871 {
872 addr_t step_addr = sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
873 if (step_addr != LLDB_INVALID_ADDRESS)
874 {
875 if (fun_range.ContainsLoadAddress(step_addr, target))
876 step_over_until_addrs.push_back(step_addr);
877 else
878 all_in_function = false;
879 }
880 }
881 }
882 }
883
884 if (step_over_until_addrs.empty())
885 {
886 if (all_in_function)
887 {
888 step_file_spec.GetPath (path, sizeof(path));
889 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path, line);
890 }
891 else
892 sb_error.SetErrorString ("step until target not in current function");
893 }
894 else
895 {
896 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil (abort_other_plans,
897 &step_over_until_addrs[0],
898 step_over_until_addrs.size(),
899 stop_other_threads,
900 frame_sp->GetFrameIndex()));
901
902 sb_error = ResumeNewPlan (exe_ctx, new_plan_sp.get());
903 }
904 }
905 else
906 {
907 sb_error.SetErrorString("this SBThread object is invalid");
908 }
909 return sb_error;
910 }
911
912 SBError
ReturnFromFrame(SBFrame & frame,SBValue & return_value)913 SBThread::ReturnFromFrame (SBFrame &frame, SBValue &return_value)
914 {
915 SBError sb_error;
916
917 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
918
919 Mutex::Locker api_locker;
920 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
921
922
923 if (log)
924 log->Printf ("SBThread(%p)::ReturnFromFrame (frame=%d)", exe_ctx.GetThreadPtr(), frame.GetFrameID());
925
926 if (exe_ctx.HasThreadScope())
927 {
928 Thread *thread = exe_ctx.GetThreadPtr();
929 sb_error.SetError (thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
930 }
931
932 return sb_error;
933 }
934
935
936 bool
Suspend()937 SBThread::Suspend()
938 {
939 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
940 ExecutionContext exe_ctx (m_opaque_sp.get());
941 bool result = false;
942 if (exe_ctx.HasThreadScope())
943 {
944 Process::StopLocker stop_locker;
945 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
946 {
947 exe_ctx.GetThreadPtr()->SetResumeState (eStateSuspended);
948 result = true;
949 }
950 else
951 {
952 if (log)
953 log->Printf ("SBThread(%p)::Suspend() => error: process is running", exe_ctx.GetThreadPtr());
954 }
955 }
956 if (log)
957 log->Printf ("SBThread(%p)::Suspend() => %i", exe_ctx.GetThreadPtr(), result);
958 return result;
959 }
960
961 bool
Resume()962 SBThread::Resume ()
963 {
964 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
965 ExecutionContext exe_ctx (m_opaque_sp.get());
966 bool result = false;
967 if (exe_ctx.HasThreadScope())
968 {
969 Process::StopLocker stop_locker;
970 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
971 {
972 exe_ctx.GetThreadPtr()->SetResumeState (eStateRunning);
973 result = true;
974 }
975 else
976 {
977 if (log)
978 log->Printf ("SBThread(%p)::Resume() => error: process is running", exe_ctx.GetThreadPtr());
979 }
980 }
981 if (log)
982 log->Printf ("SBThread(%p)::Resume() => %i", exe_ctx.GetThreadPtr(), result);
983 return result;
984 }
985
986 bool
IsSuspended()987 SBThread::IsSuspended()
988 {
989 ExecutionContext exe_ctx (m_opaque_sp.get());
990 if (exe_ctx.HasThreadScope())
991 return exe_ctx.GetThreadPtr()->GetResumeState () == eStateSuspended;
992 return false;
993 }
994
995 bool
IsStopped()996 SBThread::IsStopped()
997 {
998 ExecutionContext exe_ctx (m_opaque_sp.get());
999 if (exe_ctx.HasThreadScope())
1000 return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1001 return false;
1002 }
1003
1004 SBProcess
GetProcess()1005 SBThread::GetProcess ()
1006 {
1007 SBProcess sb_process;
1008 ExecutionContext exe_ctx (m_opaque_sp.get());
1009 if (exe_ctx.HasThreadScope())
1010 {
1011 // Have to go up to the target so we can get a shared pointer to our process...
1012 sb_process.SetSP (exe_ctx.GetProcessSP());
1013 }
1014
1015 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1016 if (log)
1017 {
1018 SBStream frame_desc_strm;
1019 sb_process.GetDescription (frame_desc_strm);
1020 log->Printf ("SBThread(%p)::GetProcess () => SBProcess(%p): %s", exe_ctx.GetThreadPtr(),
1021 sb_process.GetSP().get(), frame_desc_strm.GetData());
1022 }
1023
1024 return sb_process;
1025 }
1026
1027 uint32_t
GetNumFrames()1028 SBThread::GetNumFrames ()
1029 {
1030 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1031
1032 uint32_t num_frames = 0;
1033 Mutex::Locker api_locker;
1034 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1035
1036 if (exe_ctx.HasThreadScope())
1037 {
1038 Process::StopLocker stop_locker;
1039 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1040 {
1041 num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1042 }
1043 else
1044 {
1045 if (log)
1046 log->Printf ("SBThread(%p)::GetNumFrames() => error: process is running", exe_ctx.GetThreadPtr());
1047 }
1048 }
1049
1050 if (log)
1051 log->Printf ("SBThread(%p)::GetNumFrames () => %u", exe_ctx.GetThreadPtr(), num_frames);
1052
1053 return num_frames;
1054 }
1055
1056 SBFrame
GetFrameAtIndex(uint32_t idx)1057 SBThread::GetFrameAtIndex (uint32_t idx)
1058 {
1059 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1060
1061 SBFrame sb_frame;
1062 StackFrameSP frame_sp;
1063 Mutex::Locker api_locker;
1064 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1065
1066 if (exe_ctx.HasThreadScope())
1067 {
1068 Process::StopLocker stop_locker;
1069 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1070 {
1071 frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex (idx);
1072 sb_frame.SetFrameSP (frame_sp);
1073 }
1074 else
1075 {
1076 if (log)
1077 log->Printf ("SBThread(%p)::GetFrameAtIndex() => error: process is running", exe_ctx.GetThreadPtr());
1078 }
1079 }
1080
1081 if (log)
1082 {
1083 SBStream frame_desc_strm;
1084 sb_frame.GetDescription (frame_desc_strm);
1085 log->Printf ("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1086 exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1087 }
1088
1089 return sb_frame;
1090 }
1091
1092 lldb::SBFrame
GetSelectedFrame()1093 SBThread::GetSelectedFrame ()
1094 {
1095 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1096
1097 SBFrame sb_frame;
1098 StackFrameSP frame_sp;
1099 Mutex::Locker api_locker;
1100 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1101
1102 if (exe_ctx.HasThreadScope())
1103 {
1104 Process::StopLocker stop_locker;
1105 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1106 {
1107 frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame ();
1108 sb_frame.SetFrameSP (frame_sp);
1109 }
1110 else
1111 {
1112 if (log)
1113 log->Printf ("SBThread(%p)::GetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1114 }
1115 }
1116
1117 if (log)
1118 {
1119 SBStream frame_desc_strm;
1120 sb_frame.GetDescription (frame_desc_strm);
1121 log->Printf ("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1122 exe_ctx.GetThreadPtr(), frame_sp.get(), frame_desc_strm.GetData());
1123 }
1124
1125 return sb_frame;
1126 }
1127
1128 lldb::SBFrame
SetSelectedFrame(uint32_t idx)1129 SBThread::SetSelectedFrame (uint32_t idx)
1130 {
1131 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
1132
1133 SBFrame sb_frame;
1134 StackFrameSP frame_sp;
1135 Mutex::Locker api_locker;
1136 ExecutionContext exe_ctx (m_opaque_sp.get(), api_locker);
1137
1138 if (exe_ctx.HasThreadScope())
1139 {
1140 Process::StopLocker stop_locker;
1141 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock()))
1142 {
1143 Thread *thread = exe_ctx.GetThreadPtr();
1144 frame_sp = thread->GetStackFrameAtIndex (idx);
1145 if (frame_sp)
1146 {
1147 thread->SetSelectedFrame (frame_sp.get());
1148 sb_frame.SetFrameSP (frame_sp);
1149 }
1150 }
1151 else
1152 {
1153 if (log)
1154 log->Printf ("SBThread(%p)::SetSelectedFrame() => error: process is running", exe_ctx.GetThreadPtr());
1155 }
1156 }
1157
1158 if (log)
1159 {
1160 SBStream frame_desc_strm;
1161 sb_frame.GetDescription (frame_desc_strm);
1162 log->Printf ("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1163 exe_ctx.GetThreadPtr(), idx, frame_sp.get(), frame_desc_strm.GetData());
1164 }
1165 return sb_frame;
1166 }
1167
1168 bool
EventIsThreadEvent(const SBEvent & event)1169 SBThread::EventIsThreadEvent (const SBEvent &event)
1170 {
1171 return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
1172 }
1173
1174 SBFrame
GetStackFrameFromEvent(const SBEvent & event)1175 SBThread::GetStackFrameFromEvent (const SBEvent &event)
1176 {
1177 return Thread::ThreadEventData::GetStackFrameFromEvent (event.get());
1178
1179 }
1180
1181 SBThread
GetThreadFromEvent(const SBEvent & event)1182 SBThread::GetThreadFromEvent (const SBEvent &event)
1183 {
1184 return Thread::ThreadEventData::GetThreadFromEvent (event.get());
1185 }
1186
1187 bool
operator ==(const SBThread & rhs) const1188 SBThread::operator == (const SBThread &rhs) const
1189 {
1190 return m_opaque_sp->GetThreadSP().get() == rhs.m_opaque_sp->GetThreadSP().get();
1191 }
1192
1193 bool
operator !=(const SBThread & rhs) const1194 SBThread::operator != (const SBThread &rhs) const
1195 {
1196 return m_opaque_sp->GetThreadSP().get() != rhs.m_opaque_sp->GetThreadSP().get();
1197 }
1198
1199 bool
GetStatus(SBStream & status) const1200 SBThread::GetStatus (SBStream &status) const
1201 {
1202 Stream &strm = status.ref();
1203
1204 ExecutionContext exe_ctx (m_opaque_sp.get());
1205 if (exe_ctx.HasThreadScope())
1206 {
1207 exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1);
1208 }
1209 else
1210 strm.PutCString ("No status");
1211
1212 return true;
1213 }
1214
1215 bool
GetDescription(SBStream & description) const1216 SBThread::GetDescription (SBStream &description) const
1217 {
1218 Stream &strm = description.ref();
1219
1220 ExecutionContext exe_ctx (m_opaque_sp.get());
1221 if (exe_ctx.HasThreadScope())
1222 {
1223 strm.Printf("SBThread: tid = 0x%4.4" PRIx64, exe_ctx.GetThreadPtr()->GetID());
1224 }
1225 else
1226 strm.PutCString ("No value");
1227
1228 return true;
1229 }
1230