blob: 72d474c81f8a7514842ab7562a27c873658ce479 [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"
Zachary Turnera78bd7f2015-03-03 23:11:11 +000027#include "lldb/Core/ValueObject.h"
Jim Ingham4b536182011-08-09 02:12:22 +000028#include "lldb/Expression/ClangUserExpression.h"
29#include "lldb/Target/Target.h"
Greg Claytonf4b47e12010-08-04 01:40:35 +000030#include "lldb/Target/Thread.h"
31#include "lldb/Target/ThreadPlan.h"
32#include "lldb/Target/Process.h"
33#include "lldb/Target/UnixSignals.h"
34
35using namespace lldb;
36using namespace lldb_private;
37
38StopInfo::StopInfo (Thread &thread, uint64_t value) :
Greg Clayton46c2b6e2013-04-29 23:30:46 +000039 m_thread_wp (thread.shared_from_this()),
Greg Clayton1ac04c32012-02-21 00:09:25 +000040 m_stop_id (thread.GetProcess()->GetStopID()),
41 m_resume_id (thread.GetProcess()->GetResumeID()),
Jim Ingham0161b492013-02-09 01:29:05 +000042 m_value (value),
Jim Ingham221d51c2013-05-08 00:35:16 +000043 m_override_should_notify (eLazyBoolCalculate),
Kuba Breckaafdf8422014-10-10 23:43:03 +000044 m_override_should_stop (eLazyBoolCalculate),
45 m_extended_info()
Greg Claytonf4b47e12010-08-04 01:40:35 +000046{
47}
48
49bool
50StopInfo::IsValid () const
51{
Greg Clayton46c2b6e2013-04-29 23:30:46 +000052 ThreadSP thread_sp (m_thread_wp.lock());
53 if (thread_sp)
54 return thread_sp->GetProcess()->GetStopID() == m_stop_id;
55 return false;
Greg Claytonf4b47e12010-08-04 01:40:35 +000056}
57
Jim Ingham77787032011-01-20 02:03:18 +000058void
59StopInfo::MakeStopInfoValid ()
60{
Greg Clayton46c2b6e2013-04-29 23:30:46 +000061 ThreadSP thread_sp (m_thread_wp.lock());
62 if (thread_sp)
63 {
64 m_stop_id = thread_sp->GetProcess()->GetStopID();
65 m_resume_id = thread_sp->GetProcess()->GetResumeID();
66 }
Jim Ingham77787032011-01-20 02:03:18 +000067}
68
Jim Ingham0faa43f2011-11-08 03:00:11 +000069bool
70StopInfo::HasTargetRunSinceMe ()
Jim Ingham4b536182011-08-09 02:12:22 +000071{
Greg Clayton46c2b6e2013-04-29 23:30:46 +000072 ThreadSP thread_sp (m_thread_wp.lock());
73
74 if (thread_sp)
Jim Ingham0faa43f2011-11-08 03:00:11 +000075 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +000076 lldb::StateType ret_type = thread_sp->GetProcess()->GetPrivateState();
77 if (ret_type == eStateRunning)
Jim Ingham0faa43f2011-11-08 03:00:11 +000078 {
79 return true;
80 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +000081 else if (ret_type == eStateStopped)
82 {
83 // This is a little tricky. We want to count "run and stopped again before you could
84 // ask this question as a "TRUE" answer to HasTargetRunSinceMe. But we don't want to
85 // include any running of the target done for expressions. So we track both resumes,
86 // and resumes caused by expressions, and check if there are any resumes NOT caused
87 // by expressions.
88
89 uint32_t curr_resume_id = thread_sp->GetProcess()->GetResumeID();
90 uint32_t last_user_expression_id = thread_sp->GetProcess()->GetLastUserExpressionResumeID ();
91 if (curr_resume_id == m_resume_id)
92 {
93 return false;
94 }
95 else if (curr_resume_id > last_user_expression_id)
96 {
97 return true;
98 }
99 }
Jim Ingham0faa43f2011-11-08 03:00:11 +0000100 }
101 return false;
Jim Ingham4b536182011-08-09 02:12:22 +0000102}
103
Greg Claytonf4b47e12010-08-04 01:40:35 +0000104//----------------------------------------------------------------------
105// StopInfoBreakpoint
106//----------------------------------------------------------------------
107
Jim Ingham4b536182011-08-09 02:12:22 +0000108namespace lldb_private
109{
Greg Claytonf4b47e12010-08-04 01:40:35 +0000110class StopInfoBreakpoint : public StopInfo
111{
112public:
Greg Claytonf4b47e12010-08-04 01:40:35 +0000113 StopInfoBreakpoint (Thread &thread, break_id_t break_id) :
114 StopInfo (thread, break_id),
115 m_description(),
116 m_should_stop (false),
Jim Ingham0f16e732011-02-08 05:20:59 +0000117 m_should_stop_is_valid (false),
Jim Ingham52c7d202011-10-28 01:12:19 +0000118 m_should_perform_action (true),
Jim Inghamca36cd12012-10-05 19:16:31 +0000119 m_address (LLDB_INVALID_ADDRESS),
120 m_break_id(LLDB_INVALID_BREAK_ID),
121 m_was_one_shot (false)
Greg Claytonf4b47e12010-08-04 01:40:35 +0000122 {
Jim Inghamca36cd12012-10-05 19:16:31 +0000123 StoreBPInfo();
Greg Claytonf4b47e12010-08-04 01:40:35 +0000124 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000125
Jim Ingham36f3b362010-10-14 23:45:03 +0000126 StopInfoBreakpoint (Thread &thread, break_id_t break_id, bool should_stop) :
127 StopInfo (thread, break_id),
128 m_description(),
129 m_should_stop (should_stop),
Jim Ingham0f16e732011-02-08 05:20:59 +0000130 m_should_stop_is_valid (true),
Jim Ingham52c7d202011-10-28 01:12:19 +0000131 m_should_perform_action (true),
Jim Inghamca36cd12012-10-05 19:16:31 +0000132 m_address (LLDB_INVALID_ADDRESS),
133 m_break_id(LLDB_INVALID_BREAK_ID),
134 m_was_one_shot (false)
135 {
136 StoreBPInfo();
137 }
138
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000139 void
140 StoreBPInfo ()
Jim Ingham36f3b362010-10-14 23:45:03 +0000141 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000142 ThreadSP thread_sp (m_thread_wp.lock());
143 if (thread_sp)
Jim Ingham52c7d202011-10-28 01:12:19 +0000144 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000145 BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value));
146 if (bp_site_sp)
Jim Inghamca36cd12012-10-05 19:16:31 +0000147 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000148 if (bp_site_sp->GetNumberOfOwners() == 1)
Jim Inghamca36cd12012-10-05 19:16:31 +0000149 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000150 BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(0);
151 if (bp_loc_sp)
152 {
153 m_break_id = bp_loc_sp->GetBreakpoint().GetID();
154 m_was_one_shot = bp_loc_sp->GetBreakpoint().IsOneShot();
155 }
Jim Inghamca36cd12012-10-05 19:16:31 +0000156 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000157 m_address = bp_site_sp->GetLoadAddress();
Jim Inghamca36cd12012-10-05 19:16:31 +0000158 }
Jim Ingham52c7d202011-10-28 01:12:19 +0000159 }
Jim Ingham36f3b362010-10-14 23:45:03 +0000160 }
161
Greg Claytonf4b47e12010-08-04 01:40:35 +0000162 virtual ~StopInfoBreakpoint ()
163 {
164 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000165
Greg Claytonf4b47e12010-08-04 01:40:35 +0000166 virtual StopReason
167 GetStopReason () const
168 {
169 return eStopReasonBreakpoint;
170 }
171
172 virtual bool
Jim Ingham6d66ce62012-04-20 21:16:56 +0000173 ShouldStopSynchronous (Event *event_ptr)
Greg Claytonf4b47e12010-08-04 01:40:35 +0000174 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000175 ThreadSP thread_sp (m_thread_wp.lock());
176 if (thread_sp)
Greg Claytonf4b47e12010-08-04 01:40:35 +0000177 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000178 if (!m_should_stop_is_valid)
Greg Claytonf4b47e12010-08-04 01:40:35 +0000179 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000180 // Only check once if we should stop at a breakpoint
181 BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value));
182 if (bp_site_sp)
183 {
184 ExecutionContext exe_ctx (thread_sp->GetStackFrameAtIndex(0));
185 StoppointCallbackContext context (event_ptr, exe_ctx, true);
Jim Inghama672ece2014-10-22 01:54:17 +0000186 bp_site_sp->BumpHitCounts();
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000187 m_should_stop = bp_site_sp->ShouldStop (&context);
188 }
189 else
190 {
191 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
Greg Claytonf4b47e12010-08-04 01:40:35 +0000192
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000193 if (log)
194 log->Printf ("Process::%s could not find breakpoint site id: %" PRId64 "...", __FUNCTION__, m_value);
Greg Claytonf4b47e12010-08-04 01:40:35 +0000195
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000196 m_should_stop = true;
197 }
198 m_should_stop_is_valid = true;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000199 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000200 return m_should_stop;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000201 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000202 return false;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000203 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000204
Jim Inghamf57b4352012-11-10 02:08:14 +0000205 virtual bool
Jim Ingham221d51c2013-05-08 00:35:16 +0000206 DoShouldNotify (Event *event_ptr)
Jim Inghamf57b4352012-11-10 02:08:14 +0000207 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000208 ThreadSP thread_sp (m_thread_wp.lock());
209 if (thread_sp)
Jim Inghamf57b4352012-11-10 02:08:14 +0000210 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000211 BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value));
212 if (bp_site_sp)
Jim Inghamf57b4352012-11-10 02:08:14 +0000213 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000214 bool all_internal = true;
215
216 for (uint32_t i = 0; i < bp_site_sp->GetNumberOfOwners(); i++)
Jim Inghamf57b4352012-11-10 02:08:14 +0000217 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000218 if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal())
219 {
220 all_internal = false;
221 break;
222 }
Jim Inghamf57b4352012-11-10 02:08:14 +0000223 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000224 return all_internal == false;
Jim Inghamf57b4352012-11-10 02:08:14 +0000225 }
Jim Inghamf57b4352012-11-10 02:08:14 +0000226 }
227 return true;
228 }
229
230 virtual const char *
231 GetDescription ()
232 {
233 if (m_description.empty())
234 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000235 ThreadSP thread_sp (m_thread_wp.lock());
236 if (thread_sp)
Jim Inghamf57b4352012-11-10 02:08:14 +0000237 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000238 BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value));
239 if (bp_site_sp)
Jim Ingham29950772013-01-26 02:19:28 +0000240 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000241 StreamString strm;
242 // If we have just hit an internal breakpoint, and it has a kind description, print that instead of the
243 // full breakpoint printing:
244 if (bp_site_sp->IsInternal())
Jim Ingham29950772013-01-26 02:19:28 +0000245 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000246 size_t num_owners = bp_site_sp->GetNumberOfOwners();
247 for (size_t idx = 0; idx < num_owners; idx++)
Jim Ingham29950772013-01-26 02:19:28 +0000248 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000249 const char *kind = bp_site_sp->GetOwnerAtIndex(idx)->GetBreakpoint().GetBreakpointKind();
250 if (kind != NULL)
251 {
252 m_description.assign (kind);
253 return kind;
254 }
Jim Ingham29950772013-01-26 02:19:28 +0000255 }
256 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000257
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000258 strm.Printf("breakpoint ");
259 bp_site_sp->GetDescription(&strm, eDescriptionLevelBrief);
260 m_description.swap (strm.GetString());
Jim Ingham29950772013-01-26 02:19:28 +0000261 }
Jim Inghamf57b4352012-11-10 02:08:14 +0000262 else
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000263 {
264 StreamString strm;
265 if (m_break_id != LLDB_INVALID_BREAK_ID)
266 {
267 BreakpointSP break_sp = thread_sp->GetProcess()->GetTarget().GetBreakpointByID(m_break_id);
268 if (break_sp)
269 {
270 if (break_sp->IsInternal())
271 {
272 const char *kind = break_sp->GetBreakpointKind();
273 if (kind)
274 strm.Printf ("internal %s breakpoint(%d).", kind, m_break_id);
275 else
276 strm.Printf ("internal breakpoint(%d).", m_break_id);
277 }
278 else
279 {
280 strm.Printf ("breakpoint %d.", m_break_id);
281 }
282 }
283 else
284 {
285 if (m_was_one_shot)
286 strm.Printf ("one-shot breakpoint %d", m_break_id);
287 else
288 strm.Printf ("breakpoint %d which has been deleted.", m_break_id);
289 }
290 }
291 else if (m_address == LLDB_INVALID_ADDRESS)
292 strm.Printf("breakpoint site %" PRIi64 " which has been deleted - unknown address", m_value);
293 else
294 strm.Printf("breakpoint site %" PRIi64 " which has been deleted - was at 0x%" PRIx64, m_value, m_address);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000295
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000296 m_description.swap (strm.GetString());
297 }
Jim Inghamf57b4352012-11-10 02:08:14 +0000298 }
299 }
300 return m_description.c_str();
301 }
302
303protected:
Jim Ingham6d66ce62012-04-20 21:16:56 +0000304 bool
305 ShouldStop (Event *event_ptr)
306 {
307 // This just reports the work done by PerformAction or the synchronous stop. It should
308 // only ever get called after they have had a chance to run.
309 assert (m_should_stop_is_valid);
310 return m_should_stop;
311 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000312
Jim Ingham3ebcf7f2010-08-10 00:59:59 +0000313 virtual void
314 PerformAction (Event *event_ptr)
315 {
Jim Ingham0f16e732011-02-08 05:20:59 +0000316 if (!m_should_perform_action)
317 return;
318 m_should_perform_action = false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000319
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000320 ThreadSP thread_sp (m_thread_wp.lock());
321
322 if (thread_sp)
Jim Ingham5cb9a182013-03-28 00:13:30 +0000323 {
Jim Inghamcca89952014-08-05 01:58:14 +0000324 Log *log = lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_BREAKPOINTS | LIBLLDB_LOG_STEP);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000325
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000326 if (!thread_sp->IsValid())
Jim Ingham3ebcf7f2010-08-10 00:59:59 +0000327 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000328 // This shouldn't ever happen, but just in case, don't do more harm.
Jason Molenda3f032ff2013-08-06 23:08:59 +0000329 if (log)
330 {
331 log->Printf ("PerformAction got called with an invalid thread.");
332 }
Jim Ingham79ea1d82011-12-09 04:17:31 +0000333 m_should_stop = true;
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000334 m_should_stop_is_valid = true;
335 return;
Jim Ingham79ea1d82011-12-09 04:17:31 +0000336 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000337
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000338 BreakpointSiteSP bp_site_sp (thread_sp->GetProcess()->GetBreakpointSiteList().FindByID (m_value));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000339
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000340 if (bp_site_sp)
Jim Ingham79ea1d82011-12-09 04:17:31 +0000341 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000342 size_t num_owners = bp_site_sp->GetNumberOfOwners();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000343
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000344 if (num_owners == 0)
345 {
346 m_should_stop = true;
Jim Ingham184e9812013-01-15 02:47:48 +0000347 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000348 else
Jim Ingham4b536182011-08-09 02:12:22 +0000349 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000350 // We go through each location, and test first its condition. If the condition says to stop,
351 // then we run the callback for that location. If that callback says to stop as well, then
352 // we set m_should_stop to true; we are going to stop.
353 // But we still want to give all the breakpoints whose conditions say we are going to stop a
354 // chance to run their callbacks.
355 // Of course if any callback restarts the target by putting "continue" in the callback, then
356 // we're going to restart, without running the rest of the callbacks. And in this case we will
357 // end up not stopping even if another location said we should stop. But that's better than not
358 // running all the callbacks.
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000359
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000360 m_should_stop = false;
361
362 ExecutionContext exe_ctx (thread_sp->GetStackFrameAtIndex(0));
363 Process *process = exe_ctx.GetProcessPtr();
364 if (process->GetModIDRef().IsLastResumeForUserExpression())
Jim Ingham4b536182011-08-09 02:12:22 +0000365 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000366 // If we are in the middle of evaluating an expression, don't run asynchronous breakpoint commands or
367 // expressions. That could lead to infinite recursion if the command or condition re-calls the function
368 // with this breakpoint.
369 // TODO: We can keep a list of the breakpoints we've seen while running expressions in the nested
370 // PerformAction calls that can arise when the action runs a function that hits another breakpoint,
371 // and only stop running commands when we see the same breakpoint hit a second time.
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000372
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000373 m_should_stop_is_valid = true;
374 if (log)
375 log->Printf ("StopInfoBreakpoint::PerformAction - Hit a breakpoint while running an expression,"
376 " not running commands to avoid recursion.");
377 bool ignoring_breakpoints = process->GetIgnoreBreakpointsInExpressions();
378 if (ignoring_breakpoints)
Jim Ingham4b536182011-08-09 02:12:22 +0000379 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000380 m_should_stop = false;
381 // Internal breakpoints will always stop.
382 for (size_t j = 0; j < num_owners; j++)
383 {
384 lldb::BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(j);
385 if (bp_loc_sp->GetBreakpoint().IsInternal())
386 {
387 m_should_stop = true;
388 break;
389 }
390 }
Jim Ingham4b536182011-08-09 02:12:22 +0000391 }
Sean Callanan3dbf3462013-04-19 07:09:15 +0000392 else
393 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000394 m_should_stop = true;
395 }
396 if (log)
397 log->Printf ("StopInfoBreakpoint::PerformAction - in expression, continuing: %s.",
398 m_should_stop ? "true" : "false");
399 process->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf("Warning: hit breakpoint while "
400 "running function, skipping commands and conditions to prevent recursion.");
401 return;
402 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000403
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000404 StoppointCallbackContext context (event_ptr, exe_ctx, false);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000405
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000406 // Let's copy the breakpoint locations out of the site and store them in a local list. That way if
407 // one of the breakpoint actions changes the site, then we won't be operating on a bad list.
Jim Inghama672ece2014-10-22 01:54:17 +0000408 // For safety's sake let's also grab an extra reference to the breakpoint owners of the locations we're
409 // going to examine, since the locations are going to have to get back to their breakpoints, and the
410 // locations don't keep their owners alive. I'm just sticking the BreakpointSP's in a vector since
411 // I'm only really using it to locally increment their retain counts.
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000412
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000413 BreakpointLocationCollection site_locations;
Jim Inghama672ece2014-10-22 01:54:17 +0000414 std::vector<lldb::BreakpointSP> location_owners;
415
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000416 for (size_t j = 0; j < num_owners; j++)
Jim Inghama672ece2014-10-22 01:54:17 +0000417 {
418 BreakpointLocationSP loc(bp_site_sp->GetOwnerAtIndex(j));
419 site_locations.Add(loc);
420 location_owners.push_back(loc->GetBreakpoint().shared_from_this());
421
422 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000423
424 for (size_t j = 0; j < num_owners; j++)
425 {
426 lldb::BreakpointLocationSP bp_loc_sp = site_locations.GetByIndex(j);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000427
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000428 // If another action disabled this breakpoint or its location, then don't run the actions.
429 if (!bp_loc_sp->IsEnabled() || !bp_loc_sp->GetBreakpoint().IsEnabled())
430 continue;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000431
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000432 // The breakpoint site may have many locations associated with it, not all of them valid for
433 // this thread. Skip the ones that aren't:
434 if (!bp_loc_sp->ValidForThisThread(thread_sp.get()))
Jim Inghama8b99ca2014-01-15 03:30:04 +0000435 {
436 if (log)
437 {
438 StreamString s;
439 bp_loc_sp->GetDescription(&s, eDescriptionLevelBrief);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000440 log->Printf ("Breakpoint %s hit on thread 0x%llx but it was not for this thread, continuing.",
441 s.GetData(),
442 static_cast<unsigned long long>(thread_sp->GetID()));
Jim Inghama8b99ca2014-01-15 03:30:04 +0000443 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000444 continue;
Jim Inghama8b99ca2014-01-15 03:30:04 +0000445 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000446 // First run the condition for the breakpoint. If that says we should stop, then we'll run
447 // the callback for the breakpoint. If the callback says we shouldn't stop that will win.
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000448
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000449 if (bp_loc_sp->GetConditionText() != NULL)
450 {
451 Error condition_error;
452 bool condition_says_stop = bp_loc_sp->ConditionSaysStop(exe_ctx, condition_error);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000453
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000454 if (!condition_error.Success())
455 {
456 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
457 StreamSP error_sp = debugger.GetAsyncErrorStream ();
458 error_sp->Printf ("Stopped due to an error evaluating condition of breakpoint ");
459 bp_loc_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief);
460 error_sp->Printf (": \"%s\"",
461 bp_loc_sp->GetConditionText());
462 error_sp->EOL();
463 const char *err_str = condition_error.AsCString("<Unknown Error>");
464 if (log)
465 log->Printf("Error evaluating condition: \"%s\"\n", err_str);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000466
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000467 error_sp->PutCString (err_str);
468 error_sp->EOL();
469 error_sp->Flush();
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000470 }
471 else
472 {
Jim Inghama8b99ca2014-01-15 03:30:04 +0000473 if (log)
474 {
475 StreamString s;
476 bp_loc_sp->GetDescription(&s, eDescriptionLevelBrief);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000477 log->Printf ("Condition evaluated for breakpoint %s on thread 0x%llx conditon_says_stop: %i.",
478 s.GetData(),
479 static_cast<unsigned long long>(thread_sp->GetID()),
480 condition_says_stop);
Jim Inghama8b99ca2014-01-15 03:30:04 +0000481 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000482 if (!condition_says_stop)
Jim Inghamd762df82015-01-15 01:41:04 +0000483 {
484 // We don't want to increment the hit count of breakpoints if the condition fails.
485 // We've already bumped it by the time we get here, so undo the bump:
486 bp_loc_sp->UndoBumpHitCount();
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000487 continue;
Jim Inghamd762df82015-01-15 01:41:04 +0000488 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000489 }
490 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000491
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000492 bool callback_says_stop;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000493
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000494 // FIXME: For now the callbacks have to run in async mode - the first time we restart we need
495 // to get out of there. So set it here.
496 // When we figure out how to nest breakpoint hits then this will change.
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000497
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000498 Debugger &debugger = thread_sp->CalculateTarget()->GetDebugger();
499 bool old_async = debugger.GetAsyncExecution();
500 debugger.SetAsyncExecution (true);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000501
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000502 callback_says_stop = bp_loc_sp->InvokeCallback (&context);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000503
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000504 debugger.SetAsyncExecution (old_async);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000505
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000506 if (callback_says_stop)
507 m_should_stop = true;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000508
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000509 // If we are going to stop for this breakpoint, then remove the breakpoint.
510 if (callback_says_stop && bp_loc_sp && bp_loc_sp->GetBreakpoint().IsOneShot())
511 {
512 thread_sp->GetProcess()->GetTarget().RemoveBreakpointByID (bp_loc_sp->GetBreakpoint().GetID());
513 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000514
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000515 // Also make sure that the callback hasn't continued the target.
516 // If it did, when we'll set m_should_start to false and get out of here.
517 if (HasTargetRunSinceMe ())
518 {
519 m_should_stop = false;
520 break;
Sean Callanan3dbf3462013-04-19 07:09:15 +0000521 }
Jim Ingham4b536182011-08-09 02:12:22 +0000522 }
Jim Ingham4b536182011-08-09 02:12:22 +0000523 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000524 // We've figured out what this stop wants to do, so mark it as valid so we don't compute it again.
525 m_should_stop_is_valid = true;
526
Jim Ingham3ebcf7f2010-08-10 00:59:59 +0000527 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000528 else
529 {
530 m_should_stop = true;
531 m_should_stop_is_valid = true;
532 Log * log_process(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
Jim Ingham79ea1d82011-12-09 04:17:31 +0000533
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000534 if (log_process)
535 log_process->Printf ("Process::%s could not find breakpoint site id: %" PRId64 "...", __FUNCTION__, m_value);
536 }
537 if (log)
538 log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop);
Jim Ingham3ebcf7f2010-08-10 00:59:59 +0000539 }
Jim Ingham3ebcf7f2010-08-10 00:59:59 +0000540 }
Greg Claytonf4b47e12010-08-04 01:40:35 +0000541
542private:
543 std::string m_description;
544 bool m_should_stop;
545 bool m_should_stop_is_valid;
Jim Ingham0f16e732011-02-08 05:20:59 +0000546 bool m_should_perform_action; // Since we are trying to preserve the "state" of the system even if we run functions
547 // etc. behind the users backs, we need to make sure we only REALLY perform the action once.
Jim Ingham52c7d202011-10-28 01:12:19 +0000548 lldb::addr_t m_address; // We use this to capture the breakpoint site address when we create the StopInfo,
549 // in case somebody deletes it between the time the StopInfo is made and the
550 // description is asked for.
Jim Inghamca36cd12012-10-05 19:16:31 +0000551 lldb::break_id_t m_break_id;
552 bool m_was_one_shot;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000553};
554
555
556//----------------------------------------------------------------------
557// StopInfoWatchpoint
558//----------------------------------------------------------------------
559
560class StopInfoWatchpoint : public StopInfo
561{
562public:
Jim Inghamf57b4352012-11-10 02:08:14 +0000563 // Make sure watchpoint is properly disabled and subsequently enabled while performing watchpoint actions.
564 class WatchpointSentry {
565 public:
566 WatchpointSentry(Process *p, Watchpoint *w):
567 process(p),
568 watchpoint(w)
569 {
570 if (process && watchpoint)
571 {
Jim Ingham1b5792e2012-12-18 02:03:49 +0000572 const bool notify = false;
Jim Inghamf57b4352012-11-10 02:08:14 +0000573 watchpoint->TurnOnEphemeralMode();
Jim Ingham1b5792e2012-12-18 02:03:49 +0000574 process->DisableWatchpoint(watchpoint, notify);
Jim Inghamf57b4352012-11-10 02:08:14 +0000575 }
576 }
577 ~WatchpointSentry()
578 {
579 if (process && watchpoint)
580 {
581 if (!watchpoint->IsDisabledDuringEphemeralMode())
Jim Ingham1b5792e2012-12-18 02:03:49 +0000582 {
583 const bool notify = false;
584 process->EnableWatchpoint(watchpoint, notify);
585 }
Jim Inghamf57b4352012-11-10 02:08:14 +0000586 watchpoint->TurnOffEphemeralMode();
587 }
588 }
589 private:
590 Process *process;
591 Watchpoint *watchpoint;
592 };
Greg Claytonf4b47e12010-08-04 01:40:35 +0000593
594 StopInfoWatchpoint (Thread &thread, break_id_t watch_id) :
Johnny Chenfd158f42011-09-21 22:47:15 +0000595 StopInfo(thread, watch_id),
596 m_description(),
597 m_should_stop(false),
598 m_should_stop_is_valid(false)
Greg Claytonf4b47e12010-08-04 01:40:35 +0000599 {
600 }
601
602 virtual ~StopInfoWatchpoint ()
603 {
604 }
605
606 virtual StopReason
607 GetStopReason () const
608 {
609 return eStopReasonWatchpoint;
610 }
611
Jim Inghamf57b4352012-11-10 02:08:14 +0000612 virtual const char *
613 GetDescription ()
614 {
615 if (m_description.empty())
616 {
617 StreamString strm;
Daniel Malead01b2952012-11-29 21:49:15 +0000618 strm.Printf("watchpoint %" PRIi64, m_value);
Jim Inghamf57b4352012-11-10 02:08:14 +0000619 m_description.swap (strm.GetString());
620 }
621 return m_description.c_str();
622 }
623
624protected:
Johnny Chenfd158f42011-09-21 22:47:15 +0000625 virtual bool
Jim Ingham9b620f32013-02-22 21:23:43 +0000626 ShouldStopSynchronous (Event *event_ptr)
Johnny Chenfd158f42011-09-21 22:47:15 +0000627 {
628 // ShouldStop() method is idempotent and should not affect hit count.
Johnny Chen16dcf712011-10-17 18:58:00 +0000629 // See Process::RunPrivateStateThread()->Process()->HandlePrivateEvent()
630 // -->Process()::ShouldBroadcastEvent()->ThreadList::ShouldStop()->
631 // Thread::ShouldStop()->ThreadPlanBase::ShouldStop()->
632 // StopInfoWatchpoint::ShouldStop() and
633 // Event::DoOnRemoval()->Process::ProcessEventData::DoOnRemoval()->
634 // StopInfoWatchpoint::PerformAction().
Johnny Chenfd158f42011-09-21 22:47:15 +0000635 if (m_should_stop_is_valid)
636 return m_should_stop;
637
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000638 ThreadSP thread_sp (m_thread_wp.lock());
639 if (thread_sp)
Johnny Chenfd158f42011-09-21 22:47:15 +0000640 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000641 WatchpointSP wp_sp (thread_sp->CalculateTarget()->GetWatchpointList().FindByID(GetValue()));
642 if (wp_sp)
643 {
644 // Check if we should stop at a watchpoint.
645 ExecutionContext exe_ctx (thread_sp->GetStackFrameAtIndex(0));
646 StoppointCallbackContext context (event_ptr, exe_ctx, true);
647 m_should_stop = wp_sp->ShouldStop (&context);
648 }
649 else
650 {
651 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
Johnny Chenfd158f42011-09-21 22:47:15 +0000652
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000653 if (log)
654 log->Printf ("Process::%s could not find watchpoint location id: %" PRId64 "...",
655 __FUNCTION__, GetValue());
Johnny Chenfd158f42011-09-21 22:47:15 +0000656
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000657 m_should_stop = true;
658 }
Johnny Chenfd158f42011-09-21 22:47:15 +0000659 }
660 m_should_stop_is_valid = true;
661 return m_should_stop;
662 }
663
Jim Ingham9b620f32013-02-22 21:23:43 +0000664 bool
665 ShouldStop (Event *event_ptr)
666 {
667 // This just reports the work done by PerformAction or the synchronous stop. It should
668 // only ever get called after they have had a chance to run.
669 assert (m_should_stop_is_valid);
670 return m_should_stop;
671 }
672
Johnny Chen16dcf712011-10-17 18:58:00 +0000673 virtual void
674 PerformAction (Event *event_ptr)
675 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000676 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_WATCHPOINTS);
Johnny Chen16dcf712011-10-17 18:58:00 +0000677 // We're going to calculate if we should stop or not in some way during the course of
678 // this code. Also by default we're going to stop, so set that here.
679 m_should_stop = true;
680
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000681 ThreadSP thread_sp (m_thread_wp.lock());
682 if (thread_sp)
Johnny Chen16dcf712011-10-17 18:58:00 +0000683 {
Johnny Chen0f7ad8d2012-08-21 22:06:34 +0000684
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000685 WatchpointSP wp_sp (thread_sp->CalculateTarget()->GetWatchpointList().FindByID(GetValue()));
686 if (wp_sp)
Enrico Granataf04a2192012-07-13 23:18:48 +0000687 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000688 ExecutionContext exe_ctx (thread_sp->GetStackFrameAtIndex(0));
689 Process* process = exe_ctx.GetProcessPtr();
690
691 // This sentry object makes sure the current watchpoint is disabled while performing watchpoint actions,
692 // and it is then enabled after we are finished.
693 WatchpointSentry sentry(process, wp_sp.get());
694
Enrico Granataf04a2192012-07-13 23:18:48 +0000695 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000696 // check if this process is running on an architecture where watchpoints trigger
697 // before the associated instruction runs. if so, disable the WP, single-step and then
698 // re-enable the watchpoint
699 if (process)
Enrico Granataf04a2192012-07-13 23:18:48 +0000700 {
Jason Molendafe806902013-05-04 00:39:52 +0000701 uint32_t num;
702 bool wp_triggers_after;
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000703 if (process->GetWatchpointSupportInfo(num, wp_triggers_after).Success())
Enrico Granataf04a2192012-07-13 23:18:48 +0000704 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000705 if (!wp_triggers_after)
706 {
Jim Ingham363ddd72013-07-02 21:12:44 +0000707 StopInfoSP stored_stop_info_sp = thread_sp->GetStopInfo();
708 assert (stored_stop_info_sp.get() == this);
709
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000710 ThreadPlanSP new_plan_sp(thread_sp->QueueThreadPlanForStepSingleInstruction(false, // step-over
Greg Claytondc6224e2014-10-21 01:00:42 +0000711 false, // abort_other_plans
712 true)); // stop_other_threads
Jim Ingham4d56e9c2013-07-18 21:48:26 +0000713 new_plan_sp->SetIsMasterPlan (true);
714 new_plan_sp->SetOkayToDiscard (false);
715 new_plan_sp->SetPrivate (true);
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000716 process->GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
Greg Claytondc6224e2014-10-21 01:00:42 +0000717 process->ResumeSynchronous(NULL);
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000718 process->GetThreadList().SetSelectedThreadByID (thread_sp->GetID());
Jim Ingham363ddd72013-07-02 21:12:44 +0000719 thread_sp->SetStopInfo(stored_stop_info_sp);
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000720 }
Enrico Granataf04a2192012-07-13 23:18:48 +0000721 }
722 }
723 }
Johnny Chen209bd652012-08-13 21:09:54 +0000724
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000725 if (m_should_stop && wp_sp->GetConditionText() != NULL)
Johnny Chen16dcf712011-10-17 18:58:00 +0000726 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000727 // We need to make sure the user sees any parse errors in their condition, so we'll hook the
728 // constructor errors up to the debugger's Async I/O.
Jim Ingham1624a2d2014-05-05 02:26:40 +0000729 ExpressionResults result_code;
Greg Clayton62afb9f2013-11-04 19:35:17 +0000730 EvaluateExpressionOptions expr_options;
731 expr_options.SetUnwindOnError(true);
732 expr_options.SetIgnoreBreakpoints(true);
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000733 ValueObjectSP result_value_sp;
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000734 Error error;
Greg Clayton62afb9f2013-11-04 19:35:17 +0000735 result_code = ClangUserExpression::Evaluate (exe_ctx,
736 expr_options,
737 wp_sp->GetConditionText(),
738 NULL,
739 result_value_sp,
740 error);
Jim Ingham8646d3c2014-05-05 02:47:44 +0000741 if (result_code == eExpressionCompleted)
Johnny Chen16dcf712011-10-17 18:58:00 +0000742 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000743 if (result_value_sp)
Johnny Chen16dcf712011-10-17 18:58:00 +0000744 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000745 Scalar scalar_value;
746 if (result_value_sp->ResolveValue (scalar_value))
Johnny Chen16dcf712011-10-17 18:58:00 +0000747 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000748 if (scalar_value.ULongLong(1) == 0)
749 {
750 // We have been vetoed. This takes precedence over querying
751 // the watchpoint whether it should stop (aka ignore count and
752 // friends). See also StopInfoWatchpoint::ShouldStop() as well
753 // as Process::ProcessEventData::DoOnRemoval().
754 m_should_stop = false;
755 }
756 else
757 m_should_stop = true;
758 if (log)
759 log->Printf("Condition successfully evaluated, result is %s.\n",
760 m_should_stop ? "true" : "false");
Johnny Chen16dcf712011-10-17 18:58:00 +0000761 }
762 else
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000763 {
Johnny Chen16dcf712011-10-17 18:58:00 +0000764 m_should_stop = true;
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000765 if (log)
766 log->Printf("Failed to get an integer result from the expression.");
767 }
Johnny Chen16dcf712011-10-17 18:58:00 +0000768 }
769 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000770 else
771 {
772 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
773 StreamSP error_sp = debugger.GetAsyncErrorStream ();
774 error_sp->Printf ("Stopped due to an error evaluating condition of watchpoint ");
775 wp_sp->GetDescription (error_sp.get(), eDescriptionLevelBrief);
776 error_sp->Printf (": \"%s\"",
777 wp_sp->GetConditionText());
778 error_sp->EOL();
779 const char *err_str = error.AsCString("<Unknown Error>");
780 if (log)
781 log->Printf("Error evaluating condition: \"%s\"\n", err_str);
782
783 error_sp->PutCString (err_str);
784 error_sp->EOL();
785 error_sp->Flush();
786 // If the condition fails to be parsed or run, we should stop.
787 m_should_stop = true;
788 }
Johnny Chen16dcf712011-10-17 18:58:00 +0000789 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000790
791 // If the condition says to stop, we run the callback to further decide whether to stop.
792 if (m_should_stop)
Johnny Chen16dcf712011-10-17 18:58:00 +0000793 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000794 StoppointCallbackContext context (event_ptr, exe_ctx, false);
795 bool stop_requested = wp_sp->InvokeCallback (&context);
796 // Also make sure that the callback hasn't continued the target.
797 // If it did, when we'll set m_should_stop to false and get out of here.
798 if (HasTargetRunSinceMe ())
799 m_should_stop = false;
800
801 if (m_should_stop && !stop_requested)
802 {
803 // We have been vetoed by the callback mechanism.
804 m_should_stop = false;
805 }
806 }
807 // Finally, if we are going to stop, print out the new & old values:
808 if (m_should_stop)
809 {
810 wp_sp->CaptureWatchedValue(exe_ctx);
811
Greg Clayton1ac04c32012-02-21 00:09:25 +0000812 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000813 StreamSP output_sp = debugger.GetAsyncOutputStream ();
814 wp_sp->DumpSnapshots(output_sp.get());
815 output_sp->EOL();
816 output_sp->Flush();
Johnny Chen16dcf712011-10-17 18:58:00 +0000817 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000818
Johnny Chen16dcf712011-10-17 18:58:00 +0000819 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000820 else
821 {
822 Log * log_process(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
Johnny Chen13206412012-08-09 23:10:57 +0000823
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000824 if (log_process)
825 log_process->Printf ("Process::%s could not find watchpoint id: %" PRId64 "...", __FUNCTION__, m_value);
Johnny Chen13206412012-08-09 23:10:57 +0000826 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000827 if (log)
828 log->Printf ("Process::%s returning from action with m_should_stop: %d.", __FUNCTION__, m_should_stop);
Jim Inghama7dfb662012-10-23 07:20:06 +0000829
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000830 m_should_stop_is_valid = true;
Johnny Chen16dcf712011-10-17 18:58:00 +0000831 }
Johnny Chen16dcf712011-10-17 18:58:00 +0000832 }
833
Greg Claytonf4b47e12010-08-04 01:40:35 +0000834private:
835 std::string m_description;
Johnny Chenfd158f42011-09-21 22:47:15 +0000836 bool m_should_stop;
837 bool m_should_stop_is_valid;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000838};
839
840
841
842//----------------------------------------------------------------------
843// StopInfoUnixSignal
844//----------------------------------------------------------------------
845
846class StopInfoUnixSignal : public StopInfo
847{
848public:
849
850 StopInfoUnixSignal (Thread &thread, int signo) :
Greg Claytona658fd22011-06-04 01:26:29 +0000851 StopInfo (thread, signo)
Greg Claytonf4b47e12010-08-04 01:40:35 +0000852 {
853 }
854
855 virtual ~StopInfoUnixSignal ()
856 {
857 }
858
859
860 virtual StopReason
861 GetStopReason () const
862 {
863 return eStopReasonSignal;
864 }
865
866 virtual bool
Jim Ingham0161b492013-02-09 01:29:05 +0000867 ShouldStopSynchronous (Event *event_ptr)
868 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000869 ThreadSP thread_sp (m_thread_wp.lock());
870 if (thread_sp)
871 return thread_sp->GetProcess()->GetUnixSignals().GetShouldStop (m_value);
872 return false;
Jim Ingham0161b492013-02-09 01:29:05 +0000873 }
874
875 virtual bool
Greg Claytonf4b47e12010-08-04 01:40:35 +0000876 ShouldStop (Event *event_ptr)
877 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000878 ThreadSP thread_sp (m_thread_wp.lock());
879 if (thread_sp)
880 return thread_sp->GetProcess()->GetUnixSignals().GetShouldStop (m_value);
881 return false;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000882 }
883
884
885 // If should stop returns false, check if we should notify of this event
886 virtual bool
Jim Ingham221d51c2013-05-08 00:35:16 +0000887 DoShouldNotify (Event *event_ptr)
Greg Claytonf4b47e12010-08-04 01:40:35 +0000888 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000889 ThreadSP thread_sp (m_thread_wp.lock());
890 if (thread_sp)
Jim Ingham0161b492013-02-09 01:29:05 +0000891 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000892 bool should_notify = thread_sp->GetProcess()->GetUnixSignals().GetShouldNotify (m_value);
893 if (should_notify)
894 {
895 StreamString strm;
896 strm.Printf ("thread %d received signal: %s",
897 thread_sp->GetIndexID(),
898 thread_sp->GetProcess()->GetUnixSignals().GetSignalAsCString (m_value));
899 Process::ProcessEventData::AddRestartedReason(event_ptr, strm.GetData());
900 }
901 return should_notify;
Jim Ingham0161b492013-02-09 01:29:05 +0000902 }
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000903 return true;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000904 }
905
906
907 virtual void
908 WillResume (lldb::StateType resume_state)
909 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000910 ThreadSP thread_sp (m_thread_wp.lock());
911 if (thread_sp)
912 {
913 if (thread_sp->GetProcess()->GetUnixSignals().GetShouldSuppress(m_value) == false)
914 thread_sp->SetResumeSignal(m_value);
915 }
Greg Claytonf4b47e12010-08-04 01:40:35 +0000916 }
917
918 virtual const char *
919 GetDescription ()
920 {
921 if (m_description.empty())
922 {
Greg Clayton46c2b6e2013-04-29 23:30:46 +0000923 ThreadSP thread_sp (m_thread_wp.lock());
924 if (thread_sp)
925 {
926 StreamString strm;
927 const char *signal_name = thread_sp->GetProcess()->GetUnixSignals().GetSignalAsCString (m_value);
928 if (signal_name)
929 strm.Printf("signal %s", signal_name);
930 else
931 strm.Printf("signal %" PRIi64, m_value);
932 m_description.swap (strm.GetString());
933 }
Greg Claytonf4b47e12010-08-04 01:40:35 +0000934 }
935 return m_description.c_str();
936 }
Greg Claytonf4b47e12010-08-04 01:40:35 +0000937};
938
939//----------------------------------------------------------------------
940// StopInfoTrace
941//----------------------------------------------------------------------
942
943class StopInfoTrace : public StopInfo
944{
945public:
946
947 StopInfoTrace (Thread &thread) :
948 StopInfo (thread, LLDB_INVALID_UID)
949 {
950 }
951
952 virtual ~StopInfoTrace ()
953 {
954 }
955
956 virtual StopReason
957 GetStopReason () const
958 {
959 return eStopReasonTrace;
960 }
961
962 virtual const char *
963 GetDescription ()
964 {
Greg Claytona658fd22011-06-04 01:26:29 +0000965 if (m_description.empty())
Greg Claytonf4b47e12010-08-04 01:40:35 +0000966 return "trace";
Greg Claytona658fd22011-06-04 01:26:29 +0000967 else
968 return m_description.c_str();
969 }
970};
971
972
973//----------------------------------------------------------------------
974// StopInfoException
975//----------------------------------------------------------------------
976
977class StopInfoException : public StopInfo
978{
979public:
980
981 StopInfoException (Thread &thread, const char *description) :
982 StopInfo (thread, LLDB_INVALID_UID)
983 {
984 if (description)
985 SetDescription (description);
986 }
987
988 virtual
989 ~StopInfoException ()
990 {
991 }
992
993 virtual StopReason
994 GetStopReason () const
995 {
996 return eStopReasonException;
997 }
998
999 virtual const char *
1000 GetDescription ()
1001 {
1002 if (m_description.empty())
1003 return "exception";
1004 else
1005 return m_description.c_str();
Greg Claytonf4b47e12010-08-04 01:40:35 +00001006 }
1007};
1008
1009
1010//----------------------------------------------------------------------
1011// StopInfoThreadPlan
1012//----------------------------------------------------------------------
1013
1014class StopInfoThreadPlan : public StopInfo
1015{
1016public:
1017
Jim Ingham30fadaf2014-07-08 01:07:32 +00001018 StopInfoThreadPlan (ThreadPlanSP &plan_sp, ValueObjectSP &return_valobj_sp, ClangExpressionVariableSP &expression_variable_sp) :
Greg Claytonf4b47e12010-08-04 01:40:35 +00001019 StopInfo (plan_sp->GetThread(), LLDB_INVALID_UID),
Jim Ingham73ca05a2011-12-17 01:35:57 +00001020 m_plan_sp (plan_sp),
Jim Ingham30fadaf2014-07-08 01:07:32 +00001021 m_return_valobj_sp (return_valobj_sp),
1022 m_expression_variable_sp (expression_variable_sp)
Greg Claytonf4b47e12010-08-04 01:40:35 +00001023 {
1024 }
1025
1026 virtual ~StopInfoThreadPlan ()
1027 {
1028 }
1029
1030 virtual StopReason
1031 GetStopReason () const
1032 {
1033 return eStopReasonPlanComplete;
1034 }
1035
1036 virtual const char *
1037 GetDescription ()
1038 {
1039 if (m_description.empty())
1040 {
1041 StreamString strm;
1042 m_plan_sp->GetDescription (&strm, eDescriptionLevelBrief);
1043 m_description.swap (strm.GetString());
1044 }
1045 return m_description.c_str();
1046 }
Jim Ingham73ca05a2011-12-17 01:35:57 +00001047
1048 ValueObjectSP
1049 GetReturnValueObject()
1050 {
1051 return m_return_valobj_sp;
1052 }
Jim Ingham0161b492013-02-09 01:29:05 +00001053
Jim Ingham30fadaf2014-07-08 01:07:32 +00001054 ClangExpressionVariableSP
1055 GetExpressionVariable()
1056 {
1057 return m_expression_variable_sp;
1058 }
1059
Jim Ingham0161b492013-02-09 01:29:05 +00001060protected:
1061 virtual bool
1062 ShouldStop (Event *event_ptr)
1063 {
1064 if (m_plan_sp)
1065 return m_plan_sp->ShouldStop(event_ptr);
1066 else
1067 return StopInfo::ShouldStop(event_ptr);
1068 }
Greg Claytonf4b47e12010-08-04 01:40:35 +00001069
1070private:
1071 ThreadPlanSP m_plan_sp;
Jim Ingham73ca05a2011-12-17 01:35:57 +00001072 ValueObjectSP m_return_valobj_sp;
Jim Ingham30fadaf2014-07-08 01:07:32 +00001073 ClangExpressionVariableSP m_expression_variable_sp;
Greg Claytonf4b47e12010-08-04 01:40:35 +00001074};
Greg Clayton90ba8112012-12-05 00:16:59 +00001075
1076class StopInfoExec : public StopInfo
1077{
1078public:
1079
1080 StopInfoExec (Thread &thread) :
1081 StopInfo (thread, LLDB_INVALID_UID),
1082 m_performed_action (false)
1083 {
1084 }
1085
1086 virtual
1087 ~StopInfoExec ()
1088 {
1089 }
1090
1091 virtual StopReason
1092 GetStopReason () const
1093 {
1094 return eStopReasonExec;
1095 }
1096
1097 virtual const char *
1098 GetDescription ()
1099 {
1100 return "exec";
1101 }
1102protected:
Greg Clayton90ba8112012-12-05 00:16:59 +00001103
1104 virtual void
1105 PerformAction (Event *event_ptr)
1106 {
1107 // Only perform the action once
1108 if (m_performed_action)
1109 return;
1110 m_performed_action = true;
Greg Clayton46c2b6e2013-04-29 23:30:46 +00001111 ThreadSP thread_sp (m_thread_wp.lock());
1112 if (thread_sp)
1113 thread_sp->GetProcess()->DidExec();
Greg Clayton90ba8112012-12-05 00:16:59 +00001114 }
1115
1116 bool m_performed_action;
1117};
1118
Jim Ingham4b536182011-08-09 02:12:22 +00001119} // namespace lldb_private
Greg Claytonf4b47e12010-08-04 01:40:35 +00001120
1121StopInfoSP
1122StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id)
1123{
1124 return StopInfoSP (new StopInfoBreakpoint (thread, break_id));
1125}
1126
1127StopInfoSP
Jim Ingham36f3b362010-10-14 23:45:03 +00001128StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id, bool should_stop)
1129{
1130 return StopInfoSP (new StopInfoBreakpoint (thread, break_id, should_stop));
1131}
1132
1133StopInfoSP
Greg Claytonf4b47e12010-08-04 01:40:35 +00001134StopInfo::CreateStopReasonWithWatchpointID (Thread &thread, break_id_t watch_id)
1135{
1136 return StopInfoSP (new StopInfoWatchpoint (thread, watch_id));
1137}
1138
1139StopInfoSP
1140StopInfo::CreateStopReasonWithSignal (Thread &thread, int signo)
1141{
1142 return StopInfoSP (new StopInfoUnixSignal (thread, signo));
1143}
1144
1145StopInfoSP
1146StopInfo::CreateStopReasonToTrace (Thread &thread)
1147{
1148 return StopInfoSP (new StopInfoTrace (thread));
1149}
1150
1151StopInfoSP
Jim Ingham30fadaf2014-07-08 01:07:32 +00001152StopInfo::CreateStopReasonWithPlan (ThreadPlanSP &plan_sp,
1153 ValueObjectSP return_valobj_sp,
1154 ClangExpressionVariableSP expression_variable_sp)
Greg Claytonf4b47e12010-08-04 01:40:35 +00001155{
Jim Ingham30fadaf2014-07-08 01:07:32 +00001156 return StopInfoSP (new StopInfoThreadPlan (plan_sp, return_valobj_sp, expression_variable_sp));
Greg Claytonf4b47e12010-08-04 01:40:35 +00001157}
Greg Claytona658fd22011-06-04 01:26:29 +00001158
1159StopInfoSP
1160StopInfo::CreateStopReasonWithException (Thread &thread, const char *description)
1161{
1162 return StopInfoSP (new StopInfoException (thread, description));
1163}
Jim Ingham73ca05a2011-12-17 01:35:57 +00001164
Greg Clayton90ba8112012-12-05 00:16:59 +00001165StopInfoSP
1166StopInfo::CreateStopReasonWithExec (Thread &thread)
1167{
1168 return StopInfoSP (new StopInfoExec (thread));
1169}
1170
Jim Ingham73ca05a2011-12-17 01:35:57 +00001171ValueObjectSP
1172StopInfo::GetReturnValueObject(StopInfoSP &stop_info_sp)
1173{
1174 if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonPlanComplete)
1175 {
1176 StopInfoThreadPlan *plan_stop_info = static_cast<StopInfoThreadPlan *>(stop_info_sp.get());
1177 return plan_stop_info->GetReturnValueObject();
1178 }
1179 else
1180 return ValueObjectSP();
1181}
Jim Ingham30fadaf2014-07-08 01:07:32 +00001182
1183ClangExpressionVariableSP
1184StopInfo::GetExpressionVariable(StopInfoSP &stop_info_sp)
1185{
1186 if (stop_info_sp && stop_info_sp->GetStopReason() == eStopReasonPlanComplete)
1187 {
1188 StopInfoThreadPlan *plan_stop_info = static_cast<StopInfoThreadPlan *>(stop_info_sp.get());
1189 return plan_stop_info->GetExpressionVariable();
1190 }
1191 else
1192 return ClangExpressionVariableSP();
1193}