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