blob: 0c3c0e22caaa1c323e105bfaa6bb8d0c48ff809c [file] [log] [blame]
Jim Inghamd1686902010-10-14 23:45:03 +00001//===-- ThreadPlanTestCondition.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/Target/ThreadPlanTestCondition.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16
17#include "lldb/lldb-private-log.h"
Jim Inghama8a68712011-06-01 23:52:47 +000018#include "lldb/Breakpoint/Breakpoint.h"
Jim Inghamd1686902010-10-14 23:45:03 +000019#include "lldb/Breakpoint/BreakpointLocation.h"
20#include "lldb/Core/Log.h"
21#include "lldb/Core/Stream.h"
22#include "lldb/Core/Value.h"
23#include "lldb/Core/ValueObject.h"
24#include "lldb/Symbol/Function.h"
25#include "lldb/Symbol/Symbol.h"
26#include "lldb/Target/Process.h"
27#include "lldb/Target/RegisterContext.h"
28#include "lldb/Target/StopInfo.h"
29#include "lldb/Target/Thread.h"
30
31using namespace lldb;
32using namespace lldb_private;
33
34
35//----------------------------------------------------------------------
36// ThreadPlanTestCondition: Step through a stack range, either stepping over or into
37// based on the value of \a type.
38//----------------------------------------------------------------------
39
40ThreadPlanTestCondition::ThreadPlanTestCondition (
41 Thread& thread,
42 ExecutionContext &exe_ctx,
43 ClangUserExpression *expression,
44 lldb::BreakpointLocationSP break_loc_sp,
45 bool stop_others) :
46 ThreadPlan (ThreadPlan::eKindTestCondition, "test condition", thread, eVoteNoOpinion, eVoteNoOpinion),
Jim Inghamd1686902010-10-14 23:45:03 +000047 m_expression (expression),
Stephen Wilsondbeb3e12011-04-11 19:41:40 +000048 m_exe_ctx (exe_ctx),
Jim Inghamd1686902010-10-14 23:45:03 +000049 m_break_loc_sp (break_loc_sp),
50 m_did_stop (false),
51 m_stop_others (stop_others)
52{
53}
54
55ThreadPlanTestCondition::~ThreadPlanTestCondition ()
56{
57}
58
59bool
60ThreadPlanTestCondition::ValidatePlan (Stream *error)
61{
62 return true;
63}
64
65void
66ThreadPlanTestCondition::GetDescription (Stream *s, lldb::DescriptionLevel level)
67{
Jim Ingham360f53f2010-11-30 02:22:11 +000068 if (m_expression)
69 s->Printf("Thread plan to test condition: \"%s\".", m_expression->GetUserText());
70 else
71 s->Printf("Thread plan to test unspecified condition.");
Jim Inghamd1686902010-10-14 23:45:03 +000072}
73
74bool
75ThreadPlanTestCondition::ShouldStop (Event *event_ptr)
76{
Greg Claytone005f2c2010-11-06 01:53:30 +000077 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Jim Inghamd1686902010-10-14 23:45:03 +000078 if (m_thread.IsThreadPlanDone(m_expression_plan_sp.get()))
79 {
Greg Clayton427f2902010-12-14 02:59:59 +000080 lldb::ClangExpressionVariableSP expr_result;
Jim Inghamd1686902010-10-14 23:45:03 +000081 StreamString error_stream;
82 m_expression->FinalizeJITExecution(error_stream, m_exe_ctx, expr_result);
83
Greg Clayton427f2902010-12-14 02:59:59 +000084 ValueObjectSP result_sp (expr_result->GetValueObject());
Jim Inghamd1686902010-10-14 23:45:03 +000085 if (result_sp)
86 {
87 // FIXME: This is not the right answer, we should have a "GetValueAsBoolean..."
Jim Inghame41494a2011-04-16 00:01:13 +000088 Scalar scalar_value;
89 if (result_sp->ResolveValue (scalar_value))
Jim Inghamd1686902010-10-14 23:45:03 +000090 {
91 if (scalar_value.ULongLong(1) == 0)
92 m_did_stop = false;
93 else
94 m_did_stop = true;
95 }
96 if (log)
97 log->Printf("Condition successfully evaluated, result is %s.\n", m_did_stop ? "true" : "false");
98 }
99 else
100 {
101 if (log)
102 log->Printf("Failed to get a result from the expression, error: \"%s\"\n", error_stream.GetData());
103 m_did_stop = true;
104 }
105 }
106 else if (m_exe_ctx.thread->WasThreadPlanDiscarded (m_expression_plan_sp.get()))
107 {
108 if (log)
109 log->Printf("ExecuteExpression thread plan was discarded.\n");
110 m_did_stop = true;
111 }
112
Jim Inghama8a68712011-06-01 23:52:47 +0000113 // One tricky bit, somebody might have disabled/deleted the breakpoint while we were running this condition, if so we
114 // should just continue. If the breakpoint gets disabled, then its "site" will be null'ed out, so we can't report
115 // this as a breakpoint event any more, since we can't reconstruct it's site. So just pass the event on.
116 if (!m_break_loc_sp->IsEnabled())
Jim Inghamd1686902010-10-14 23:45:03 +0000117 {
Jim Inghama8a68712011-06-01 23:52:47 +0000118 m_did_stop = false;
Jim Inghamd1686902010-10-14 23:45:03 +0000119 }
120 else
121 {
Jim Inghama8a68712011-06-01 23:52:47 +0000122 // Now we have to change the event to a breakpoint event and mark it up appropriately:
123 Process::ProcessEventData *new_data = new Process::ProcessEventData (m_thread.GetProcess().GetSP(), eStateStopped);
124 event_ptr->SetData(new_data);
125 event_ptr->SetType(Process::eBroadcastBitStateChanged);
126 SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID (m_thread,
127 m_break_loc_sp->GetBreakpointSite()->GetID(),
128 m_did_stop));
129 if (m_did_stop)
130 {
131 Process::ProcessEventData::SetRestartedInEvent (event_ptr, false);
132 }
133 else
134 {
135 Process::ProcessEventData::SetRestartedInEvent (event_ptr, true);
136 }
Jim Inghamd1686902010-10-14 23:45:03 +0000137 }
Jim Inghamd1686902010-10-14 23:45:03 +0000138 SetPlanComplete();
139 return m_did_stop;
140}
141
142bool
143ThreadPlanTestCondition::PlanExplainsStop ()
144{
145 // We explain all stops, and we just can the execution and return true if we stop for any
146 // reason other than that our expression execution is done.
147 return true;
148}
149
150Vote
151ThreadPlanTestCondition::ShouldReportStop (Event *event_ptr)
152{
153 if (m_did_stop)
154 {
155 return eVoteYes;
156 }
157 else
158 {
159 return eVoteNo;
160 }
161}
162
163void
164ThreadPlanTestCondition::DidPush()
165{
166 StreamString error_stream;
167 m_expression_plan_sp.reset(m_expression->GetThreadPlanToExecuteJITExpression (error_stream, m_exe_ctx));
168 m_thread.QueueThreadPlan (m_expression_plan_sp, false);
169}
170
171bool
172ThreadPlanTestCondition::StopOthers ()
173{
174 return m_stop_others;
175}
176
177bool
178ThreadPlanTestCondition::WillStop ()
179{
180 return true;
181}
182
183StateType
Jim Ingham745ac7a2010-11-11 19:26:09 +0000184ThreadPlanTestCondition::GetPlanRunState ()
Jim Inghamd1686902010-10-14 23:45:03 +0000185{
186 return eStateRunning;
187}
188
189bool
190ThreadPlanTestCondition::MischiefManaged ()
191{
192 // If we get a stop we're done, we don't puase in the middle of
193 // condition execution.
194 return true;
195}