blob: 35120905ac10e0a5bb8d504c4cc1c58543dbb581 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- Thread.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-private-log.h"
Jim Ingham3c7b5b92010-06-16 02:00:15 +000011#include "lldb/Breakpoint/BreakpointLocation.h"
Chris Lattner24943d22010-06-08 16:52:24 +000012#include "lldb/Core/Log.h"
13#include "lldb/Core/Stream.h"
14#include "lldb/Core/StreamString.h"
15#include "lldb/Host/Host.h"
16#include "lldb/Target/DynamicLoader.h"
17#include "lldb/Target/ExecutionContext.h"
18#include "lldb/Target/Process.h"
19#include "lldb/Target/RegisterContext.h"
Greg Clayton7661a982010-07-23 16:45:51 +000020#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "lldb/Target/Thread.h"
22#include "lldb/Target/ThreadPlan.h"
23#include "lldb/Target/ThreadPlanCallFunction.h"
Chris Lattner24943d22010-06-08 16:52:24 +000024#include "lldb/Target/ThreadPlanBase.h"
25#include "lldb/Target/ThreadPlanStepInstruction.h"
26#include "lldb/Target/ThreadPlanStepOut.h"
27#include "lldb/Target/ThreadPlanStepOverBreakpoint.h"
28#include "lldb/Target/ThreadPlanStepThrough.h"
29#include "lldb/Target/ThreadPlanStepInRange.h"
30#include "lldb/Target/ThreadPlanStepOverRange.h"
31#include "lldb/Target/ThreadPlanRunToAddress.h"
32#include "lldb/Target/ThreadPlanStepUntil.h"
Jim Ingham3c7b5b92010-06-16 02:00:15 +000033#include "lldb/Target/ThreadSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000034
35using namespace lldb;
36using namespace lldb_private;
37
38Thread::Thread (Process &process, lldb::tid_t tid) :
39 UserID (tid),
Benjamin Kramer36a08102010-07-16 12:32:33 +000040 m_process (process),
Chris Lattner24943d22010-06-08 16:52:24 +000041 m_index_id (process.GetNextThreadIndexID ()),
42 m_reg_context_sp (),
Chris Lattner24943d22010-06-08 16:52:24 +000043 m_state (eStateUnloaded),
44 m_plan_stack (),
45 m_immediate_plan_stack(),
46 m_completed_plan_stack(),
47 m_state_mutex (Mutex::eMutexTypeRecursive),
48 m_frames (),
49 m_current_frame_idx (0),
50 m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER),
51 m_resume_state (eStateRunning)
52{
53 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
54 if (log)
55 log->Printf ("%p Thread::Thread(tid = 0x%4.4x)", this, GetID());
56
57 QueueFundamentalPlan(true);
58}
59
60
61Thread::~Thread()
62{
63 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT);
64 if (log)
65 log->Printf ("%p Thread::~Thread(tid = 0x%4.4x)", this, GetID());
66}
67
68int
69Thread::GetResumeSignal () const
70{
71 return m_resume_signal;
72}
73
74void
75Thread::SetResumeSignal (int signal)
76{
77 m_resume_signal = signal;
78}
79
80StateType
81Thread::GetResumeState () const
82{
83 return m_resume_state;
84}
85
86void
87Thread::SetResumeState (StateType state)
88{
89 m_resume_state = state;
90}
91
92Thread::StopInfo::StopInfo(Thread *thread) :
93 m_reason (eStopReasonInvalid),
Chris Lattner24943d22010-06-08 16:52:24 +000094 m_thread (thread),
Benjamin Kramer36a08102010-07-16 12:32:33 +000095 m_description (),
Chris Lattner24943d22010-06-08 16:52:24 +000096 m_details ()
97{
98 m_description[0] = '\0';
99}
100
101Thread::StopInfo::~StopInfo()
102{
103}
104
105
106void
107Thread::StopInfo::Clear()
108{
109 m_reason = eStopReasonInvalid;
110 m_completed_plan_sp.reset();
111 m_description[0] = '\0';
112 ::bzero (&m_details, sizeof(m_details));
113}
114
115StopReason
116Thread::StopInfo::GetStopReason() const
117{
118 return m_reason;
119}
120
121const char *
122Thread::StopInfo::GetStopDescription() const
123{
124 if (m_description[0])
125 return m_description;
126 return NULL;
127}
128
129void
130Thread::StopInfo::SetStopDescription(const char *desc)
131{
132 if (desc && desc[0])
133 {
134 ::snprintf (m_description, sizeof(m_description), "%s", desc);
135 }
136 else
137 {
138 m_description[0] = '\0';
139 }
140}
141
142void
Greg Clayton7661a982010-07-23 16:45:51 +0000143Thread::StopInfo::SetStopReasonWithMachException
144(
145 uint32_t exc_type,
146 size_t exc_data_count,
147 const addr_t *exc_data
148)
149{
150 assert (exc_data_count < LLDB_THREAD_MAX_STOP_EXC_DATA);
151 assert (m_thread != NULL);
152 m_reason = eStopReasonException;
153 m_details.exception.type = exc_type;
154 m_details.exception.data_count = exc_data_count;
155 for (size_t i=0; i<exc_data_count; ++i)
156 m_details.exception.data[i] = exc_data[i];
157
158 if (m_details.exception.type != 0)
159 {
160 ArchSpec::CPU cpu = m_thread->GetProcess().GetTarget().GetArchitecture().GetGenericCPUType();
161
162 bool exc_translated = false;
163 const char *exc_desc = NULL;
164 const char *code_label = "code";
165 const char *code_desc = NULL;
166 const char *subcode_label = "subcode";
167 const char *subcode_desc = NULL;
168 switch (m_details.exception.type)
169 {
170 case 1: // EXC_BAD_ACCESS
171 exc_desc = "EXC_BAD_ACCESS";
172 subcode_label = "address";
173 switch (cpu)
174 {
175 case ArchSpec::eCPU_arm:
176 switch (m_details.exception.data[0])
177 {
178 case 0x101: code_desc = "EXC_ARM_DA_ALIGN"; break;
179 case 0x102: code_desc = "EXC_ARM_DA_DEBUG"; break;
180 }
181 break;
182
183 case ArchSpec::eCPU_ppc:
184 case ArchSpec::eCPU_ppc64:
185 switch (m_details.exception.data[0])
186 {
187 case 0x101: code_desc = "EXC_PPC_VM_PROT_READ"; break;
188 case 0x102: code_desc = "EXC_PPC_BADSPACE"; break;
189 case 0x103: code_desc = "EXC_PPC_UNALIGNED"; break;
190 }
191 break;
192
193 default:
194 break;
195 }
196 break;
197
198 case 2: // EXC_BAD_INSTRUCTION
199 exc_desc = "EXC_BAD_INSTRUCTION";
200 switch (cpu)
201 {
202 case ArchSpec::eCPU_i386:
203 case ArchSpec::eCPU_x86_64:
204 if (m_details.exception.data[0] == 1)
205 code_desc = "EXC_I386_INVOP";
206 break;
207
208 case ArchSpec::eCPU_ppc:
209 case ArchSpec::eCPU_ppc64:
210 switch (m_details.exception.data[0])
211 {
212 case 1: code_desc = "EXC_PPC_INVALID_SYSCALL"; break;
213 case 2: code_desc = "EXC_PPC_UNIPL_INST"; break;
214 case 3: code_desc = "EXC_PPC_PRIVINST"; break;
215 case 4: code_desc = "EXC_PPC_PRIVREG"; break;
216 case 5: // EXC_PPC_TRACE
217 SetStopReasonToTrace();
218 exc_translated = true;
219 break;
220 case 6: code_desc = "EXC_PPC_PERFMON"; break;
221 }
222 break;
223
224 case ArchSpec::eCPU_arm:
225 if (m_details.exception.data[0] == 1)
226 code_desc = "EXC_ARM_UNDEFINED";
227 break;
228
229 default:
230 break;
231 }
232 break;
233
234 case 3: // EXC_ARITHMETIC
235 exc_desc = "EXC_ARITHMETIC";
236 switch (cpu)
237 {
238 case ArchSpec::eCPU_i386:
239 case ArchSpec::eCPU_x86_64:
240 switch (m_details.exception.data[0])
241 {
242 case 1: code_desc = "EXC_I386_DIV"; break;
243 case 2: code_desc = "EXC_I386_INTO"; break;
244 case 3: code_desc = "EXC_I386_NOEXT"; break;
245 case 4: code_desc = "EXC_I386_EXTOVR"; break;
246 case 5: code_desc = "EXC_I386_EXTERR"; break;
247 case 6: code_desc = "EXC_I386_EMERR"; break;
248 case 7: code_desc = "EXC_I386_BOUND"; break;
249 case 8: code_desc = "EXC_I386_SSEEXTERR"; break;
250 }
251 break;
252
253 case ArchSpec::eCPU_ppc:
254 case ArchSpec::eCPU_ppc64:
255 switch (m_details.exception.data[0])
256 {
257 case 1: code_desc = "EXC_PPC_OVERFLOW"; break;
258 case 2: code_desc = "EXC_PPC_ZERO_DIVIDE"; break;
259 case 3: code_desc = "EXC_PPC_FLT_INEXACT"; break;
260 case 4: code_desc = "EXC_PPC_FLT_ZERO_DIVIDE"; break;
261 case 5: code_desc = "EXC_PPC_FLT_UNDERFLOW"; break;
262 case 6: code_desc = "EXC_PPC_FLT_OVERFLOW"; break;
263 case 7: code_desc = "EXC_PPC_FLT_NOT_A_NUMBER"; break;
264 }
265 break;
266
267 default:
268 break;
269 }
270 break;
271
272 case 4: // EXC_EMULATION
273 exc_desc = "EXC_EMULATION";
274 break;
275
276
277 case 5: // EXC_SOFTWARE
278 exc_desc = "EXC_SOFTWARE";
279 if (m_details.exception.data[0] == EXC_SOFT_SIGNAL && m_details.exception.data_count == 2)
280 {
281 SetStopReasonWithSignal(m_details.exception.data[1]);
282 exc_translated = true;
283 }
284 break;
285
286 case 6:
287 {
288 exc_desc = "EXC_SOFTWARE";
289 bool is_software_breakpoint = false;
290 switch (cpu)
291 {
292 case ArchSpec::eCPU_i386:
293 case ArchSpec::eCPU_x86_64:
294 if (m_details.exception.data[0] == 1) // EXC_I386_SGL
295 {
296 exc_translated = true;
297 SetStopReasonToTrace ();
298 }
299 else if (m_details.exception.data[0] == 2) // EXC_I386_BPT
300 {
301 is_software_breakpoint = true;
302 }
303 break;
304
305 case ArchSpec::eCPU_ppc:
306 case ArchSpec::eCPU_ppc64:
307 is_software_breakpoint = m_details.exception.data[0] == 1; // EXC_PPC_BREAKPOINT
308 break;
309
310 case ArchSpec::eCPU_arm:
311 is_software_breakpoint = m_details.exception.data[0] == 1; // EXC_ARM_BREAKPOINT
312 break;
313
314 default:
315 break;
316 }
317
318 if (is_software_breakpoint)
319 {
320 addr_t pc = m_thread->GetRegisterContext()->GetPC();
321 lldb::BreakpointSiteSP bp_site_sp = m_thread->GetProcess().GetBreakpointSiteList().FindByAddress(pc);
322 if (bp_site_sp)
323 {
324 exc_translated = true;
325 if (bp_site_sp->ValidForThisThread (m_thread))
326 {
327 Clear ();
328 SetStopReasonWithBreakpointSiteID (bp_site_sp->GetID());
329 }
330 else
331 {
332 Clear ();
333 SetStopReasonToNone();
334 }
335
336 }
337 }
338 }
339 break;
340
341 case 7:
342 exc_desc = "EXC_SYSCALL";
343 break;
344
345 case 8:
346 exc_desc = "EXC_MACH_SYSCALL";
347 break;
348
349 case 9:
350 exc_desc = "EXC_RPC_ALERT";
351 break;
352
353 case 10:
354 exc_desc = "EXC_CRASH";
355 break;
356 }
357
358 if (!exc_translated)
359 {
360 StreamString desc_strm;
361
362 if (exc_desc)
363 desc_strm.PutCString(exc_desc);
364 else
365 desc_strm.Printf("EXC_??? (%u)", exc_type);
366
367 if (m_details.exception.data_count >= 1)
368 {
369 if (code_desc)
370 desc_strm.Printf(" (%s=%s", code_label, code_desc);
371 else
372 desc_strm.Printf(" (%s=%llu", code_label, exc_data[0]);
373 }
374
375 if (m_details.exception.data_count >= 2)
376 {
377 if (subcode_desc)
378 desc_strm.Printf(", %s=%s", subcode_label, subcode_desc);
379 else
380 desc_strm.Printf(", %s=0x%llx", subcode_label, exc_data[1]);
381 }
382
383 if (m_details.exception.data_count > 0)
384 desc_strm.PutChar(')');
385
386 SetStopDescription(desc_strm.GetString().c_str());
387 }
388 }
389}
390void
Chris Lattner24943d22010-06-08 16:52:24 +0000391Thread::StopInfo::SetThread (Thread* thread)
392{
393 m_thread = thread;
394}
395
396Thread *
397Thread::StopInfo::GetThread ()
398{
399 return m_thread;
400}
401
402lldb::user_id_t
403Thread::StopInfo::GetBreakpointSiteID() const
404{
405 if (m_reason == eStopReasonBreakpoint)
406 return m_details.breakpoint.bp_site_id;
407 return LLDB_INVALID_BREAK_ID;
408}
409
410void
411Thread::StopInfo::SetStopReasonWithBreakpointSiteID (lldb::user_id_t bp_site_id)
412{
413 m_reason = eStopReasonBreakpoint;
414 m_details.breakpoint.bp_site_id = bp_site_id;
415}
416
417lldb::user_id_t
418Thread::StopInfo::GetWatchpointID() const
419{
420 if (m_reason == eStopReasonWatchpoint)
421 return m_details.watchpoint.watch_id;
422 return LLDB_INVALID_WATCH_ID;
423}
424
425void
426Thread::StopInfo::SetStopReasonWithWatchpointID (lldb::user_id_t watch_id)
427{
428 m_reason = eStopReasonWatchpoint;
429 m_details.watchpoint.watch_id = watch_id;
430}
431
432
433int
434Thread::StopInfo::GetSignal() const
435{
436 if (m_reason == eStopReasonSignal)
437 return m_details.signal.signo;
438 return 0;
439}
440
441lldb::user_id_t
442Thread::StopInfo::GetPlanID() const
443{
444 if (m_reason == eStopReasonPlanComplete)
445 return m_completed_plan_sp->GetID();
446 return LLDB_INVALID_UID;
447}
448
449void
450Thread::StopInfo::SetStopReasonWithSignal (int signo)
451{
452 m_reason = eStopReasonSignal;
453 m_details.signal.signo = signo;
454}
455
456void
457Thread::StopInfo::SetStopReasonToTrace ()
458{
459 m_reason = eStopReasonTrace;
460}
461
462uint32_t
463Thread::StopInfo::GetExceptionType() const
464{
465 if (m_reason == eStopReasonException)
466 return m_details.exception.type;
467 return 0;
468}
469
470size_t
471Thread::StopInfo::GetExceptionDataCount() const
472{
473 if (m_reason == eStopReasonException)
474 return m_details.exception.data_count;
475 return 0;
476}
477
478void
Greg Clayton7661a982010-07-23 16:45:51 +0000479Thread::StopInfo::SetStopReasonWithGenericException (uint32_t exc_type, size_t exc_data_count)
Chris Lattner24943d22010-06-08 16:52:24 +0000480{
481 m_reason = eStopReasonException;
482 m_details.exception.type = exc_type;
483 m_details.exception.data_count = exc_data_count;
484}
485
486void
487Thread::StopInfo::SetStopReasonWithPlan (ThreadPlanSP &thread_plan_sp)
488{
489 m_reason = eStopReasonPlanComplete;
490 m_completed_plan_sp = thread_plan_sp;
491}
492
493void
494Thread::StopInfo::SetStopReasonToNone ()
495{
496 Clear();
497 m_reason = eStopReasonNone;
498}
499
500lldb::addr_t
501Thread::StopInfo::GetExceptionDataAtIndex (uint32_t idx) const
502{
503 if (m_reason == eStopReasonException && idx < m_details.exception.data_count)
504 return m_details.exception.data[idx];
505 return 0;
506
507}
508
509
510bool
511Thread::StopInfo::SetExceptionDataAtIndex (uint32_t idx, lldb::addr_t data)
512{
513 if (m_reason == eStopReasonException && idx < m_details.exception.data_count)
514 {
515 m_details.exception.data[idx] = data;
516 return true;
517 }
518 return false;
519}
520
521void
522Thread::StopInfo::Dump (Stream *s) const
523{
524 if (m_description[0])
525 s->Printf("%s", m_description);
526 else
527 {
528 switch (m_reason)
529 {
530 case eStopReasonInvalid:
531 s->PutCString("invalid");
532 break;
533
534 case eStopReasonNone:
535 s->PutCString("none");
536 break;
537
538 case eStopReasonTrace:
539 s->PutCString("trace");
540 break;
541
542 case eStopReasonBreakpoint:
543 {
544 bool no_details = true;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000545 s->PutCString ("breakpoint");
Chris Lattner24943d22010-06-08 16:52:24 +0000546 if (m_thread)
547 {
548 BreakpointSiteSP bp_site_sp = m_thread->GetProcess().GetBreakpointSiteList().FindByID(m_details.breakpoint.bp_site_id);
549 if (bp_site_sp)
550 {
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000551 // Only report the breakpoint locations that actually caused this hit - some of them may
552 // have options that would have caused us not to stop here...
553 uint32_t num_locations = bp_site_sp->GetNumberOfOwners();
554 for (uint32_t i = 0; i < num_locations; i++)
555 {
556 BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(i);
557 if (bp_loc_sp->ValidForThisThread(m_thread))
558 {
559 s->PutCString(" ");
560 bp_loc_sp->GetDescription(s, lldb::eDescriptionLevelBrief);
561 no_details = false;
562 }
563 }
Chris Lattner24943d22010-06-08 16:52:24 +0000564 }
565 }
566
567 if (no_details)
568 s->Printf ("site id: %d", m_details.breakpoint.bp_site_id);
569 }
570 break;
571
572 case eStopReasonWatchpoint:
573 s->Printf("watchpoint (site id = %u)", m_details.watchpoint.watch_id);
574 break;
575
576 case eStopReasonSignal:
577 {
578 s->Printf("signal: signo = %i", m_details.signal.signo);
579 const char * signal_name = m_thread->GetProcess().GetUnixSignals().GetSignalAsCString (m_details.signal.signo);
580 if (signal_name)
581 s->Printf(" (%s)", signal_name);
582 }
583 break;
584
585 case eStopReasonException:
586 {
587 s->Printf("exception: type = 0x%8.8x, data_count = %zu", m_details.exception.type, m_details.exception.data_count);
588 uint32_t i;
589 for (i=0; i<m_details.exception.data_count; ++i)
590 {
591 s->Printf(", data[%u] = 0x%8.8llx", i, m_details.exception.data[i]);
592 }
593 }
594 break;
595
596 case eStopReasonPlanComplete:
597 {
598 m_completed_plan_sp->GetDescription (s, lldb::eDescriptionLevelBrief);
599 }
600 break;
601 }
602 }
603}
604
605bool
606Thread::GetStopInfo (Thread::StopInfo *stop_info)
607{
608 stop_info->SetThread(this);
609 ThreadPlanSP completed_plan = GetCompletedPlan();
610 if (completed_plan != NULL)
611 {
612 stop_info->Clear ();
613 stop_info->SetStopReasonWithPlan (completed_plan);
614 return true;
615 }
616 else
617 return GetRawStopReason (stop_info);
618}
619
620bool
621Thread::ThreadStoppedForAReason (void)
622{
623 Thread::StopInfo stop_info;
624 stop_info.SetThread(this);
625 if (GetRawStopReason (&stop_info))
626 {
627 StopReason reason = stop_info.GetStopReason();
628 if (reason == eStopReasonInvalid || reason == eStopReasonNone)
629 return false;
630 else
631 return true;
632 }
633 else
634 return false;
635}
636
637StateType
638Thread::GetState() const
639{
640 // If any other threads access this we will need a mutex for it
641 Mutex::Locker locker(m_state_mutex);
642 return m_state;
643}
644
645void
646Thread::SetState(StateType state)
647{
648 Mutex::Locker locker(m_state_mutex);
649 m_state = state;
650}
651
652void
653Thread::WillStop()
654{
655 ThreadPlan *current_plan = GetCurrentPlan();
656
657 // FIXME: I may decide to disallow threads with no plans. In which
658 // case this should go to an assert.
659
660 if (!current_plan)
661 return;
662
663 current_plan->WillStop();
664}
665
666void
667Thread::SetupForResume ()
668{
669 if (GetResumeState() != eStateSuspended)
670 {
671
672 // If we're at a breakpoint push the step-over breakpoint plan. Do this before
673 // telling the current plan it will resume, since we might change what the current
674 // plan is.
675
676 lldb::addr_t pc = GetRegisterContext()->GetPC();
677 BreakpointSiteSP bp_site_sp = GetProcess().GetBreakpointSiteList().FindByAddress(pc);
678 if (bp_site_sp && bp_site_sp->IsEnabled())
679 {
680 // Note, don't assume there's a ThreadPlanStepOverBreakpoint, the target may not require anything
681 // special to step over a breakpoint.
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000682
683 ThreadPlan *cur_plan = GetCurrentPlan();
Chris Lattner24943d22010-06-08 16:52:24 +0000684
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000685 if (cur_plan->GetKind() != ThreadPlan::eKindStepOverBreakpoint)
686 {
687 ThreadPlanStepOverBreakpoint *step_bp_plan = new ThreadPlanStepOverBreakpoint (*this);
688 if (step_bp_plan)
Chris Lattner24943d22010-06-08 16:52:24 +0000689 {
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000690 ThreadPlanSP step_bp_plan_sp;
691 step_bp_plan->SetPrivate (true);
692
Chris Lattner24943d22010-06-08 16:52:24 +0000693 if (GetCurrentPlan()->RunState() != eStateStepping)
694 {
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000695 step_bp_plan->SetAutoContinue(true);
Chris Lattner24943d22010-06-08 16:52:24 +0000696 }
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000697 step_bp_plan_sp.reset (step_bp_plan);
Chris Lattner24943d22010-06-08 16:52:24 +0000698 QueueThreadPlan (step_bp_plan_sp, false);
699 }
700 }
701 }
702 }
703}
704
705bool
706Thread::WillResume (StateType resume_state)
707{
708 // At this point clear the completed plan stack.
709 m_completed_plan_stack.clear();
710 m_discarded_plan_stack.clear();
711
712 // If this thread stopped with a signal, work out what its resume state should
713 // be. Note if the thread resume state is already set, then don't override it,
714 // the user must have asked us to resume with some other signal.
715
716 if (GetResumeSignal() == LLDB_INVALID_SIGNAL_NUMBER)
717 {
718 Thread::StopInfo stop_info;
719 GetRawStopReason(&stop_info);
720
721 StopReason reason = stop_info.GetStopReason();
722 if (reason == eStopReasonSignal)
723 {
724 UnixSignals &signals = GetProcess().GetUnixSignals();
725 int32_t signo = stop_info.GetSignal();
726 if (!signals.GetShouldSuppress(signo))
727 {
728 SetResumeSignal(signo);
729 }
730 }
731 }
732
733 // Tell all the plans that we are about to resume in case they need to clear any state.
734 // We distinguish between the plan on the top of the stack and the lower
735 // plans in case a plan needs to do any special business before it runs.
736
737 ThreadPlan *plan_ptr = GetCurrentPlan();
738 plan_ptr->WillResume(resume_state, true);
739
740 while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
741 {
742 plan_ptr->WillResume (resume_state, false);
743 }
744 return true;
745}
746
747void
748Thread::DidResume ()
749{
750 SetResumeSignal (LLDB_INVALID_SIGNAL_NUMBER);
751}
752
753bool
754Thread::ShouldStop (Event* event_ptr)
755{
756 ThreadPlan *current_plan = GetCurrentPlan();
757 bool should_stop = true;
758
759 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
760 if (log)
761 {
762 StreamString s;
763 DumpThreadPlans(&s);
764 log->PutCString (s.GetData());
765 }
766
767 if (current_plan->PlanExplainsStop())
768 {
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000769 bool over_ride_stop = current_plan->ShouldAutoContinue(event_ptr);
Chris Lattner24943d22010-06-08 16:52:24 +0000770 while (1)
771 {
772 should_stop = current_plan->ShouldStop(event_ptr);
773 if (current_plan->MischiefManaged())
774 {
775 if (should_stop)
776 current_plan->WillStop();
777
778 // If a Master Plan wants to stop, and wants to stick on the stack, we let it.
779 // Otherwise, see if the plan's parent wants to stop.
780
781 if (should_stop && current_plan->IsMasterPlan() && !current_plan->OkayToDiscard())
782 {
783 PopPlan();
784 break;
785 }
786 else
787 {
788
789 PopPlan();
790
791 current_plan = GetCurrentPlan();
792 if (current_plan == NULL)
793 {
794 break;
795 }
796 }
797
798 }
799 else
800 {
801 break;
802 }
803 }
Jim Ingham5a47e8b2010-06-19 04:45:32 +0000804 if (over_ride_stop)
805 should_stop = false;
Chris Lattner24943d22010-06-08 16:52:24 +0000806 }
807 else
808 {
809 // If the current plan doesn't explain the stop, then, find one that
810 // does and let it handle the situation.
811 ThreadPlan *plan_ptr = current_plan;
812 while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL)
813 {
814 if (plan_ptr->PlanExplainsStop())
815 {
816 should_stop = plan_ptr->ShouldStop (event_ptr);
817 break;
818 }
819
820 }
821 }
822
823 return should_stop;
824}
825
826Vote
827Thread::ShouldReportStop (Event* event_ptr)
828{
829 StateType thread_state = GetResumeState ();
830 if (thread_state == eStateSuspended
831 || thread_state == eStateInvalid)
832 return eVoteNoOpinion;
833
834 if (m_completed_plan_stack.size() > 0)
835 {
836 // Don't use GetCompletedPlan here, since that suppresses private plans.
837 return m_completed_plan_stack.back()->ShouldReportStop (event_ptr);
838 }
839 else
840 return GetCurrentPlan()->ShouldReportStop (event_ptr);
841}
842
843Vote
844Thread::ShouldReportRun (Event* event_ptr)
845{
846 StateType thread_state = GetResumeState ();
847 if (thread_state == eStateSuspended
848 || thread_state == eStateInvalid)
849 return eVoteNoOpinion;
850
851 if (m_completed_plan_stack.size() > 0)
852 {
853 // Don't use GetCompletedPlan here, since that suppresses private plans.
854 return m_completed_plan_stack.back()->ShouldReportRun (event_ptr);
855 }
856 else
857 return GetCurrentPlan()->ShouldReportRun (event_ptr);
858}
859
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000860bool
861Thread::MatchesSpec (const ThreadSpec *spec)
862{
863 if (spec == NULL)
864 return true;
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000865
Jim Ingham649492b2010-06-18 01:00:58 +0000866 return spec->ThreadPassesBasicTests(this);
Jim Ingham3c7b5b92010-06-16 02:00:15 +0000867}
868
Chris Lattner24943d22010-06-08 16:52:24 +0000869void
870Thread::PushPlan (ThreadPlanSP &thread_plan_sp)
871{
872 if (thread_plan_sp)
873 {
874 if (thread_plan_sp->IsImmediate())
875 m_immediate_plan_stack.push_back (thread_plan_sp);
876 else
877 m_plan_stack.push_back (thread_plan_sp);
878
879 thread_plan_sp->DidPush();
880
881 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
882 if (log)
883 {
884 StreamString s;
885 thread_plan_sp->GetDescription (&s, lldb::eDescriptionLevelFull);
886 log->Printf("Pushing plan: \"%s\" for thread: %d immediate: %s.",
887 s.GetData(),
888 thread_plan_sp->GetThread().GetID(),
889 thread_plan_sp->IsImmediate() ? "true" : "false");
890 }
891 }
892}
893
894void
895Thread::PopPlan ()
896{
897 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
898
899 if (!m_immediate_plan_stack.empty())
900 {
901 ThreadPlanSP &plan = m_immediate_plan_stack.back();
902 if (log)
903 {
904 log->Printf("Popping plan: \"%s\" for thread: %d immediate: true.", plan->GetName(), plan->GetThread().GetID());
905 }
906 plan->WillPop();
907 m_immediate_plan_stack.pop_back();
908 }
909 else if (m_plan_stack.empty())
910 return;
911 else
912 {
913 ThreadPlanSP &plan = m_plan_stack.back();
914 if (log)
915 {
916 log->Printf("Popping plan: \"%s\" for thread: 0x%x immediate: false.", plan->GetName(), plan->GetThread().GetID());
917 }
918 m_completed_plan_stack.push_back (plan);
919 plan->WillPop();
920 m_plan_stack.pop_back();
921 }
922}
923
924void
925Thread::DiscardPlan ()
926{
927 if (m_plan_stack.size() > 1)
928 {
929 ThreadPlanSP &plan = m_plan_stack.back();
930 m_discarded_plan_stack.push_back (plan);
931 plan->WillPop();
932 m_plan_stack.pop_back();
933 }
934}
935
936ThreadPlan *
937Thread::GetCurrentPlan ()
938{
939 if (!m_immediate_plan_stack.empty())
940 return m_immediate_plan_stack.back().get();
941 else if (m_plan_stack.empty())
942 return NULL;
943 else
944 return m_plan_stack.back().get();
945}
946
947ThreadPlanSP
948Thread::GetCompletedPlan ()
949{
950 ThreadPlanSP empty_plan_sp;
951 if (!m_completed_plan_stack.empty())
952 {
953 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
954 {
955 ThreadPlanSP completed_plan_sp;
956 completed_plan_sp = m_completed_plan_stack[i];
957 if (!completed_plan_sp->GetPrivate ())
958 return completed_plan_sp;
959 }
960 }
961 return empty_plan_sp;
962}
963
964bool
965Thread::IsThreadPlanDone (ThreadPlan *plan)
966{
967 ThreadPlanSP empty_plan_sp;
968 if (!m_completed_plan_stack.empty())
969 {
970 for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--)
971 {
972 if (m_completed_plan_stack[i].get() == plan)
973 return true;
974 }
975 }
976 return false;
977}
978
979bool
980Thread::WasThreadPlanDiscarded (ThreadPlan *plan)
981{
982 ThreadPlanSP empty_plan_sp;
983 if (!m_discarded_plan_stack.empty())
984 {
985 for (int i = m_discarded_plan_stack.size() - 1; i >= 0; i--)
986 {
987 if (m_discarded_plan_stack[i].get() == plan)
988 return true;
989 }
990 }
991 return false;
992}
993
994ThreadPlan *
995Thread::GetPreviousPlan (ThreadPlan *current_plan)
996{
997 if (current_plan == NULL)
998 return NULL;
999
1000 int stack_size = m_completed_plan_stack.size();
1001 for (int i = stack_size - 1; i > 0; i--)
1002 {
1003 if (current_plan == m_completed_plan_stack[i].get())
1004 return m_completed_plan_stack[i-1].get();
1005 }
1006
1007 if (stack_size > 0 && m_completed_plan_stack[0].get() == current_plan)
1008 {
1009 if (m_immediate_plan_stack.size() > 0)
1010 return m_immediate_plan_stack.back().get();
1011 else if (m_plan_stack.size() > 0)
1012 return m_plan_stack.back().get();
1013 else
1014 return NULL;
1015 }
1016
1017 stack_size = m_immediate_plan_stack.size();
1018 for (int i = stack_size - 1; i > 0; i--)
1019 {
1020 if (current_plan == m_immediate_plan_stack[i].get())
1021 return m_immediate_plan_stack[i-1].get();
1022 }
1023 if (stack_size > 0 && m_immediate_plan_stack[0].get() == current_plan)
1024 {
1025 if (m_plan_stack.size() > 0)
1026 return m_plan_stack.back().get();
1027 else
1028 return NULL;
1029 }
1030
1031 stack_size = m_plan_stack.size();
1032 for (int i = stack_size - 1; i > 0; i--)
1033 {
1034 if (current_plan == m_plan_stack[i].get())
1035 return m_plan_stack[i-1].get();
1036 }
1037 return NULL;
1038}
1039
1040void
1041Thread::QueueThreadPlan (ThreadPlanSP &thread_plan_sp, bool abort_other_plans)
1042{
1043 if (abort_other_plans)
1044 DiscardThreadPlans(true);
1045
1046 PushPlan (thread_plan_sp);
1047}
1048
1049void
1050Thread::DiscardThreadPlans(bool force)
1051{
1052 // FIXME: It is not always safe to just discard plans. Some, like the step over
1053 // breakpoint trap can't be discarded in general (though you can if you plan to
1054 // force a return from a function, for instance.
1055 // For now I'm just not clearing immediate plans, but I need a way for plans to
1056 // say they really need to be kept on, and then a way to override that. Humm...
1057
1058 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
1059 if (log)
1060 {
1061 log->Printf("Discarding thread plans for thread: 0x%x: force %d.", GetID(), force);
1062 }
1063
1064 if (force)
1065 {
1066 int stack_size = m_plan_stack.size();
1067 for (int i = stack_size - 1; i > 0; i--)
1068 {
1069 DiscardPlan();
1070 }
1071 return;
1072 }
1073
1074 while (1)
1075 {
1076
1077 int master_plan_idx;
1078 bool discard;
1079
1080 // Find the first master plan, see if it wants discarding, and if yes discard up to it.
1081 for (master_plan_idx = m_plan_stack.size() - 1; master_plan_idx >= 0; master_plan_idx--)
1082 {
1083 if (m_plan_stack[master_plan_idx]->IsMasterPlan())
1084 {
1085 discard = m_plan_stack[master_plan_idx]->OkayToDiscard();
1086 break;
1087 }
1088 }
1089
1090 if (discard)
1091 {
1092 // First pop all the dependent plans:
1093 for (int i = m_plan_stack.size() - 1; i > master_plan_idx; i--)
1094 {
1095
1096 // FIXME: Do we need a finalize here, or is the rule that "PrepareForStop"
1097 // for the plan leaves it in a state that it is safe to pop the plan
1098 // with no more notice?
1099 DiscardPlan();
1100 }
1101
1102 // Now discard the master plan itself.
1103 // The bottom-most plan never gets discarded. "OkayToDiscard" for it means
1104 // discard it's dependent plans, but not it...
1105 if (master_plan_idx > 0)
1106 {
1107 DiscardPlan();
1108 }
1109 }
1110 else
1111 {
1112 // If the master plan doesn't want to get discarded, then we're done.
1113 break;
1114 }
1115
1116 }
1117 // FIXME: What should we do about the immediate plans?
1118}
1119
1120ThreadPlan *
1121Thread::QueueFundamentalPlan (bool abort_other_plans)
1122{
1123 ThreadPlanSP thread_plan_sp (new ThreadPlanBase(*this));
1124 QueueThreadPlan (thread_plan_sp, abort_other_plans);
1125 return thread_plan_sp.get();
1126}
1127
1128ThreadPlan *
1129Thread::QueueThreadPlanForStepSingleInstruction (bool step_over, bool abort_other_plans, bool stop_other_threads)
1130{
1131 ThreadPlanSP thread_plan_sp (new ThreadPlanStepInstruction (*this, step_over, stop_other_threads, eVoteNoOpinion, eVoteNoOpinion));
1132 QueueThreadPlan (thread_plan_sp, abort_other_plans);
1133 return thread_plan_sp.get();
1134}
1135
1136ThreadPlan *
Greg Clayton8f5fd6b2010-06-12 18:59:55 +00001137Thread::QueueThreadPlanForStepRange
1138(
1139 bool abort_other_plans,
1140 StepType type,
1141 const AddressRange &range,
1142 const SymbolContext &addr_context,
1143 lldb::RunMode stop_other_threads,
1144 bool avoid_code_without_debug_info
1145)
Chris Lattner24943d22010-06-08 16:52:24 +00001146{
1147 ThreadPlanSP thread_plan_sp;
1148 if (type == eStepTypeInto)
Greg Clayton8f5fd6b2010-06-12 18:59:55 +00001149 {
1150 ThreadPlanStepInRange *plan = new ThreadPlanStepInRange (*this, range, addr_context, stop_other_threads);
1151 if (avoid_code_without_debug_info)
1152 plan->GetFlags().Set (ThreadPlanShouldStopHere::eAvoidNoDebug);
1153 else
1154 plan->GetFlags().Clear (ThreadPlanShouldStopHere::eAvoidNoDebug);
1155 thread_plan_sp.reset (plan);
1156 }
Chris Lattner24943d22010-06-08 16:52:24 +00001157 else
1158 thread_plan_sp.reset (new ThreadPlanStepOverRange (*this, range, addr_context, stop_other_threads));
1159
1160 QueueThreadPlan (thread_plan_sp, abort_other_plans);
1161 return thread_plan_sp.get();
1162}
1163
1164
1165ThreadPlan *
1166Thread::QueueThreadPlanForStepOverBreakpointPlan (bool abort_other_plans)
1167{
1168 ThreadPlanSP thread_plan_sp (new ThreadPlanStepOverBreakpoint (*this));
1169 QueueThreadPlan (thread_plan_sp, abort_other_plans);
1170 return thread_plan_sp.get();
1171}
1172
1173ThreadPlan *
1174Thread::QueueThreadPlanForStepOut (bool abort_other_plans, SymbolContext *addr_context, bool first_insn,
1175 bool stop_other_threads, Vote stop_vote, Vote run_vote)
1176{
1177 ThreadPlanSP thread_plan_sp (new ThreadPlanStepOut (*this, addr_context, first_insn, stop_other_threads, stop_vote, run_vote));
1178 QueueThreadPlan (thread_plan_sp, abort_other_plans);
1179 return thread_plan_sp.get();
1180}
1181
1182ThreadPlan *
1183Thread::QueueThreadPlanForStepThrough (bool abort_other_plans, bool stop_other_threads)
1184{
1185 ThreadPlanSP thread_plan_sp(GetProcess().GetDynamicLoader()->GetStepThroughTrampolinePlan (*this, stop_other_threads));
1186 if (thread_plan_sp.get() == NULL)
1187 {
1188 thread_plan_sp.reset(new ThreadPlanStepThrough (*this, stop_other_threads));
1189 if (thread_plan_sp && !thread_plan_sp->ValidatePlan (NULL))
Greg Claytonf8e98a62010-07-23 15:37:46 +00001190 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001191 }
1192 QueueThreadPlan (thread_plan_sp, abort_other_plans);
1193 return thread_plan_sp.get();
1194}
1195
1196ThreadPlan *
Chris Lattner24943d22010-06-08 16:52:24 +00001197Thread::QueueThreadPlanForCallFunction (bool abort_other_plans,
1198 Address& function,
1199 lldb::addr_t arg,
1200 bool stop_other_threads,
1201 bool discard_on_error)
1202{
1203 ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, arg, stop_other_threads, discard_on_error));
1204 QueueThreadPlan (thread_plan_sp, abort_other_plans);
1205 return thread_plan_sp.get();
1206}
1207
1208ThreadPlan *
1209Thread::QueueThreadPlanForCallFunction (bool abort_other_plans,
1210 Address& function,
1211 ValueList &args,
1212 bool stop_other_threads,
1213 bool discard_on_error)
1214{
1215 ThreadPlanSP thread_plan_sp (new ThreadPlanCallFunction (*this, function, args, stop_other_threads, discard_on_error));
1216 QueueThreadPlan (thread_plan_sp, abort_other_plans);
1217 return thread_plan_sp.get();
1218}
1219
1220ThreadPlan *
1221Thread::QueueThreadPlanForRunToAddress (bool abort_other_plans,
1222 Address &target_addr,
1223 bool stop_other_threads)
1224{
1225 ThreadPlanSP thread_plan_sp (new ThreadPlanRunToAddress (*this, target_addr, stop_other_threads));
1226 QueueThreadPlan (thread_plan_sp, abort_other_plans);
1227 return thread_plan_sp.get();
1228}
1229
1230ThreadPlan *
1231Thread::QueueThreadPlanForStepUntil (bool abort_other_plans,
1232 lldb::addr_t *address_list,
1233 size_t num_addresses,
1234 bool stop_other_threads)
1235{
1236 ThreadPlanSP thread_plan_sp (new ThreadPlanStepUntil (*this, address_list, num_addresses, stop_other_threads));
1237 QueueThreadPlan (thread_plan_sp, abort_other_plans);
1238 return thread_plan_sp.get();
1239
1240}
1241
1242uint32_t
1243Thread::GetIndexID () const
1244{
1245 return m_index_id;
1246}
1247
1248void
1249Thread::DumpThreadPlans (lldb_private::Stream *s) const
1250{
1251 uint32_t stack_size = m_plan_stack.size();
Jim Ingham3c7b5b92010-06-16 02:00:15 +00001252 s->Printf ("Plan Stack for thread #%u: tid = 0x%4.4x - %d elements.\n", GetIndexID(), GetID(), stack_size);
Chris Lattner24943d22010-06-08 16:52:24 +00001253 for (int i = stack_size - 1; i > 0; i--)
1254 {
1255 s->Printf ("Element %d: ", i);
1256 s->IndentMore();
1257 m_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
1258 s->IndentLess();
1259 s->EOL();
1260 }
1261
1262 stack_size = m_immediate_plan_stack.size();
1263 s->Printf ("Immediate Plan Stack: %d elements.\n", stack_size);
1264 for (int i = stack_size - 1; i > 0; i--)
1265 {
1266 s->Printf ("Element %d: ", i);
1267 s->IndentMore();
1268 m_immediate_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
1269 s->IndentLess();
1270 s->EOL();
1271 }
1272
1273 stack_size = m_completed_plan_stack.size();
1274 s->Printf ("Completed Plan Stack: %d elements.\n", stack_size);
1275 for (int i = stack_size - 1; i > 0; i--)
1276 {
1277 s->Printf ("Element %d: ", i);
1278 s->IndentMore();
1279 m_completed_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
1280 s->IndentLess();
1281 s->EOL();
1282 }
1283
1284 stack_size = m_discarded_plan_stack.size();
1285 s->Printf ("Discarded Plan Stack: %d elements.\n", stack_size);
1286 for (int i = stack_size - 1; i > 0; i--)
1287 {
1288 s->Printf ("Element %d: ", i);
1289 s->IndentMore();
1290 m_discarded_plan_stack[i]->GetDescription (s, eDescriptionLevelFull);
1291 s->IndentLess();
1292 s->EOL();
1293 }
1294
1295}
1296
1297Target *
1298Thread::CalculateTarget ()
1299{
1300 return m_process.CalculateTarget();
1301}
1302
1303Process *
1304Thread::CalculateProcess ()
1305{
1306 return &m_process;
1307}
1308
1309Thread *
1310Thread::CalculateThread ()
1311{
1312 return this;
1313}
1314
1315StackFrame *
1316Thread::CalculateStackFrame ()
1317{
1318 return NULL;
1319}
1320
1321void
1322Thread::Calculate (ExecutionContext &exe_ctx)
1323{
1324 m_process.Calculate (exe_ctx);
1325 exe_ctx.thread = this;
1326 exe_ctx.frame = NULL;
1327}
1328
1329lldb::StackFrameSP
1330Thread::GetCurrentFrame ()
1331{
1332 return GetStackFrameAtIndex (m_frames.GetCurrentFrameIndex());
1333}
1334
1335uint32_t
1336Thread::SetCurrentFrame (lldb_private::StackFrame *frame)
1337{
1338 return m_frames.SetCurrentFrame(frame);
1339}
1340
1341void
1342Thread::SetCurrentFrameByIndex (uint32_t frame_idx)
1343{
1344 m_frames.SetCurrentFrameByIndex(frame_idx);
1345}
1346
1347void
1348Thread::DumpInfo
1349(
1350 Stream &strm,
1351 bool show_stop_reason,
1352 bool show_name,
1353 bool show_queue,
1354 uint32_t frame_idx
1355)
1356{
1357 strm.Printf("thread #%u: tid = 0x%4.4x", GetIndexID(), GetID());
1358
1359 if (frame_idx != LLDB_INVALID_INDEX32)
1360 {
1361 StackFrameSP frame_sp(GetStackFrameAtIndex (frame_idx));
1362 if (frame_sp)
1363 {
1364 strm.PutCString(", ");
1365 frame_sp->Dump (&strm, false);
1366 }
1367 }
1368
1369 if (show_stop_reason)
1370 {
1371 Thread::StopInfo thread_stop_info;
1372 if (GetStopInfo(&thread_stop_info))
1373 {
1374 if (thread_stop_info.GetStopReason() != eStopReasonNone)
1375 {
1376 strm.PutCString(", stop reason = ");
1377 thread_stop_info.Dump(&strm);
1378 }
1379 }
1380 }
1381
1382 if (show_name)
1383 {
1384 const char *name = GetName();
1385 if (name && name[0])
1386 strm.Printf(", name = %s", name);
1387 }
1388
1389 if (show_queue)
1390 {
1391 const char *queue = GetQueueName();
1392 if (queue && queue[0])
1393 strm.Printf(", queue = %s", queue);
1394 }
1395}
1396
1397lldb::ThreadSP
1398Thread::GetSP ()
1399{
1400 return m_process.GetThreadList().GetThreadSPForThreadPtr(this);
1401}