blob: a37a4079ff116ea74290ee10f6e7b399a36e51b1 [file] [log] [blame]
Greg Claytonf4b47e12010-08-04 01:40:35 +00001//===-- StopInfo.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
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Greg Claytonf4b47e12010-08-04 01:40:35 +000012#include "lldb/Target/StopInfo.h"
13
14// C Includes
15// C++ Includes
16#include <string>
17
18// Other libraries and framework includes
19// Project includes
20#include "lldb/Core/Log.h"
Greg Clayton4e78f602010-11-18 18:52:36 +000021#include "lldb/Breakpoint/Breakpoint.h"
Greg Claytonf4b47e12010-08-04 01:40:35 +000022#include "lldb/Breakpoint/BreakpointLocation.h"
23#include "lldb/Breakpoint/StoppointCallbackContext.h"
Johnny Chen01a67862011-10-14 00:42:25 +000024#include "lldb/Breakpoint/Watchpoint.h"
Jim Ingham4b536182011-08-09 02:12:22 +000025#include "lldb/Core/Debugger.h"
Greg Claytonf4b47e12010-08-04 01:40:35 +000026#include "lldb/Core/StreamString.h"
Jim Ingham4b536182011-08-09 02:12:22 +000027#include "lldb/Expression/ClangUserExpression.h"
28#include "lldb/Target/Target.h"
Greg Claytonf4b47e12010-08-04 01:40:35 +000029#include "lldb/Target/Thread.h"
30#include "lldb/Target/ThreadPlan.h"
31#include "lldb/Target/Process.h"
32#include "lldb/Target/UnixSignals.h"
33
34using namespace lldb;
35using namespace lldb_private;
36
37StopInfo::StopInfo (Thread &thread, uint64_t value) :
Greg Clayton46c2b6e2013-04-29 23:30:46 +000038 m_thread_wp (thread.shared_from_this()),
Greg Clayton1ac04c32012-02-21 00:09:25 +000039 m_stop_id (thread.GetProcess()->GetStopID()),
40 m_resume_id (thread.GetProcess()->GetResumeID()),
Jim Ingham0161b492013-02-09 01:29:05 +000041 m_value (value),
Jim Ingham221d51c2013-05-08 00:35:16 +000042 m_override_should_notify (eLazyBoolCalculate),
43 m_override_should_stop (eLazyBoolCalculate)
Greg Claytonf4b47e12010-08-04 01:40:35 +000044{
45}
46
47bool
48StopInfo::IsValid () const
49{
Greg Clayton46c2b6e2013-04-29 23:30:46 +000050 ThreadSP thread_sp (m_thread_wp.lock());
51 if (thread_sp)
52 return thread_sp->GetProcess()->GetStopID() == m_stop_id;
53 return false;
Greg Claytonf4b47e12010-08-04 01:40:35 +000054}
55
Jim Ingham77787032011-01-20 02:03:18 +000056void
57StopInfo::MakeStopInfoValid ()
58{
Greg Clayton46c2b6e2013-04-29 23:30:46 +000059 ThreadSP thread_sp (m_thread_wp.lock());
60 if (thread_sp)
61 {
62 m_stop_id = thread_sp->GetProcess()->GetStopID();
63 m_resume_id = thread_sp->GetProcess()->GetResumeID();
64 }
Jim Ingham77787032011-01-20 02:03:18 +000065}
66
Jim Ingham0faa43f2011-11-08 03:00:11 +000067bool
68StopInfo::HasTargetRunSinceMe ()
Jim Ingham4b536182011-08-09 02:12:22 +000069{
Greg Clayton46c2b6e2013-04-29 23:30:46 +000070 ThreadSP thread_sp (m_thread_wp.lock());
71
72 if (thread_sp)
Jim Ingham0faa43f2011-11-08 03:00:11 +000073 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +000074 lldb::StateType ret_type = thread_sp->GetProcess()->GetPrivateState();
75 if (ret_type == eStateRunning)
Jim Ingham0faa43f2011-11-08 03:00:11 +000076 {
77 return true;
78 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +000079 else if (ret_type == eStateStopped)
80 {
81 // This is a little tricky. We want to count "run and stopped again before you could
82 // ask this question as a "TRUE" answer to HasTargetRunSinceMe. But we don't want to
83 // include any running of the target done for expressions. So we track both resumes,
84 // and resumes caused by expressions, and check if there are any resumes NOT caused
85 // by expressions.
86
87 uint32_t curr_resume_id = thread_sp->GetProcess()->GetResumeID();
88 uint32_t last_user_expression_id = thread_sp->GetProcess()->GetLastUserExpressionResumeID ();
89 if (curr_resume_id == m_resume_id)
90 {
91 return false;
92 }
93 else if (curr_resume_id > last_user_expression_id)
94 {
95 return true;
96 }
97 }
Jim Ingham0faa43f2011-11-08 03:00:11 +000098 }
99 return false;
Jim Ingham4b536182011-08-09 02:12:22 +0000100}
101
Greg Claytonf4b47e12010-08-04 01:40:35 +0000102//----------------------------------------------------------------------
103// StopInfoBreakpoint
104//----------------------------------------------------------------------
105
Jim Ingham4b536182011-08-09 02:12:22 +0000106namespace lldb_private
107{
Greg Claytonf4b47e12010-08-04 01:40:35 +0000108class StopInfoBreakpoint : public StopInfo
109{
110public:
Greg Claytonf4b47e12010-08-04 01:40:35 +0000111 StopInfoBreakpoint (Thread &thread, break_id_t break_id) :
112 StopInfo (thread, break_id),
113 m_description(),
114 m_should_stop (false),
Jim Ingham0f16e732011-02-08 05:20:59 +0000115 m_should_stop_is_valid (false),
Jim Ingham52c7d202011-10-28 01:12:19 +0000116 m_should_perform_action (true),
Jim Inghamca36cd12012-10-05 19:16:31 +0000117 m_address (LLDB_INVALID_ADDRESS),
118 m_break_id(LLDB_INVALID_BREAK_ID),
119 m_was_one_shot (false)
Greg Claytonf4b47e12010-08-04 01:40:35 +0000120 {
Jim Inghamca36cd12012-10-05 19:16:31 +0000121 StoreBPInfo();
Greg Claytonf4b47e12010-08-04 01:40:35 +0000122 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000123
Jim Ingham36f3b362010-10-14 23:45:03 +0000124 StopInfoBreakpoint (Thread &thread, break_id_t break_id, bool should_stop) :
125 StopInfo (thread, break_id),
126 m_description(),
127 m_should_stop (should_stop),
Jim Ingham0f16e732011-02-08 05:20:59 +0000128 m_should_stop_is_valid (true),
Jim Ingham52c7d202011-10-28 01:12:19 +0000129 m_should_perform_action (true),
Jim Inghamca36cd12012-10-05 19:16:31 +0000130 m_address (LLDB_INVALID_ADDRESS),
131 m_break_id(LLDB_INVALID_BREAK_ID),
132 m_was_one_shot (false)
133 {
134 StoreBPInfo();
135 }
136
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000137 void
138 StoreBPInfo ()
Jim Ingham36f3b362010-10-14 23:45:03 +0000139 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000140 ThreadSP thread_sp (m_thread_wp.lock());
141 if (thread_sp)
Jim Ingham52c7d202011-10-28 01:12:19 +0000142 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000143 BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value));
144 if (bp_site_sp)
Jim Inghamca36cd12012-10-05 19:16:31 +0000145 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000146 if (bp_site_sp->GetNumberOfOwners() == 1)
Jim Inghamca36cd12012-10-05 19:16:31 +0000147 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000148 BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(0);
149 if (bp_loc_sp)
150 {
151 m_break_id = bp_loc_sp->GetBreakpoint().GetID();
152 m_was_one_shot = bp_loc_sp->GetBreakpoint().IsOneShot();
153 }
Jim Inghamca36cd12012-10-05 19:16:31 +0000154 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000155 m_address = bp_site_sp->GetLoadAddress();
Jim Inghamca36cd12012-10-05 19:16:31 +0000156 }
Jim Ingham52c7d202011-10-28 01:12:19 +0000157 }
Jim Ingham36f3b362010-10-14 23:45:03 +0000158 }
159
Greg Claytonf4b47e12010-08-04 01:40:35 +0000160 virtual ~StopInfoBreakpoint ()
161 {
162 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000163
Greg Claytonf4b47e12010-08-04 01:40:35 +0000164 virtual StopReason
165 GetStopReason () const
166 {
167 return eStopReasonBreakpoint;
168 }
169
170 virtual bool
Jim Ingham6d66ce62012-04-20 21:16:56 +0000171 ShouldStopSynchronous (Event *event_ptr)
Greg Claytonf4b47e12010-08-04 01:40:35 +0000172 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000173 ThreadSP thread_sp (m_thread_wp.lock());
174 if (thread_sp)
Greg Claytonf4b47e12010-08-04 01:40:35 +0000175 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000176 if (!m_should_stop_is_valid)
Greg Claytonf4b47e12010-08-04 01:40:35 +0000177 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000178 // Only check once if we should stop at a breakpoint
179 BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value));
180 if (bp_site_sp)
181 {
182 ExecutionContext exe_ctx (thread_sp->GetStackFrameAtIndex(0));
183 StoppointCallbackContext context (event_ptr, exe_ctx, true);
184 m_should_stop = bp_site_sp->ShouldStop (&context);
185 }
186 else
187 {
188 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
Greg Claytonf4b47e12010-08-04 01:40:35 +0000189
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000190 if (log)
191 log->Printf ("Process::%s could not find breakpoint site id: %" PRId64 "...", __FUNCTION__, m_value);
Greg Claytonf4b47e12010-08-04 01:40:35 +0000192
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000193 m_should_stop = true;
194 }
195 m_should_stop_is_valid = true;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000196 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000197 return m_should_stop;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000198 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000199 return false;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000200 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000201
Jim Inghamf57b4352012-11-10 02:08:14 +0000202 virtual bool
Jim Ingham221d51c2013-05-08 00:35:16 +0000203 DoShouldNotify (Event *event_ptr)
Jim Inghamf57b4352012-11-10 02:08:14 +0000204 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000205 ThreadSP thread_sp (m_thread_wp.lock());
206 if (thread_sp)
Jim Inghamf57b4352012-11-10 02:08:14 +0000207 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000208 BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value));
209 if (bp_site_sp)
Jim Inghamf57b4352012-11-10 02:08:14 +0000210 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000211 bool all_internal = true;
212
213 for (uint32_t i = 0; i < bp_site_sp->GetNumberOfOwners(); i++)
Jim Inghamf57b4352012-11-10 02:08:14 +0000214 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000215 if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal())
216 {
217 all_internal = false;
218 break;
219 }
Jim Inghamf57b4352012-11-10 02:08:14 +0000220 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000221 return all_internal == false;
Jim Inghamf57b4352012-11-10 02:08:14 +0000222 }
Jim Inghamf57b4352012-11-10 02:08:14 +0000223 }
224 return true;
225 }
226
227 virtual const char *
228 GetDescription ()
229 {
230 if (m_description.empty())
231 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000232 ThreadSP thread_sp (m_thread_wp.lock());
233 if (thread_sp)
Jim Inghamf57b4352012-11-10 02:08:14 +0000234 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000235 BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value));
236 if (bp_site_sp)
Jim Ingham29950772013-01-26 02:19:28 +0000237 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000238 StreamString strm;
239 // If we have just hit an internal breakpoint, and it has a kind description, print that instead of the
240 // full breakpoint printing:
241 if (bp_site_sp->IsInternal())
Jim Ingham29950772013-01-26 02:19:28 +0000242 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000243 size_t num_owners = bp_site_sp->GetNumberOfOwners();
244 for (size_t idx = 0; idx < num_owners; idx++)
Jim Ingham29950772013-01-26 02:19:28 +0000245 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000246 const char *kind = bp_site_sp->GetOwnerAtIndex(idx)->GetBreakpoint().GetBreakpointKind();
247 if (kind != NULL)
248 {
249 m_description.assign (kind);
250 return kind;
251 }
Jim Ingham29950772013-01-26 02:19:28 +0000252 }
253 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000254
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000255 strm.Printf("breakpoint ");
256 bp_site_sp->GetDescription(&strm, eDescriptionLevelBrief);
257 m_description.swap (strm.GetString());
Jim Ingham29950772013-01-26 02:19:28 +0000258 }
Jim Inghamf57b4352012-11-10 02:08:14 +0000259 else
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000260 {
261 StreamString strm;
262 if (m_break_id != LLDB_INVALID_BREAK_ID)
263 {
264 BreakpointSP break_sp = thread_sp->GetProcess()->GetTarget().GetBreakpointByID(m_break_id);
265 if (break_sp)
266 {
267 if (break_sp->IsInternal())
268 {
269 const char *kind = break_sp->GetBreakpointKind();
270 if (kind)
271 strm.Printf ("internal %s breakpoint(%d).", kind, m_break_id);
272 else
273 strm.Printf ("internal breakpoint(%d).", m_break_id);
274 }
275 else
276 {
277 strm.Printf ("breakpoint %d.", m_break_id);
278 }
279 }
280 else
281 {
282 if (m_was_one_shot)
283 strm.Printf ("one-shot breakpoint %d", m_break_id);
284 else
285 strm.Printf ("breakpoint %d which has been deleted.", m_break_id);
286 }
287 }
288 else if (m_address == LLDB_INVALID_ADDRESS)
289 strm.Printf("breakpoint site %" PRIi64 " which has been deleted - unknown address", m_value);
290 else
291 strm.Printf("breakpoint site %" PRIi64 " which has been deleted - was at 0x%" PRIx64, m_value, m_address);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000292
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000293 m_description.swap (strm.GetString());
294 }
Jim Inghamf57b4352012-11-10 02:08:14 +0000295 }
296 }
297 return m_description.c_str();
298 }
299
300protected:
Jim Ingham6d66ce62012-04-20 21:16:56 +0000301 bool
302 ShouldStop (Event *event_ptr)
303 {
304 // This just reports the work done by PerformAction or the synchronous stop. It should
305 // only ever get called after they have had a chance to run.
306 assert (m_should_stop_is_valid);
307 return m_should_stop;
308 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000309
Jim Ingham3ebcf7f2010-08-10 00:59:59 +0000310 virtual void
311 PerformAction (Event *event_ptr)
312 {
Jim Ingham0f16e732011-02-08 05:20:59 +0000313 if (!m_should_perform_action)
314 return;
315 m_should_perform_action = false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000316
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000317 ThreadSP thread_sp (m_thread_wp.lock());
318
319 if (thread_sp)
Jim Ingham5cb9a182013-03-28 00:13:30 +0000320 {
Jim Inghamcca89952014-08-05 01:58:14 +0000321 Log *log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS | LIBLLDB_LOG_STEP);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000322
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000323 if (!thread_sp->IsValid())
Jim Ingham3ebcf7f2010-08-10 00:59:59 +0000324 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000325 // This shouldn't ever happen, but just in case, don't do more harm.
Jason Molenda3f032ff2013-08-06 23:08:59 +0000326 if (log)
327 {
328 log->Printf ("PerformAction got called with an invalid thread.");
329 }
Jim Ingham79ea1d82011-12-09 04:17:31 +0000330 m_should_stop = true;
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000331 m_should_stop_is_valid = true;
332 return;
Jim Ingham79ea1d82011-12-09 04:17:31 +0000333 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000334
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000335 BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000336
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000337 if (bp_site_sp)
Jim Ingham79ea1d82011-12-09 04:17:31 +0000338 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000339 size_t num_owners = bp_site_sp->GetNumberOfOwners();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000340
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000341 if (num_owners == 0)
342 {
343 m_should_stop = true;
Jim Ingham184e9812013-01-15 02:47:48 +0000344 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000345 else
Jim Ingham4b536182011-08-09 02:12:22 +0000346 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000347 // We go through each location, and test first its condition. If the condition says to stop,
348 // then we run the callback for that location. If that callback says to stop as well, then
349 // we set m_should_stop to true; we are going to stop.
350 // But we still want to give all the breakpoints whose conditions say we are going to stop a
351 // chance to run their callbacks.
352 // Of course if any callback restarts the target by putting "continue" in the callback, then
353 // we're going to restart, without running the rest of the callbacks. And in this case we will
354 // end up not stopping even if another location said we should stop. But that's better than not
355 // running all the callbacks.
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000356
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000357 m_should_stop = false;
358
359 ExecutionContext exe_ctx (thread_sp->GetStackFrameAtIndex(0));
360 Process *process = exe_ctx.GetProcessPtr();
361 if (process->GetModIDRef().IsLastResumeForUserExpression())
Jim Ingham4b536182011-08-09 02:12:22 +0000362 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000363 // If we are in the middle of evaluating an expression, don't run asynchronous breakpoint commands or
364 // expressions. That could lead to infinite recursion if the command or condition re-calls the function
365 // with this breakpoint.
366 // TODO: We can keep a list of the breakpoints we've seen while running expressions in the nested
367 // PerformAction calls that can arise when the action runs a function that hits another breakpoint,
368 // and only stop running commands when we see the same breakpoint hit a second time.
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000369
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000370 m_should_stop_is_valid = true;
371 if (log)
372 log->Printf ("StopInfoBreakpoint::PerformAction - Hit a breakpoint while running an expression,"
373 " not running commands to avoid recursion.");
374 bool ignoring_breakpoints = process->GetIgnoreBreakpointsInExpressions();
375 if (ignoring_breakpoints)
Jim Ingham4b536182011-08-09 02:12:22 +0000376 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000377 m_should_stop = false;
378 // Internal breakpoints will always stop.
379 for (size_t j = 0; j < num_owners; j++)
380 {
381 lldb::BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(j);
382 if (bp_loc_sp->GetBreakpoint().IsInternal())
383 {
384 m_should_stop = true;
385 break;
386 }
387 }
Jim Ingham4b536182011-08-09 02:12:22 +0000388 }
Sean Callanan3dbf3462013-04-19 07:09:15 +0000389 else
390 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000391 m_should_stop = true;
392 }
393 if (log)
394 log->Printf ("StopInfoBreakpoint::PerformAction - in expression, continuing: %s.",
395 m_should_stop ? "true" : "false");
396 process->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf("Warning: hit breakpoint while "
397 "running function, skipping commands and conditions to prevent recursion.");
398 return;
399 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000400
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000401 StoppointCallbackContext context (event_ptr, exe_ctx, false);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000402
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000403 // Let's copy the breakpoint locations out of the site and store them in a local list. That way if
404 // one of the breakpoint actions changes the site, then we won't be operating on a bad list.
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000405
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000406 BreakpointLocationCollection site_locations;
407 for (size_t j = 0; j < num_owners; j++)
408 site_locations.Add(bp_site_sp->GetOwnerAtIndex(j));
409
410 for (size_t j = 0; j < num_owners; j++)
411 {
412 lldb::BreakpointLocationSP bp_loc_sp = site_locations.GetByIndex(j);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000413
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000414 // If another action disabled this breakpoint or its location, then don't run the actions.
415 if (!bp_loc_sp->IsEnabled() || !bp_loc_sp->GetBreakpoint().IsEnabled())
416 continue;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000417
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000418 // The breakpoint site may have many locations associated with it, not all of them valid for
419 // this thread. Skip the ones that aren't:
420 if (!bp_loc_sp->ValidForThisThread(thread_sp.get()))
Jim Inghama8b99ca2014-01-15 03:30:04 +0000421 {
422 if (log)
423 {
424 StreamString s;
425 bp_loc_sp->GetDescription(&s, eDescriptionLevelBrief);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000426 log->Printf ("Breakpoint %s hit on thread 0x%llx but it was not for this thread, continuing.",
427 s.GetData(),
428 static_cast<unsigned long long>(thread_sp->GetID()));
Jim Inghama8b99ca2014-01-15 03:30:04 +0000429 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000430 continue;
Jim Inghama8b99ca2014-01-15 03:30:04 +0000431 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000432 // First run the condition for the breakpoint. If that says we should stop, then we'll run
433 // the callback for the breakpoint. If the callback says we shouldn't stop that will win.
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000434
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000435 if (bp_loc_sp->GetConditionText() != NULL)
436 {
437 Error condition_error;
438 bool condition_says_stop = bp_loc_sp->ConditionSaysStop(exe_ctx, condition_error);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000439
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000440 if (!condition_error.Success())
441 {
442 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
443 StreamSP error_sp = debugger.GetAsyncErrorStream ();
444 error_sp->Printf ("Stopped due to an error evaluating condition of breakpoint ");
445 bp_loc_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief);
446 error_sp->Printf (": \"%s\"",
447 bp_loc_sp->GetConditionText());
448 error_sp->EOL();
449 const char *err_str = condition_error.AsCString("<Unknown Error>");
450 if (log)
451 log->Printf("Error evaluating condition: \"%s\"\n", err_str);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000452
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000453 error_sp->PutCString (err_str);
454 error_sp->EOL();
455 error_sp->Flush();
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000456 }
457 else
458 {
Jim Inghama8b99ca2014-01-15 03:30:04 +0000459 if (log)
460 {
461 StreamString s;
462 bp_loc_sp->GetDescription(&s, eDescriptionLevelBrief);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000463 log->Printf ("Condition evaluated for breakpoint %s on thread 0x%llx conditon_says_stop: %i.",
464 s.GetData(),
465 static_cast<unsigned long long>(thread_sp->GetID()),
466 condition_says_stop);
Jim Inghama8b99ca2014-01-15 03:30:04 +0000467 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000468 if (!condition_says_stop)
469 continue;
470 }
471 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000472
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000473 bool callback_says_stop;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000474
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000475 // FIXME: For now the callbacks have to run in async mode - the first time we restart we need
476 // to get out of there. So set it here.
477 // When we figure out how to nest breakpoint hits then this will change.
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000478
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000479 Debugger &debugger = thread_sp->CalculateTarget()->GetDebugger();
480 bool old_async = debugger.GetAsyncExecution();
481 debugger.SetAsyncExecution (true);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000482
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000483 callback_says_stop = bp_loc_sp->InvokeCallback (&context);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000484
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000485 debugger.SetAsyncExecution (old_async);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000486
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000487 if (callback_says_stop)
488 m_should_stop = true;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000489
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000490 // If we are going to stop for this breakpoint, then remove the breakpoint.
491 if (callback_says_stop && bp_loc_sp && bp_loc_sp->GetBreakpoint().IsOneShot())
492 {
493 thread_sp->GetProcess()->GetTarget().RemoveBreakpointByID (bp_loc_sp->GetBreakpoint().GetID());
494 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000495
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000496 // Also make sure that the callback hasn't continued the target.
497 // If it did, when we'll set m_should_start to false and get out of here.
498 if (HasTargetRunSinceMe ())
499 {
500 m_should_stop = false;
501 break;
Sean Callanan3dbf3462013-04-19 07:09:15 +0000502 }
Jim Ingham4b536182011-08-09 02:12:22 +0000503 }
Jim Ingham4b536182011-08-09 02:12:22 +0000504 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000505 // We've figured out what this stop wants to do, so mark it as valid so we don't compute it again.
506 m_should_stop_is_valid = true;
507
Jim Ingham3ebcf7f2010-08-10 00:59:59 +0000508 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000509 else
510 {
511 m_should_stop = true;
512 m_should_stop_is_valid = true;
513 Log * log_process(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
Jim Ingham79ea1d82011-12-09 04:17:31 +0000514
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000515 if (log_process)
516 log_process->Printf ("Process::%s could not find breakpoint site id: %" PRId64 "...", __FUNCTION__, m_value);
517 }
518 if (log)
519 log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop);
Jim Ingham3ebcf7f2010-08-10 00:59:59 +0000520 }
Jim Ingham3ebcf7f2010-08-10 00:59:59 +0000521 }
Greg Claytonf4b47e12010-08-04 01:40:35 +0000522
523private:
524 std::string m_description;
525 bool m_should_stop;
526 bool m_should_stop_is_valid;
Jim Ingham0f16e732011-02-08 05:20:59 +0000527 bool m_should_perform_action; // Since we are trying to preserve the "state" of the system even if we run functions
528 // etc. behind the users backs, we need to make sure we only REALLY perform the action once.
Jim Ingham52c7d202011-10-28 01:12:19 +0000529 lldb::addr_t m_address; // We use this to capture the breakpoint site address when we create the StopInfo,
530 // in case somebody deletes it between the time the StopInfo is made and the
531 // description is asked for.
Jim Inghamca36cd12012-10-05 19:16:31 +0000532 lldb::break_id_t m_break_id;
533 bool m_was_one_shot;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000534};
535
536
537//----------------------------------------------------------------------
538// StopInfoWatchpoint
539//----------------------------------------------------------------------
540
541class StopInfoWatchpoint : public StopInfo
542{
543public:
Jim Inghamf57b4352012-11-10 02:08:14 +0000544 // Make sure watchpoint is properly disabled and subsequently enabled while performing watchpoint actions.
545 class WatchpointSentry {
546 public:
547 WatchpointSentry(Process *p, Watchpoint *w):
548 process(p),
549 watchpoint(w)
550 {
551 if (process && watchpoint)
552 {
Jim Ingham1b5792e2012-12-18 02:03:49 +0000553 const bool notify = false;
Jim Inghamf57b4352012-11-10 02:08:14 +0000554 watchpoint->TurnOnEphemeralMode();
Jim Ingham1b5792e2012-12-18 02:03:49 +0000555 process->DisableWatchpoint(watchpoint, notify);
Jim Inghamf57b4352012-11-10 02:08:14 +0000556 }
557 }
558 ~WatchpointSentry()
559 {
560 if (process && watchpoint)
561 {
562 if (!watchpoint->IsDisabledDuringEphemeralMode())
Jim Ingham1b5792e2012-12-18 02:03:49 +0000563 {
564 const bool notify = false;
565 process->EnableWatchpoint(watchpoint, notify);
566 }
Jim Inghamf57b4352012-11-10 02:08:14 +0000567 watchpoint->TurnOffEphemeralMode();
568 }
569 }
570 private:
571 Process *process;
572 Watchpoint *watchpoint;
573 };
Greg Claytonf4b47e12010-08-04 01:40:35 +0000574
575 StopInfoWatchpoint (Thread &thread, break_id_t watch_id) :
Johnny Chenfd158f42011-09-21 22:47:15 +0000576 StopInfo(thread, watch_id),
577 m_description(),
578 m_should_stop(false),
579 m_should_stop_is_valid(false)
Greg Claytonf4b47e12010-08-04 01:40:35 +0000580 {
581 }
582
583 virtual ~StopInfoWatchpoint ()
584 {
585 }
586
587 virtual StopReason
588 GetStopReason () const
589 {
590 return eStopReasonWatchpoint;
591 }
592
Jim Inghamf57b4352012-11-10 02:08:14 +0000593 virtual const char *
594 GetDescription ()
595 {
596 if (m_description.empty())
597 {
598 StreamString strm;
Daniel Malead01b2952012-11-29 21:49:15 +0000599 strm.Printf("watchpoint %" PRIi64, m_value);
Jim Inghamf57b4352012-11-10 02:08:14 +0000600 m_description.swap (strm.GetString());
601 }
602 return m_description.c_str();
603 }
604
605protected:
Johnny Chenfd158f42011-09-21 22:47:15 +0000606 virtual bool
Jim Ingham9b620f32013-02-22 21:23:43 +0000607 ShouldStopSynchronous (Event *event_ptr)
Johnny Chenfd158f42011-09-21 22:47:15 +0000608 {
609 // ShouldStop() method is idempotent and should not affect hit count.
Johnny Chen16dcf712011-10-17 18:58:00 +0000610 // See Process::RunPrivateStateThread()->Process()->HandlePrivateEvent()
611 // -->Process()::ShouldBroadcastEvent()->ThreadList::ShouldStop()->
612 // Thread::ShouldStop()->ThreadPlanBase::ShouldStop()->
613 // StopInfoWatchpoint::ShouldStop() and
614 // Event::DoOnRemoval()->Process::ProcessEventData::DoOnRemoval()->
615 // StopInfoWatchpoint::PerformAction().
Johnny Chenfd158f42011-09-21 22:47:15 +0000616 if (m_should_stop_is_valid)
617 return m_should_stop;
618
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000619 ThreadSP thread_sp (m_thread_wp.lock());
620 if (thread_sp)
Johnny Chenfd158f42011-09-21 22:47:15 +0000621 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000622 WatchpointSP wp_sp (thread_sp->CalculateTarget()->GetWatchpointList().FindByID(GetValue()));
623 if (wp_sp)
624 {
625 // Check if we should stop at a watchpoint.
626 ExecutionContext exe_ctx (thread_sp->GetStackFrameAtIndex(0));
627 StoppointCallbackContext context (event_ptr, exe_ctx, true);
628 m_should_stop = wp_sp->ShouldStop (&context);
629 }
630 else
631 {
632 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
Johnny Chenfd158f42011-09-21 22:47:15 +0000633
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000634 if (log)
635 log->Printf ("Process::%s could not find watchpoint location id: %" PRId64 "...",
636 __FUNCTION__, GetValue());
Johnny Chenfd158f42011-09-21 22:47:15 +0000637
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000638 m_should_stop = true;
639 }
Johnny Chenfd158f42011-09-21 22:47:15 +0000640 }
641 m_should_stop_is_valid = true;
642 return m_should_stop;
643 }
644
Jim Ingham9b620f32013-02-22 21:23:43 +0000645 bool
646 ShouldStop (Event *event_ptr)
647 {
648 // This just reports the work done by PerformAction or the synchronous stop. It should
649 // only ever get called after they have had a chance to run.
650 assert (m_should_stop_is_valid);
651 return m_should_stop;
652 }
653
Johnny Chen16dcf712011-10-17 18:58:00 +0000654 virtual void
655 PerformAction (Event *event_ptr)
656 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000657 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS);
Johnny Chen16dcf712011-10-17 18:58:00 +0000658 // We're going to calculate if we should stop or not in some way during the course of
659 // this code. Also by default we're going to stop, so set that here.
660 m_should_stop = true;
661
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000662 ThreadSP thread_sp (m_thread_wp.lock());
663 if (thread_sp)
Johnny Chen16dcf712011-10-17 18:58:00 +0000664 {
Johnny Chen0f7ad8d2012-08-21 22:06:34 +0000665
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000666 WatchpointSP wp_sp (thread_sp->CalculateTarget()->GetWatchpointList().FindByID(GetValue()));
667 if (wp_sp)
Enrico Granataf04a2192012-07-13 23:18:48 +0000668 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000669 ExecutionContext exe_ctx (thread_sp->GetStackFrameAtIndex(0));
670 Process* process = exe_ctx.GetProcessPtr();
671
672 // This sentry object makes sure the current watchpoint is disabled while performing watchpoint actions,
673 // and it is then enabled after we are finished.
674 WatchpointSentry sentry(process, wp_sp.get());
675
Enrico Granataf04a2192012-07-13 23:18:48 +0000676 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000677 // check if this process is running on an architecture where watchpoints trigger
678 // before the associated instruction runs. if so, disable the WP, single-step and then
679 // re-enable the watchpoint
680 if (process)
Enrico Granataf04a2192012-07-13 23:18:48 +0000681 {
Jason Molendafe806902013-05-04 00:39:52 +0000682 uint32_t num;
683 bool wp_triggers_after;
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000684 if (process->GetWatchpointSupportInfo(num, wp_triggers_after).Success())
Enrico Granataf04a2192012-07-13 23:18:48 +0000685 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000686 if (!wp_triggers_after)
687 {
Jim Ingham363ddd72013-07-02 21:12:44 +0000688 StopInfoSP stored_stop_info_sp = thread_sp->GetStopInfo();
689 assert (stored_stop_info_sp.get() == this);
690
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000691 ThreadPlanSP new_plan_sp(thread_sp->QueueThreadPlanForStepSingleInstruction(false, // step-over
692 false, // abort_other_plans
693 true)); // stop_other_threads
694 new_plan_sp->SetIsMasterPlan (true);
695 new_plan_sp->SetOkayToDiscard (false);
696 new_plan_sp->SetPrivate (true);
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000697 process->GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
698 process->Resume ();
699 process->WaitForProcessToStop (NULL);
700 process->GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
Jim Ingham363ddd72013-07-02 21:12:44 +0000701 thread_sp->SetStopInfo(stored_stop_info_sp);
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000702 }
Enrico Granataf04a2192012-07-13 23:18:48 +0000703 }
704 }
705 }
Johnny Chen209bd652012-08-13 21:09:54 +0000706
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000707 if (m_should_stop && wp_sp->GetConditionText() != NULL)
Johnny Chen16dcf712011-10-17 18:58:00 +0000708 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000709 // We need to make sure the user sees any parse errors in their condition, so we'll hook the
710 // constructor errors up to the debugger's Async I/O.
Jim Ingham1624a2d2014-05-05 02:26:40 +0000711 ExpressionResults result_code;
Greg Clayton62afb9f2013-11-04 19:35:17 +0000712 EvaluateExpressionOptions expr_options;
713 expr_options.SetUnwindOnError(true);
714 expr_options.SetIgnoreBreakpoints(true);
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000715 ValueObjectSP result_value_sp;
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000716 Error error;
Greg Clayton62afb9f2013-11-04 19:35:17 +0000717 result_code = ClangUserExpression::Evaluate (exe_ctx,
718 expr_options,
719 wp_sp->GetConditionText(),
720 NULL,
721 result_value_sp,
722 error);
Jim Ingham8646d3c2014-05-05 02:47:44 +0000723 if (result_code == eExpressionCompleted)
Johnny Chen16dcf712011-10-17 18:58:00 +0000724 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000725 if (result_value_sp)
Johnny Chen16dcf712011-10-17 18:58:00 +0000726 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000727 Scalar scalar_value;
728 if (result_value_sp->ResolveValue (scalar_value))
Johnny Chen16dcf712011-10-17 18:58:00 +0000729 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000730 if (scalar_value.ULongLong(1) == 0)
731 {
732 // We have been vetoed. This takes precedence over querying
733 // the watchpoint whether it should stop (aka ignore count and
734 // friends). See also StopInfoWatchpoint::ShouldStop() as well
735 // as Process::ProcessEventData::DoOnRemoval().
736 m_should_stop = false;
737 }
738 else
739 m_should_stop = true;
740 if (log)
741 log->Printf("Condition successfully evaluated, result is %s.\n",
742 m_should_stop ? "true" : "false");
Johnny Chen16dcf712011-10-17 18:58:00 +0000743 }
744 else
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000745 {
Johnny Chen16dcf712011-10-17 18:58:00 +0000746 m_should_stop = true;
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000747 if (log)
748 log->Printf("Failed to get an integer result from the expression.");
749 }
Johnny Chen16dcf712011-10-17 18:58:00 +0000750 }
751 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000752 else
753 {
754 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
755 StreamSP error_sp = debugger.GetAsyncErrorStream ();
756 error_sp->Printf ("Stopped due to an error evaluating condition of watchpoint ");
757 wp_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief);
758 error_sp->Printf (": \"%s\"",
759 wp_sp->GetConditionText());
760 error_sp->EOL();
761 const char *err_str = error.AsCString("<Unknown Error>");
762 if (log)
763 log->Printf("Error evaluating condition: \"%s\"\n", err_str);
764
765 error_sp->PutCString (err_str);
766 error_sp->EOL();
767 error_sp->Flush();
768 // If the condition fails to be parsed or run, we should stop.
769 m_should_stop = true;
770 }
Johnny Chen16dcf712011-10-17 18:58:00 +0000771 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000772
773 // If the condition says to stop, we run the callback to further decide whether to stop.
774 if (m_should_stop)
Johnny Chen16dcf712011-10-17 18:58:00 +0000775 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000776 StoppointCallbackContext context (event_ptr, exe_ctx, false);
777 bool stop_requested = wp_sp->InvokeCallback (&context);
778 // Also make sure that the callback hasn't continued the target.
779 // If it did, when we'll set m_should_stop to false and get out of here.
780 if (HasTargetRunSinceMe ())
781 m_should_stop = false;
782
783 if (m_should_stop && !stop_requested)
784 {
785 // We have been vetoed by the callback mechanism.
786 m_should_stop = false;
787 }
788 }
789 // Finally, if we are going to stop, print out the new & old values:
790 if (m_should_stop)
791 {
792 wp_sp->CaptureWatchedValue(exe_ctx);
793
Greg Clayton1ac04c32012-02-21 00:09:25 +0000794 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000795 StreamSP output_sp = debugger.GetAsyncOutputStream ();
796 wp_sp->DumpSnapshots(output_sp.get());
797 output_sp->EOL();
798 output_sp->Flush();
Johnny Chen16dcf712011-10-17 18:58:00 +0000799 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000800
Johnny Chen16dcf712011-10-17 18:58:00 +0000801 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000802 else
803 {
804 Log * log_process(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
Johnny Chen13206412012-08-09 23:10:57 +0000805
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000806 if (log_process)
807 log_process->Printf ("Process::%s could not find watchpoint id: %" PRId64 "...", __FUNCTION__, m_value);
Johnny Chen13206412012-08-09 23:10:57 +0000808 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000809 if (log)
810 log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop);
Jim Inghama7dfb662012-10-23 07:20:06 +0000811
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000812 m_should_stop_is_valid = true;
Johnny Chen16dcf712011-10-17 18:58:00 +0000813 }
Johnny Chen16dcf712011-10-17 18:58:00 +0000814 }
815
Greg Claytonf4b47e12010-08-04 01:40:35 +0000816private:
817 std::string m_description;
Johnny Chenfd158f42011-09-21 22:47:15 +0000818 bool m_should_stop;
819 bool m_should_stop_is_valid;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000820};
821
822
823
824//----------------------------------------------------------------------
825// StopInfoUnixSignal
826//----------------------------------------------------------------------
827
828class StopInfoUnixSignal : public StopInfo
829{
830public:
831
832 StopInfoUnixSignal (Thread &thread, int signo) :
Greg Claytona658fd22011-06-04 01:26:29 +0000833 StopInfo (thread, signo)
Greg Claytonf4b47e12010-08-04 01:40:35 +0000834 {
835 }
836
837 virtual ~StopInfoUnixSignal ()
838 {
839 }
840
841
842 virtual StopReason
843 GetStopReason () const
844 {
845 return eStopReasonSignal;
846 }
847
848 virtual bool
Jim Ingham0161b492013-02-09 01:29:05 +0000849 ShouldStopSynchronous (Event *event_ptr)
850 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000851 ThreadSP thread_sp (m_thread_wp.lock());
852 if (thread_sp)
853 return thread_sp->GetProcess()->GetUnixSignals().GetShouldStop (m_value);
854 return false;
Jim Ingham0161b492013-02-09 01:29:05 +0000855 }
856
857 virtual bool
Greg Claytonf4b47e12010-08-04 01:40:35 +0000858 ShouldStop (Event *event_ptr)
859 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000860 ThreadSP thread_sp (m_thread_wp.lock());
861 if (thread_sp)
862 return thread_sp->GetProcess()->GetUnixSignals().GetShouldStop (m_value);
863 return false;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000864 }
865
866
867 // If should stop returns false, check if we should notify of this event
868 virtual bool
Jim Ingham221d51c2013-05-08 00:35:16 +0000869 DoShouldNotify (Event *event_ptr)
Greg Claytonf4b47e12010-08-04 01:40:35 +0000870 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000871 ThreadSP thread_sp (m_thread_wp.lock());
872 if (thread_sp)
Jim Ingham0161b492013-02-09 01:29:05 +0000873 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000874 bool should_notify = thread_sp->GetProcess()->GetUnixSignals().GetShouldNotify (m_value);
875 if (should_notify)
876 {
877 StreamString strm;
878 strm.Printf ("thread %d received signal: %s",
879 thread_sp->GetIndexID(),
880 thread_sp->GetProcess()->GetUnixSignals().GetSignalAsCString (m_value));
881 Process::ProcessEventData::AddRestartedReason(event_ptr, strm.GetData());
882 }
883 return should_notify;
Jim Ingham0161b492013-02-09 01:29:05 +0000884 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000885 return true;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000886 }
887
888
889 virtual void
890 WillResume (lldb::StateType resume_state)
891 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000892 ThreadSP thread_sp (m_thread_wp.lock());
893 if (thread_sp)
894 {
895 if (thread_sp->GetProcess()->GetUnixSignals().GetShouldSuppress(m_value) == false)
896 thread_sp->SetResumeSignal(m_value);
897 }
Greg Claytonf4b47e12010-08-04 01:40:35 +0000898 }
899
900 virtual const char *
901 GetDescription ()
902 {
903 if (m_description.empty())
904 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000905 ThreadSP thread_sp (m_thread_wp.lock());
906 if (thread_sp)
907 {
908 StreamString strm;
909 const char *signal_name = thread_sp->GetProcess()->GetUnixSignals().GetSignalAsCString (m_value);
910 if (signal_name)
911 strm.Printf("signal %s", signal_name);
912 else
913 strm.Printf("signal %" PRIi64, m_value);
914 m_description.swap (strm.GetString());
915 }
Greg Claytonf4b47e12010-08-04 01:40:35 +0000916 }
917 return m_description.c_str();
918 }
Greg Claytonf4b47e12010-08-04 01:40:35 +0000919};
920
921//----------------------------------------------------------------------
922// StopInfoTrace
923//----------------------------------------------------------------------
924
925class StopInfoTrace : public StopInfo
926{
927public:
928
929 StopInfoTrace (Thread &thread) :
930 StopInfo (thread, LLDB_INVALID_UID)
931 {
932 }
933
934 virtual ~StopInfoTrace ()
935 {
936 }
937
938 virtual StopReason
939 GetStopReason () const
940 {
941 return eStopReasonTrace;
942 }
943
944 virtual const char *
945 GetDescription ()
946 {
Greg Claytona658fd22011-06-04 01:26:29 +0000947 if (m_description.empty())
Greg Claytonf4b47e12010-08-04 01:40:35 +0000948 return "trace";
Greg Claytona658fd22011-06-04 01:26:29 +0000949 else
950 return m_description.c_str();
951 }
952};
953
954
955//----------------------------------------------------------------------
956// StopInfoException
957//----------------------------------------------------------------------
958
959class StopInfoException : public StopInfo
960{
961public:
962
963 StopInfoException (Thread &thread, const char *description) :
964 StopInfo (thread, LLDB_INVALID_UID)
965 {
966 if (description)
967 SetDescription (description);
968 }
969
970 virtual
971 ~StopInfoException ()
972 {
973 }
974
975 virtual StopReason
976 GetStopReason () const
977 {
978 return eStopReasonException;
979 }
980
981 virtual const char *
982 GetDescription ()
983 {
984 if (m_description.empty())
985 return "exception";
986 else
987 return m_description.c_str();
Greg Claytonf4b47e12010-08-04 01:40:35 +0000988 }
989};
990
991
992//----------------------------------------------------------------------
993// StopInfoThreadPlan
994//----------------------------------------------------------------------
995
996class StopInfoThreadPlan : public StopInfo
997{
998public:
999
Jim Ingham30fadaf2014-07-08 01:07:32 +00001000 StopInfoThreadPlan (ThreadPlanSP &plan_sp, ValueObjectSP &return_valobj_sp, ClangExpressionVariableSP &expression_variable_sp) :
Greg Claytonf4b47e12010-08-04 01:40:35 +00001001 StopInfo (plan_sp->GetThread(), LLDB_INVALID_UID),
Jim Ingham73ca05a2011-12-17 01:35:57 +00001002 m_plan_sp (plan_sp),
Jim Ingham30fadaf2014-07-08 01:07:32 +00001003 m_return_valobj_sp (return_valobj_sp),
1004 m_expression_variable_sp (expression_variable_sp)
Greg Claytonf4b47e12010-08-04 01:40:35 +00001005 {
1006 }
1007
1008 virtual ~StopInfoThreadPlan ()
1009 {
1010 }
1011
1012 virtual StopReason
1013 GetStopReason () const
1014 {
1015 return eStopReasonPlanComplete;
1016 }
1017
1018 virtual const char *
1019 GetDescription ()
1020 {
1021 if (m_description.empty())
1022 {
1023 StreamString strm;
1024 m_plan_sp->GetDescription (&strm, eDescriptionLevelBrief);
1025 m_description.swap (strm.GetString());
1026 }
1027 return m_description.c_str();
1028 }
Jim Ingham73ca05a2011-12-17 01:35:57 +00001029
1030 ValueObjectSP
1031 GetReturnValueObject()
1032 {
1033 return m_return_valobj_sp;
1034 }
Jim Ingham0161b492013-02-09 01:29:05 +00001035
Jim Ingham30fadaf2014-07-08 01:07:32 +00001036 ClangExpressionVariableSP
1037 GetExpressionVariable()
1038 {
1039 return m_expression_variable_sp;
1040 }
1041
Jim Ingham0161b492013-02-09 01:29:05 +00001042protected:
1043 virtual bool
1044 ShouldStop (Event *event_ptr)
1045 {
1046 if (m_plan_sp)
1047 return m_plan_sp->ShouldStop(event_ptr);
1048 else
1049 return StopInfo::ShouldStop(event_ptr);
1050 }
Greg Claytonf4b47e12010-08-04 01:40:35 +00001051
1052private:
1053 ThreadPlanSP m_plan_sp;
Jim Ingham73ca05a2011-12-17 01:35:57 +00001054 ValueObjectSP m_return_valobj_sp;
Jim Ingham30fadaf2014-07-08 01:07:32 +00001055 ClangExpressionVariableSP m_expression_variable_sp;
Greg Claytonf4b47e12010-08-04 01:40:35 +00001056};
Greg Clayton90ba8112012-12-05 00:16:59 +00001057
1058class StopInfoExec : public StopInfo
1059{
1060public:
1061
1062 StopInfoExec (Thread &thread) :
1063 StopInfo (thread, LLDB_INVALID_UID),
1064 m_performed_action (false)
1065 {
1066 }
1067
1068 virtual
1069 ~StopInfoExec ()
1070 {
1071 }
1072
1073 virtual StopReason
1074 GetStopReason () const
1075 {
1076 return eStopReasonExec;
1077 }
1078
1079 virtual const char *
1080 GetDescription ()
1081 {
1082 return "exec";
1083 }
1084protected:
Greg Clayton90ba8112012-12-05 00:16:59 +00001085
1086 virtual void
1087 PerformAction (Event *event_ptr)
1088 {
1089 // Only perform the action once
1090 if (m_performed_action)
1091 return;
1092 m_performed_action = true;
Greg Clayton46c2b6e2013-04-29 23:30:46 +00001093 ThreadSP thread_sp (m_thread_wp.lock());
1094 if (thread_sp)
1095 thread_sp->GetProcess()->DidExec();
Greg Clayton90ba8112012-12-05 00:16:59 +00001096 }
1097
1098 bool m_performed_action;
1099};
1100
Jim Ingham4b536182011-08-09 02:12:22 +00001101} // namespace lldb_private
Greg Claytonf4b47e12010-08-04 01:40:35 +00001102
1103StopInfoSP
1104StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id)
1105{
1106 return StopInfoSP (new StopInfoBreakpoint (thread, break_id));
1107}
1108
1109StopInfoSP
Jim Ingham36f3b362010-10-14 23:45:03 +00001110StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id, bool should_stop)
1111{
1112 return StopInfoSP (new StopInfoBreakpoint (thread, break_id, should_stop));
1113}
1114
1115StopInfoSP
Greg Claytonf4b47e12010-08-04 01:40:35 +00001116StopInfo::CreateStopReasonWithWatchpointID (Thread &thread, break_id_t watch_id)
1117{
1118 return StopInfoSP (new StopInfoWatchpoint (thread, watch_id));
1119}
1120
1121StopInfoSP
1122StopInfo::CreateStopReasonWithSignal (Thread &thread, int signo)
1123{
1124 return StopInfoSP (new StopInfoUnixSignal (thread, signo));
1125}
1126
1127StopInfoSP
1128StopInfo::CreateStopReasonToTrace (Thread &thread)
1129{
1130 return StopInfoSP (new StopInfoTrace (thread));
1131}
1132
1133StopInfoSP
Jim Ingham30fadaf2014-07-08 01:07:32 +00001134StopInfo::CreateStopReasonWithPlan (ThreadPlanSP &plan_sp,
1135 ValueObjectSP return_valobj_sp,
1136 ClangExpressionVariableSP expression_variable_sp)
Greg Claytonf4b47e12010-08-04 01:40:35 +00001137{
Jim Ingham30fadaf2014-07-08 01:07:32 +00001138 return StopInfoSP (new StopInfoThreadPlan (plan_sp, return_valobj_sp, expression_variable_sp));
Greg Claytonf4b47e12010-08-04 01:40:35 +00001139}
Greg Claytona658fd22011-06-04 01:26:29 +00001140
1141StopInfoSP
1142StopInfo::CreateStopReasonWithException (Thread &thread, const char *description)
1143{
1144 return StopInfoSP (new StopInfoException (thread, description));
1145}
Jim Ingham73ca05a2011-12-17 01:35:57 +00001146
Greg Clayton90ba8112012-12-05 00:16:59 +00001147StopInfoSP
1148StopInfo::CreateStopReasonWithExec (Thread &thread)
1149{
1150 return StopInfoSP (new StopInfoExec (thread));
1151}
1152
Jim Ingham73ca05a2011-12-17 01:35:57 +00001153ValueObjectSP
1154StopInfo::GetReturnValueObject(StopInfoSP &stop_info_sp)
1155{
1156 if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonPlanComplete)
1157 {
1158 StopInfoThreadPlan *plan_stop_info = static_cast<StopInfoThreadPlan *>(stop_info_sp.get());
1159 return plan_stop_info->GetReturnValueObject();
1160 }
1161 else
1162 return ValueObjectSP();
1163}
Jim Ingham30fadaf2014-07-08 01:07:32 +00001164
1165ClangExpressionVariableSP
1166StopInfo::GetExpressionVariable(StopInfoSP &stop_info_sp)
1167{
1168 if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonPlanComplete)
1169 {
1170 StopInfoThreadPlan *plan_stop_info = static_cast<StopInfoThreadPlan *>(stop_info_sp.get());
1171 return plan_stop_info->GetExpressionVariable();
1172 }
1173 else
1174 return ClangExpressionVariableSP();
1175}