1 //===-- StopInfo.cpp ------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include <string>
10
11 #include "lldb/Breakpoint/Breakpoint.h"
12 #include "lldb/Breakpoint/BreakpointLocation.h"
13 #include "lldb/Breakpoint/StoppointCallbackContext.h"
14 #include "lldb/Breakpoint/Watchpoint.h"
15 #include "lldb/Core/Debugger.h"
16 #include "lldb/Core/ValueObject.h"
17 #include "lldb/Expression/UserExpression.h"
18 #include "lldb/Target/Process.h"
19 #include "lldb/Target/StopInfo.h"
20 #include "lldb/Target/Target.h"
21 #include "lldb/Target/Thread.h"
22 #include "lldb/Target/ThreadPlan.h"
23 #include "lldb/Target/ThreadPlanStepInstruction.h"
24 #include "lldb/Target/UnixSignals.h"
25 #include "lldb/Utility/LLDBLog.h"
26 #include "lldb/Utility/Log.h"
27 #include "lldb/Utility/StreamString.h"
28
29 using namespace lldb;
30 using namespace lldb_private;
31
StopInfo(Thread & thread,uint64_t value)32 StopInfo::StopInfo(Thread &thread, uint64_t value)
33 : m_thread_wp(thread.shared_from_this()),
34 m_stop_id(thread.GetProcess()->GetStopID()),
35 m_resume_id(thread.GetProcess()->GetResumeID()), m_value(value),
36 m_description(), m_override_should_notify(eLazyBoolCalculate),
37 m_override_should_stop(eLazyBoolCalculate), m_extended_info() {}
38
IsValid() const39 bool StopInfo::IsValid() const {
40 ThreadSP thread_sp(m_thread_wp.lock());
41 if (thread_sp)
42 return thread_sp->GetProcess()->GetStopID() == m_stop_id;
43 return false;
44 }
45
MakeStopInfoValid()46 void StopInfo::MakeStopInfoValid() {
47 ThreadSP thread_sp(m_thread_wp.lock());
48 if (thread_sp) {
49 m_stop_id = thread_sp->GetProcess()->GetStopID();
50 m_resume_id = thread_sp->GetProcess()->GetResumeID();
51 }
52 }
53
HasTargetRunSinceMe()54 bool StopInfo::HasTargetRunSinceMe() {
55 ThreadSP thread_sp(m_thread_wp.lock());
56
57 if (thread_sp) {
58 lldb::StateType ret_type = thread_sp->GetProcess()->GetPrivateState();
59 if (ret_type == eStateRunning) {
60 return true;
61 } else if (ret_type == eStateStopped) {
62 // This is a little tricky. We want to count "run and stopped again
63 // before you could ask this question as a "TRUE" answer to
64 // HasTargetRunSinceMe. But we don't want to include any running of the
65 // target done for expressions. So we track both resumes, and resumes
66 // caused by expressions, and check if there are any resumes
67 // NOT caused
68 // by expressions.
69
70 uint32_t curr_resume_id = thread_sp->GetProcess()->GetResumeID();
71 uint32_t last_user_expression_id =
72 thread_sp->GetProcess()->GetLastUserExpressionResumeID();
73 if (curr_resume_id == m_resume_id) {
74 return false;
75 } else if (curr_resume_id > last_user_expression_id) {
76 return true;
77 }
78 }
79 }
80 return false;
81 }
82
83 // StopInfoBreakpoint
84
85 namespace lldb_private {
86 class StopInfoBreakpoint : public StopInfo {
87 public:
StopInfoBreakpoint(Thread & thread,break_id_t break_id)88 StopInfoBreakpoint(Thread &thread, break_id_t break_id)
89 : StopInfo(thread, break_id), m_should_stop(false),
90 m_should_stop_is_valid(false), m_should_perform_action(true),
91 m_address(LLDB_INVALID_ADDRESS), m_break_id(LLDB_INVALID_BREAK_ID),
92 m_was_all_internal(false), m_was_one_shot(false) {
93 StoreBPInfo();
94 }
95
StopInfoBreakpoint(Thread & thread,break_id_t break_id,bool should_stop)96 StopInfoBreakpoint(Thread &thread, break_id_t break_id, bool should_stop)
97 : StopInfo(thread, break_id), m_should_stop(should_stop),
98 m_should_stop_is_valid(true), m_should_perform_action(true),
99 m_address(LLDB_INVALID_ADDRESS), m_break_id(LLDB_INVALID_BREAK_ID),
100 m_was_all_internal(false), m_was_one_shot(false) {
101 StoreBPInfo();
102 }
103
104 ~StopInfoBreakpoint() override = default;
105
StoreBPInfo()106 void StoreBPInfo() {
107 ThreadSP thread_sp(m_thread_wp.lock());
108 if (thread_sp) {
109 BreakpointSiteSP bp_site_sp(
110 thread_sp->GetProcess()->GetBreakpointSiteList().FindByID(m_value));
111 if (bp_site_sp) {
112 uint32_t num_owners = bp_site_sp->GetNumberOfOwners();
113 if (num_owners == 1) {
114 BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(0);
115 if (bp_loc_sp) {
116 Breakpoint & bkpt = bp_loc_sp->GetBreakpoint();
117 m_break_id = bkpt.GetID();
118 m_was_one_shot = bkpt.IsOneShot();
119 m_was_all_internal = bkpt.IsInternal();
120 }
121 } else {
122 m_was_all_internal = true;
123 for (uint32_t i = 0; i < num_owners; i++) {
124 if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal()) {
125 m_was_all_internal = false;
126 break;
127 }
128 }
129 }
130 m_address = bp_site_sp->GetLoadAddress();
131 }
132 }
133 }
134
IsValidForOperatingSystemThread(Thread & thread)135 bool IsValidForOperatingSystemThread(Thread &thread) override {
136 ProcessSP process_sp(thread.GetProcess());
137 if (process_sp) {
138 BreakpointSiteSP bp_site_sp(
139 process_sp->GetBreakpointSiteList().FindByID(m_value));
140 if (bp_site_sp)
141 return bp_site_sp->ValidForThisThread(thread);
142 }
143 return false;
144 }
145
GetStopReason() const146 StopReason GetStopReason() const override { return eStopReasonBreakpoint; }
147
ShouldStopSynchronous(Event * event_ptr)148 bool ShouldStopSynchronous(Event *event_ptr) override {
149 ThreadSP thread_sp(m_thread_wp.lock());
150 if (thread_sp) {
151 if (!m_should_stop_is_valid) {
152 // Only check once if we should stop at a breakpoint
153 BreakpointSiteSP bp_site_sp(
154 thread_sp->GetProcess()->GetBreakpointSiteList().FindByID(m_value));
155 if (bp_site_sp) {
156 ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0));
157 StoppointCallbackContext context(event_ptr, exe_ctx, true);
158 bp_site_sp->BumpHitCounts();
159 m_should_stop = bp_site_sp->ShouldStop(&context);
160 } else {
161 Log *log = GetLog(LLDBLog::Process);
162
163 LLDB_LOGF(log,
164 "Process::%s could not find breakpoint site id: %" PRId64
165 "...",
166 __FUNCTION__, m_value);
167
168 m_should_stop = true;
169 }
170 m_should_stop_is_valid = true;
171 }
172 return m_should_stop;
173 }
174 return false;
175 }
176
DoShouldNotify(Event * event_ptr)177 bool DoShouldNotify(Event *event_ptr) override {
178 return !m_was_all_internal;
179 }
180
GetDescription()181 const char *GetDescription() override {
182 if (m_description.empty()) {
183 ThreadSP thread_sp(m_thread_wp.lock());
184 if (thread_sp) {
185 BreakpointSiteSP bp_site_sp(
186 thread_sp->GetProcess()->GetBreakpointSiteList().FindByID(m_value));
187 if (bp_site_sp) {
188 StreamString strm;
189 // If we have just hit an internal breakpoint, and it has a kind
190 // description, print that instead of the full breakpoint printing:
191 if (bp_site_sp->IsInternal()) {
192 size_t num_owners = bp_site_sp->GetNumberOfOwners();
193 for (size_t idx = 0; idx < num_owners; idx++) {
194 const char *kind = bp_site_sp->GetOwnerAtIndex(idx)
195 ->GetBreakpoint()
196 .GetBreakpointKind();
197 if (kind != nullptr) {
198 m_description.assign(kind);
199 return kind;
200 }
201 }
202 }
203
204 strm.Printf("breakpoint ");
205 bp_site_sp->GetDescription(&strm, eDescriptionLevelBrief);
206 m_description = std::string(strm.GetString());
207 } else {
208 StreamString strm;
209 if (m_break_id != LLDB_INVALID_BREAK_ID) {
210 BreakpointSP break_sp =
211 thread_sp->GetProcess()->GetTarget().GetBreakpointByID(
212 m_break_id);
213 if (break_sp) {
214 if (break_sp->IsInternal()) {
215 const char *kind = break_sp->GetBreakpointKind();
216 if (kind)
217 strm.Printf("internal %s breakpoint(%d).", kind, m_break_id);
218 else
219 strm.Printf("internal breakpoint(%d).", m_break_id);
220 } else {
221 strm.Printf("breakpoint %d.", m_break_id);
222 }
223 } else {
224 if (m_was_one_shot)
225 strm.Printf("one-shot breakpoint %d", m_break_id);
226 else
227 strm.Printf("breakpoint %d which has been deleted.",
228 m_break_id);
229 }
230 } else if (m_address == LLDB_INVALID_ADDRESS)
231 strm.Printf("breakpoint site %" PRIi64
232 " which has been deleted - unknown address",
233 m_value);
234 else
235 strm.Printf("breakpoint site %" PRIi64
236 " which has been deleted - was at 0x%" PRIx64,
237 m_value, m_address);
238
239 m_description = std::string(strm.GetString());
240 }
241 }
242 }
243 return m_description.c_str();
244 }
245
246 protected:
ShouldStop(Event * event_ptr)247 bool ShouldStop(Event *event_ptr) override {
248 // This just reports the work done by PerformAction or the synchronous
249 // stop. It should only ever get called after they have had a chance to
250 // run.
251 assert(m_should_stop_is_valid);
252 return m_should_stop;
253 }
254
PerformAction(Event * event_ptr)255 void PerformAction(Event *event_ptr) override {
256 if (!m_should_perform_action)
257 return;
258 m_should_perform_action = false;
259 bool internal_breakpoint = true;
260
261 ThreadSP thread_sp(m_thread_wp.lock());
262
263 if (thread_sp) {
264 Log *log = GetLog(LLDBLog::Breakpoints | LLDBLog::Step);
265
266 if (!thread_sp->IsValid()) {
267 // This shouldn't ever happen, but just in case, don't do more harm.
268 if (log) {
269 LLDB_LOGF(log, "PerformAction got called with an invalid thread.");
270 }
271 m_should_stop = true;
272 m_should_stop_is_valid = true;
273 return;
274 }
275
276 BreakpointSiteSP bp_site_sp(
277 thread_sp->GetProcess()->GetBreakpointSiteList().FindByID(m_value));
278 std::unordered_set<break_id_t> precondition_breakpoints;
279 // Breakpoints that fail their condition check are not considered to
280 // have been hit. If the only locations at this site have failed their
281 // conditions, we should change the stop-info to none. Otherwise, if we
282 // hit another breakpoint on a different thread which does stop, users
283 // will see a breakpont hit with a failed condition, which is wrong.
284 // Use this variable to tell us if that is true.
285 bool actually_hit_any_locations = false;
286 if (bp_site_sp) {
287 // Let's copy the owners list out of the site and store them in a local
288 // list. That way if one of the breakpoint actions changes the site,
289 // then we won't be operating on a bad list.
290 BreakpointLocationCollection site_locations;
291 size_t num_owners = bp_site_sp->CopyOwnersList(site_locations);
292
293 if (num_owners == 0) {
294 m_should_stop = true;
295 actually_hit_any_locations = true; // We're going to stop, don't
296 // change the stop info.
297 } else {
298 // We go through each location, and test first its precondition -
299 // this overrides everything. Note, we only do this once per
300 // breakpoint - not once per location... Then check the condition.
301 // If the condition says to stop, then we run the callback for that
302 // location. If that callback says to stop as well, then we set
303 // m_should_stop to true; we are going to stop. But we still want to
304 // give all the breakpoints whose conditions say we are going to stop
305 // a chance to run their callbacks. Of course if any callback
306 // restarts the target by putting "continue" in the callback, then
307 // we're going to restart, without running the rest of the callbacks.
308 // And in this case we will end up not stopping even if another
309 // location said we should stop. But that's better than not running
310 // all the callbacks.
311
312 // There's one other complication here. We may have run an async
313 // breakpoint callback that said we should stop. We only want to
314 // override that if another breakpoint action says we shouldn't
315 // stop. If nobody else has an opinion, then we should stop if the
316 // async callback says we should. An example of this is the async
317 // shared library load notification breakpoint and the setting
318 // stop-on-sharedlibrary-events.
319 // We'll keep the async value in async_should_stop, and track whether
320 // anyone said we should NOT stop in actually_said_continue.
321 bool async_should_stop = false;
322 if (m_should_stop_is_valid)
323 async_should_stop = m_should_stop;
324 bool actually_said_continue = false;
325
326 m_should_stop = false;
327
328 // We don't select threads as we go through them testing breakpoint
329 // conditions and running commands. So we need to set the thread for
330 // expression evaluation here:
331 ThreadList::ExpressionExecutionThreadPusher thread_pusher(thread_sp);
332
333 ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0));
334 Process *process = exe_ctx.GetProcessPtr();
335 if (process->GetModIDRef().IsLastResumeForUserExpression()) {
336 // If we are in the middle of evaluating an expression, don't run
337 // asynchronous breakpoint commands or expressions. That could
338 // lead to infinite recursion if the command or condition re-calls
339 // the function with this breakpoint.
340 // TODO: We can keep a list of the breakpoints we've seen while
341 // running expressions in the nested
342 // PerformAction calls that can arise when the action runs a
343 // function that hits another breakpoint, and only stop running
344 // commands when we see the same breakpoint hit a second time.
345
346 m_should_stop_is_valid = true;
347
348 // It is possible that the user has a breakpoint at the same site
349 // as the completed plan had (e.g. user has a breakpoint
350 // on a module entry point, and `ThreadPlanCallFunction` ends
351 // also there). We can't find an internal breakpoint in the loop
352 // later because it was already removed on the plan completion.
353 // So check if the plan was completed, and stop if so.
354 if (thread_sp->CompletedPlanOverridesBreakpoint()) {
355 m_should_stop = true;
356 thread_sp->ResetStopInfo();
357 return;
358 }
359
360 LLDB_LOGF(log, "StopInfoBreakpoint::PerformAction - Hit a "
361 "breakpoint while running an expression,"
362 " not running commands to avoid recursion.");
363 bool ignoring_breakpoints =
364 process->GetIgnoreBreakpointsInExpressions();
365 // Internal breakpoints should be allowed to do their job, we
366 // can make sure they don't do anything that would cause recursive
367 // command execution:
368 if (!m_was_all_internal) {
369 m_should_stop = !ignoring_breakpoints;
370 LLDB_LOGF(log,
371 "StopInfoBreakpoint::PerformAction - in expression, "
372 "continuing: %s.",
373 m_should_stop ? "true" : "false");
374 Debugger::ReportWarning(
375 "hit breakpoint while running function, skipping commands "
376 "and conditions to prevent recursion",
377 process->GetTarget().GetDebugger().GetID());
378 return;
379 }
380 }
381
382 StoppointCallbackContext context(event_ptr, exe_ctx, false);
383
384 // For safety's sake let's also grab an extra reference to the
385 // breakpoint owners of the locations we're going to examine, since
386 // the locations are going to have to get back to their breakpoints,
387 // and the locations don't keep their owners alive. I'm just
388 // sticking the BreakpointSP's in a vector since I'm only using it to
389 // locally increment their retain counts.
390
391 std::vector<lldb::BreakpointSP> location_owners;
392
393 for (size_t j = 0; j < num_owners; j++) {
394 BreakpointLocationSP loc(site_locations.GetByIndex(j));
395 location_owners.push_back(loc->GetBreakpoint().shared_from_this());
396 }
397
398 for (size_t j = 0; j < num_owners; j++) {
399 lldb::BreakpointLocationSP bp_loc_sp = site_locations.GetByIndex(j);
400 StreamString loc_desc;
401 if (log) {
402 bp_loc_sp->GetDescription(&loc_desc, eDescriptionLevelBrief);
403 }
404 // If another action disabled this breakpoint or its location, then
405 // don't run the actions.
406 if (!bp_loc_sp->IsEnabled() ||
407 !bp_loc_sp->GetBreakpoint().IsEnabled())
408 continue;
409
410 // The breakpoint site may have many locations associated with it,
411 // not all of them valid for this thread. Skip the ones that
412 // aren't:
413 if (!bp_loc_sp->ValidForThisThread(*thread_sp)) {
414 if (log) {
415 LLDB_LOGF(log,
416 "Breakpoint %s hit on thread 0x%llx but it was not "
417 "for this thread, continuing.",
418 loc_desc.GetData(),
419 static_cast<unsigned long long>(thread_sp->GetID()));
420 }
421 continue;
422 }
423
424 internal_breakpoint = bp_loc_sp->GetBreakpoint().IsInternal();
425
426 // First run the precondition, but since the precondition is per
427 // breakpoint, only run it once per breakpoint.
428 std::pair<std::unordered_set<break_id_t>::iterator, bool> result =
429 precondition_breakpoints.insert(
430 bp_loc_sp->GetBreakpoint().GetID());
431 if (!result.second)
432 continue;
433
434 bool precondition_result =
435 bp_loc_sp->GetBreakpoint().EvaluatePrecondition(context);
436 if (!precondition_result) {
437 actually_said_continue = true;
438 continue;
439 }
440 // Next run the condition for the breakpoint. If that says we
441 // should stop, then we'll run the callback for the breakpoint. If
442 // the callback says we shouldn't stop that will win.
443
444 if (bp_loc_sp->GetConditionText() == nullptr)
445 actually_hit_any_locations = true;
446 else {
447 Status condition_error;
448 bool condition_says_stop =
449 bp_loc_sp->ConditionSaysStop(exe_ctx, condition_error);
450
451 if (!condition_error.Success()) {
452 // If the condition fails to evaluate, we are going to stop
453 // at it, so the location was hit.
454 actually_hit_any_locations = true;
455 const char *err_str =
456 condition_error.AsCString("<unknown error>");
457 LLDB_LOGF(log, "Error evaluating condition: \"%s\"\n", err_str);
458
459 StreamString strm;
460 strm << "stopped due to an error evaluating condition of "
461 "breakpoint ";
462 bp_loc_sp->GetDescription(&strm, eDescriptionLevelBrief);
463 strm << ": \"" << bp_loc_sp->GetConditionText() << "\"\n";
464 strm << err_str;
465
466 Debugger::ReportError(
467 strm.GetString().str(),
468 exe_ctx.GetTargetRef().GetDebugger().GetID());
469 } else {
470 LLDB_LOGF(log,
471 "Condition evaluated for breakpoint %s on thread "
472 "0x%llx condition_says_stop: %i.",
473 loc_desc.GetData(),
474 static_cast<unsigned long long>(thread_sp->GetID()),
475 condition_says_stop);
476 if (condition_says_stop)
477 actually_hit_any_locations = true;
478 else {
479 // We don't want to increment the hit count of breakpoints if
480 // the condition fails. We've already bumped it by the time
481 // we get here, so undo the bump:
482 bp_loc_sp->UndoBumpHitCount();
483 actually_said_continue = true;
484 continue;
485 }
486 }
487 }
488
489 // We've done all the checks whose failure means "we consider lldb
490 // not to have hit the breakpoint". Now we're going to check for
491 // conditions that might continue after hitting. Start with the
492 // ignore count:
493 if (!bp_loc_sp->IgnoreCountShouldStop()) {
494 actually_said_continue = true;
495 continue;
496 }
497
498 // Check the auto-continue bit on the location, do this before the
499 // callback since it may change this, but that would be for the
500 // NEXT hit. Note, you might think you could check auto-continue
501 // before the condition, and not evaluate the condition if it says
502 // to continue. But failing the condition means the breakpoint was
503 // effectively NOT HIT. So these two states are different.
504 bool auto_continue_says_stop = true;
505 if (bp_loc_sp->IsAutoContinue())
506 {
507 LLDB_LOGF(log,
508 "Continuing breakpoint %s as AutoContinue was set.",
509 loc_desc.GetData());
510 // We want this stop reported, so you will know we auto-continued
511 // but only for external breakpoints:
512 if (!internal_breakpoint)
513 thread_sp->SetShouldReportStop(eVoteYes);
514 auto_continue_says_stop = false;
515 }
516
517 bool callback_says_stop = true;
518
519 // FIXME: For now the callbacks have to run in async mode - the
520 // first time we restart we need
521 // to get out of there. So set it here.
522 // When we figure out how to nest breakpoint hits then this will
523 // change.
524
525 // Don't run async callbacks in PerformAction. They have already
526 // been taken into account with async_should_stop.
527 if (!bp_loc_sp->IsCallbackSynchronous()) {
528 Debugger &debugger = thread_sp->CalculateTarget()->GetDebugger();
529 bool old_async = debugger.GetAsyncExecution();
530 debugger.SetAsyncExecution(true);
531
532 callback_says_stop = bp_loc_sp->InvokeCallback(&context);
533
534 debugger.SetAsyncExecution(old_async);
535
536 if (callback_says_stop && auto_continue_says_stop)
537 m_should_stop = true;
538 else
539 actually_said_continue = true;
540 }
541
542 // If we are going to stop for this breakpoint, then remove the
543 // breakpoint.
544 if (callback_says_stop && bp_loc_sp &&
545 bp_loc_sp->GetBreakpoint().IsOneShot()) {
546 thread_sp->GetProcess()->GetTarget().RemoveBreakpointByID(
547 bp_loc_sp->GetBreakpoint().GetID());
548 }
549 // Also make sure that the callback hasn't continued the target. If
550 // it did, when we'll set m_should_start to false and get out of
551 // here.
552 if (HasTargetRunSinceMe()) {
553 m_should_stop = false;
554 actually_said_continue = true;
555 break;
556 }
557 }
558 // At this point if nobody actually told us to continue, we should
559 // give the async breakpoint callback a chance to weigh in:
560 if (!actually_said_continue && !m_should_stop) {
561 m_should_stop = async_should_stop;
562 }
563 }
564 // We've figured out what this stop wants to do, so mark it as valid so
565 // we don't compute it again.
566 m_should_stop_is_valid = true;
567 } else {
568 m_should_stop = true;
569 m_should_stop_is_valid = true;
570 actually_hit_any_locations = true;
571 Log *log_process(GetLog(LLDBLog::Process));
572
573 LLDB_LOGF(log_process,
574 "Process::%s could not find breakpoint site id: %" PRId64
575 "...",
576 __FUNCTION__, m_value);
577 }
578
579 if ((!m_should_stop || internal_breakpoint) &&
580 thread_sp->CompletedPlanOverridesBreakpoint()) {
581
582 // Override should_stop decision when we have completed step plan
583 // additionally to the breakpoint
584 m_should_stop = true;
585
586 // We know we're stopping for a completed plan and we don't want to
587 // show the breakpoint stop, so compute the public stop info immediately
588 // here.
589 thread_sp->CalculatePublicStopInfo();
590 } else if (!actually_hit_any_locations) {
591 // In the end, we didn't actually have any locations that passed their
592 // "was I hit" checks. So say we aren't stopped.
593 GetThread()->ResetStopInfo();
594 LLDB_LOGF(log, "Process::%s all locations failed condition checks.",
595 __FUNCTION__);
596 }
597
598 LLDB_LOGF(log,
599 "Process::%s returning from action with m_should_stop: %d.",
600 __FUNCTION__, m_should_stop);
601 }
602 }
603
604 private:
605 bool m_should_stop;
606 bool m_should_stop_is_valid;
607 bool m_should_perform_action; // Since we are trying to preserve the "state"
608 // of the system even if we run functions
609 // etc. behind the users backs, we need to make sure we only REALLY perform
610 // the action once.
611 lldb::addr_t m_address; // We use this to capture the breakpoint site address
612 // when we create the StopInfo,
613 // in case somebody deletes it between the time the StopInfo is made and the
614 // description is asked for.
615 lldb::break_id_t m_break_id;
616 bool m_was_all_internal;
617 bool m_was_one_shot;
618 };
619
620 // StopInfoWatchpoint
621
622 class StopInfoWatchpoint : public StopInfo {
623 public:
624 // Make sure watchpoint is properly disabled and subsequently enabled while
625 // performing watchpoint actions.
626 class WatchpointSentry {
627 public:
WatchpointSentry(ProcessSP p_sp,WatchpointSP w_sp)628 WatchpointSentry(ProcessSP p_sp, WatchpointSP w_sp) : process_sp(p_sp),
629 watchpoint_sp(w_sp) {
630 if (process_sp && watchpoint_sp) {
631 const bool notify = false;
632 watchpoint_sp->TurnOnEphemeralMode();
633 process_sp->DisableWatchpoint(watchpoint_sp.get(), notify);
634 process_sp->AddPreResumeAction(SentryPreResumeAction, this);
635 }
636 }
637
DoReenable()638 void DoReenable() {
639 if (process_sp && watchpoint_sp) {
640 bool was_disabled = watchpoint_sp->IsDisabledDuringEphemeralMode();
641 watchpoint_sp->TurnOffEphemeralMode();
642 const bool notify = false;
643 if (was_disabled) {
644 process_sp->DisableWatchpoint(watchpoint_sp.get(), notify);
645 } else {
646 process_sp->EnableWatchpoint(watchpoint_sp.get(), notify);
647 }
648 }
649 }
650
~WatchpointSentry()651 ~WatchpointSentry() {
652 DoReenable();
653 if (process_sp)
654 process_sp->ClearPreResumeAction(SentryPreResumeAction, this);
655 }
656
SentryPreResumeAction(void * sentry_void)657 static bool SentryPreResumeAction(void *sentry_void) {
658 WatchpointSentry *sentry = (WatchpointSentry *) sentry_void;
659 sentry->DoReenable();
660 return true;
661 }
662
663 private:
664 ProcessSP process_sp;
665 WatchpointSP watchpoint_sp;
666 };
667
StopInfoWatchpoint(Thread & thread,break_id_t watch_id,lldb::addr_t watch_hit_addr)668 StopInfoWatchpoint(Thread &thread, break_id_t watch_id,
669 lldb::addr_t watch_hit_addr)
670 : StopInfo(thread, watch_id), m_watch_hit_addr(watch_hit_addr) {}
671
672 ~StopInfoWatchpoint() override = default;
673
GetStopReason() const674 StopReason GetStopReason() const override { return eStopReasonWatchpoint; }
675
GetDescription()676 const char *GetDescription() override {
677 if (m_description.empty()) {
678 StreamString strm;
679 strm.Printf("watchpoint %" PRIi64, m_value);
680 m_description = std::string(strm.GetString());
681 }
682 return m_description.c_str();
683 }
684
685 protected:
686 using StopInfoWatchpointSP = std::shared_ptr<StopInfoWatchpoint>;
687 // This plan is used to orchestrate stepping over the watchpoint for
688 // architectures (e.g. ARM) that report the watch before running the watched
689 // access. This is the sort of job you have to defer to the thread plans,
690 // if you try to do it directly in the stop info and there are other threads
691 // that needed to process this stop you will have yanked control away from
692 // them and they won't behave correctly.
693 class ThreadPlanStepOverWatchpoint : public ThreadPlanStepInstruction {
694 public:
ThreadPlanStepOverWatchpoint(Thread & thread,StopInfoWatchpointSP stop_info_sp,WatchpointSP watch_sp)695 ThreadPlanStepOverWatchpoint(Thread &thread,
696 StopInfoWatchpointSP stop_info_sp,
697 WatchpointSP watch_sp)
698 : ThreadPlanStepInstruction(thread, false, true, eVoteNoOpinion,
699 eVoteNoOpinion),
700 m_stop_info_sp(stop_info_sp), m_watch_sp(watch_sp) {
701 assert(watch_sp);
702 m_watch_index = watch_sp->GetHardwareIndex();
703 }
704
DoWillResume(lldb::StateType resume_state,bool current_plan)705 bool DoWillResume(lldb::StateType resume_state,
706 bool current_plan) override {
707 if (resume_state == eStateSuspended)
708 return true;
709
710 if (!m_did_disable_wp) {
711 GetThread().GetProcess()->DisableWatchpoint(m_watch_sp.get(), false);
712 m_did_disable_wp = true;
713 }
714 return true;
715 }
716
DoPlanExplainsStop(Event * event_ptr)717 bool DoPlanExplainsStop(Event *event_ptr) override {
718 if (ThreadPlanStepInstruction::DoPlanExplainsStop(event_ptr))
719 return true;
720 StopInfoSP stop_info_sp = GetThread().GetPrivateStopInfo();
721 // lldb-server resets the stop info for threads that didn't get to run,
722 // so we might have not gotten to run, but still have a watchpoint stop
723 // reason, in which case this will indeed be for us.
724 if (stop_info_sp
725 && stop_info_sp->GetStopReason() == eStopReasonWatchpoint)
726 return true;
727 return false;
728 }
729
DidPop()730 void DidPop() override {
731 // Don't artifically keep the watchpoint alive.
732 m_watch_sp.reset();
733 }
734
ShouldStop(Event * event_ptr)735 bool ShouldStop(Event *event_ptr) override {
736 bool should_stop = ThreadPlanStepInstruction::ShouldStop(event_ptr);
737 bool plan_done = MischiefManaged();
738 if (plan_done) {
739 m_stop_info_sp->SetStepOverPlanComplete();
740 GetThread().SetStopInfo(m_stop_info_sp);
741 ResetWatchpoint();
742 }
743 return should_stop;
744 }
745
ShouldRunBeforePublicStop()746 bool ShouldRunBeforePublicStop() override {
747 return true;
748 }
749
750 protected:
ResetWatchpoint()751 void ResetWatchpoint() {
752 if (!m_did_disable_wp)
753 return;
754 m_did_disable_wp = true;
755 GetThread().GetProcess()->EnableWatchpoint(m_watch_sp.get(), true);
756 m_watch_sp->SetHardwareIndex(m_watch_index);
757 }
758
759 private:
760 StopInfoWatchpointSP m_stop_info_sp;
761 WatchpointSP m_watch_sp;
762 uint32_t m_watch_index = LLDB_INVALID_INDEX32;
763 bool m_did_disable_wp = false;
764 };
765
ShouldStopSynchronous(Event * event_ptr)766 bool ShouldStopSynchronous(Event *event_ptr) override {
767 // If we are running our step-over the watchpoint plan, stop if it's done
768 // and continue if it's not:
769 if (m_should_stop_is_valid)
770 return m_should_stop;
771
772 // If we are running our step over plan, then stop here and let the regular
773 // ShouldStop figure out what we should do: Otherwise, give our plan
774 // more time to get run:
775 if (m_using_step_over_plan)
776 return m_step_over_plan_complete;
777
778 Log *log = GetLog(LLDBLog::Process);
779 ThreadSP thread_sp(m_thread_wp.lock());
780 assert(thread_sp);
781
782 if (thread_sp->GetTemporaryResumeState() == eStateSuspended) {
783 // This is the second firing of a watchpoint so don't process it again.
784 LLDB_LOG(log, "We didn't run but stopped with a StopInfoWatchpoint, we "
785 "have already handled this one, don't do it again.");
786 m_should_stop = false;
787 m_should_stop_is_valid = true;
788 return m_should_stop;
789 }
790
791 WatchpointSP wp_sp(
792 thread_sp->CalculateTarget()->GetWatchpointList().FindByID(GetValue()));
793 // If we can no longer find the watchpoint, we just have to stop:
794 if (!wp_sp) {
795
796 LLDB_LOGF(log,
797 "Process::%s could not find watchpoint location id: %" PRId64
798 "...",
799 __FUNCTION__, GetValue());
800
801 m_should_stop = true;
802 m_should_stop_is_valid = true;
803 return true;
804 }
805
806 ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0));
807 StoppointCallbackContext context(event_ptr, exe_ctx, true);
808 m_should_stop = wp_sp->ShouldStop(&context);
809 if (!m_should_stop) {
810 // This won't happen at present because we only allow one watchpoint per
811 // watched range. So we won't stop at a watched address with a disabled
812 // watchpoint. If we start allowing overlapping watchpoints, then we
813 // will have to make watchpoints be real "WatchpointSite" and delegate to
814 // all the watchpoints sharing the site. In that case, the code below
815 // would be the right thing to do.
816 m_should_stop_is_valid = true;
817 return m_should_stop;
818 }
819 // If this is a system where we need to execute the watchpoint by hand
820 // after the hit, queue a thread plan to do that, and then say not to stop.
821 // Otherwise, let the async action figure out whether the watchpoint should
822 // stop
823
824 ProcessSP process_sp = exe_ctx.GetProcessSP();
825 uint32_t num;
826 bool wp_triggers_after;
827
828 if (!process_sp->GetWatchpointSupportInfo(num, wp_triggers_after)
829 .Success()) {
830 m_should_stop_is_valid = true;
831 m_should_stop = true;
832 return m_should_stop;
833 }
834
835 if (!wp_triggers_after) {
836 // We have to step over the watchpoint before we know what to do:
837 StopInfoWatchpointSP me_as_siwp_sp
838 = std::static_pointer_cast<StopInfoWatchpoint>(shared_from_this());
839 ThreadPlanSP step_over_wp_sp(new ThreadPlanStepOverWatchpoint(
840 *(thread_sp.get()), me_as_siwp_sp, wp_sp));
841 Status error;
842 error = thread_sp->QueueThreadPlan(step_over_wp_sp, false);
843 // If we couldn't push the thread plan, just stop here:
844 if (!error.Success()) {
845 LLDB_LOGF(log, "Could not push our step over watchpoint plan: %s",
846 error.AsCString());
847
848 m_should_stop = true;
849 m_should_stop_is_valid = true;
850 return true;
851 } else {
852 // Otherwise, don't set m_should_stop, we don't know that yet. Just
853 // say we should continue, and tell the thread we really should do so:
854 thread_sp->SetShouldRunBeforePublicStop(true);
855 m_using_step_over_plan = true;
856 return false;
857 }
858 } else {
859 // We didn't have to do anything special
860 m_should_stop_is_valid = true;
861 return m_should_stop;
862 }
863
864 return m_should_stop;
865 }
866
ShouldStop(Event * event_ptr)867 bool ShouldStop(Event *event_ptr) override {
868 // This just reports the work done by PerformAction or the synchronous
869 // stop. It should only ever get called after they have had a chance to
870 // run.
871 assert(m_should_stop_is_valid);
872 return m_should_stop;
873 }
874
PerformAction(Event * event_ptr)875 void PerformAction(Event *event_ptr) override {
876 Log *log = GetLog(LLDBLog::Watchpoints);
877 // We're going to calculate if we should stop or not in some way during the
878 // course of this code. Also by default we're going to stop, so set that
879 // here.
880 m_should_stop = true;
881
882
883 ThreadSP thread_sp(m_thread_wp.lock());
884 if (thread_sp) {
885
886 WatchpointSP wp_sp(
887 thread_sp->CalculateTarget()->GetWatchpointList().FindByID(
888 GetValue()));
889 if (wp_sp) {
890 // This sentry object makes sure the current watchpoint is disabled
891 // while performing watchpoint actions, and it is then enabled after we
892 // are finished.
893 ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0));
894 ProcessSP process_sp = exe_ctx.GetProcessSP();
895
896 WatchpointSentry sentry(process_sp, wp_sp);
897
898 /*
899 * MIPS: Last 3bits of the watchpoint address are masked by the kernel.
900 * For example:
901 * 'n' is at 0x120010d00 and 'm' is 0x120010d04. When a watchpoint is
902 * set at 'm', then
903 * watch exception is generated even when 'n' is read/written. To handle
904 * this case,
905 * server emulates the instruction at PC and finds the base address of
906 * the load/store
907 * instruction and appends it in the description of the stop-info
908 * packet. If watchpoint
909 * is not set on this address by user then this do not stop.
910 */
911 if (m_watch_hit_addr != LLDB_INVALID_ADDRESS) {
912 WatchpointSP wp_hit_sp =
913 thread_sp->CalculateTarget()->GetWatchpointList().FindByAddress(
914 m_watch_hit_addr);
915 if (!wp_hit_sp) {
916 m_should_stop = false;
917 wp_sp->IncrementFalseAlarmsAndReviseHitCount();
918 }
919 }
920
921 if (wp_sp->GetHitCount() <= wp_sp->GetIgnoreCount()) {
922 m_should_stop = false;
923 m_should_stop_is_valid = true;
924 }
925
926 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
927
928 if (m_should_stop && wp_sp->GetConditionText() != nullptr) {
929 // We need to make sure the user sees any parse errors in their
930 // condition, so we'll hook the constructor errors up to the
931 // debugger's Async I/O.
932 ExpressionResults result_code;
933 EvaluateExpressionOptions expr_options;
934 expr_options.SetUnwindOnError(true);
935 expr_options.SetIgnoreBreakpoints(true);
936 ValueObjectSP result_value_sp;
937 Status error;
938 result_code = UserExpression::Evaluate(
939 exe_ctx, expr_options, wp_sp->GetConditionText(),
940 llvm::StringRef(), result_value_sp, error);
941
942 if (result_code == eExpressionCompleted) {
943 if (result_value_sp) {
944 Scalar scalar_value;
945 if (result_value_sp->ResolveValue(scalar_value)) {
946 if (scalar_value.ULongLong(1) == 0) {
947 // The condition failed, which we consider "not having hit
948 // the watchpoint" so undo the hit count here.
949 wp_sp->UndoHitCount();
950 m_should_stop = false;
951 } else
952 m_should_stop = true;
953 LLDB_LOGF(log,
954 "Condition successfully evaluated, result is %s.\n",
955 m_should_stop ? "true" : "false");
956 } else {
957 m_should_stop = true;
958 LLDB_LOGF(
959 log,
960 "Failed to get an integer result from the expression.");
961 }
962 }
963 } else {
964 const char *err_str = error.AsCString("<unknown error>");
965 LLDB_LOGF(log, "Error evaluating condition: \"%s\"\n", err_str);
966
967 StreamString strm;
968 strm << "stopped due to an error evaluating condition of "
969 "watchpoint ";
970 wp_sp->GetDescription(&strm, eDescriptionLevelBrief);
971 strm << ": \"" << wp_sp->GetConditionText() << "\"\n";
972 strm << err_str;
973
974 Debugger::ReportError(strm.GetString().str(),
975 exe_ctx.GetTargetRef().GetDebugger().GetID());
976 }
977 }
978
979 // If the condition says to stop, we run the callback to further decide
980 // whether to stop.
981 if (m_should_stop) {
982 // FIXME: For now the callbacks have to run in async mode - the
983 // first time we restart we need
984 // to get out of there. So set it here.
985 // When we figure out how to nest watchpoint hits then this will
986 // change.
987
988 bool old_async = debugger.GetAsyncExecution();
989 debugger.SetAsyncExecution(true);
990
991 StoppointCallbackContext context(event_ptr, exe_ctx, false);
992 bool stop_requested = wp_sp->InvokeCallback(&context);
993
994 debugger.SetAsyncExecution(old_async);
995
996 // Also make sure that the callback hasn't continued the target. If
997 // it did, when we'll set m_should_stop to false and get out of here.
998 if (HasTargetRunSinceMe())
999 m_should_stop = false;
1000
1001 if (m_should_stop && !stop_requested) {
1002 // We have been vetoed by the callback mechanism.
1003 m_should_stop = false;
1004 }
1005 }
1006 // Finally, if we are going to stop, print out the new & old values:
1007 if (m_should_stop) {
1008 wp_sp->CaptureWatchedValue(exe_ctx);
1009
1010 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
1011 StreamSP output_sp = debugger.GetAsyncOutputStream();
1012 wp_sp->DumpSnapshots(output_sp.get());
1013 output_sp->EOL();
1014 output_sp->Flush();
1015 }
1016
1017 } else {
1018 Log *log_process(GetLog(LLDBLog::Process));
1019
1020 LLDB_LOGF(log_process,
1021 "Process::%s could not find watchpoint id: %" PRId64 "...",
1022 __FUNCTION__, m_value);
1023 }
1024 LLDB_LOGF(log,
1025 "Process::%s returning from action with m_should_stop: %d.",
1026 __FUNCTION__, m_should_stop);
1027
1028 m_should_stop_is_valid = true;
1029 }
1030 }
1031
1032 private:
SetStepOverPlanComplete()1033 void SetStepOverPlanComplete() {
1034 assert(m_using_step_over_plan);
1035 m_step_over_plan_complete = true;
1036 }
1037
1038 bool m_should_stop = false;
1039 bool m_should_stop_is_valid = false;
1040 lldb::addr_t m_watch_hit_addr;
1041 bool m_step_over_plan_complete = false;
1042 bool m_using_step_over_plan = false;
1043 };
1044
1045 // StopInfoUnixSignal
1046
1047 class StopInfoUnixSignal : public StopInfo {
1048 public:
StopInfoUnixSignal(Thread & thread,int signo,const char * description)1049 StopInfoUnixSignal(Thread &thread, int signo, const char *description)
1050 : StopInfo(thread, signo) {
1051 SetDescription(description);
1052 }
1053
1054 ~StopInfoUnixSignal() override = default;
1055
GetStopReason() const1056 StopReason GetStopReason() const override { return eStopReasonSignal; }
1057
ShouldStopSynchronous(Event * event_ptr)1058 bool ShouldStopSynchronous(Event *event_ptr) override {
1059 ThreadSP thread_sp(m_thread_wp.lock());
1060 if (thread_sp)
1061 return thread_sp->GetProcess()->GetUnixSignals()->GetShouldStop(m_value);
1062 return false;
1063 }
1064
ShouldStop(Event * event_ptr)1065 bool ShouldStop(Event *event_ptr) override {
1066 ThreadSP thread_sp(m_thread_wp.lock());
1067 if (thread_sp)
1068 return thread_sp->GetProcess()->GetUnixSignals()->GetShouldStop(m_value);
1069 return false;
1070 }
1071
1072 // If should stop returns false, check if we should notify of this event
DoShouldNotify(Event * event_ptr)1073 bool DoShouldNotify(Event *event_ptr) override {
1074 ThreadSP thread_sp(m_thread_wp.lock());
1075 if (thread_sp) {
1076 bool should_notify =
1077 thread_sp->GetProcess()->GetUnixSignals()->GetShouldNotify(m_value);
1078 if (should_notify) {
1079 StreamString strm;
1080 strm.Printf(
1081 "thread %d received signal: %s", thread_sp->GetIndexID(),
1082 thread_sp->GetProcess()->GetUnixSignals()->GetSignalAsCString(
1083 m_value));
1084 Process::ProcessEventData::AddRestartedReason(event_ptr,
1085 strm.GetData());
1086 }
1087 return should_notify;
1088 }
1089 return true;
1090 }
1091
WillResume(lldb::StateType resume_state)1092 void WillResume(lldb::StateType resume_state) override {
1093 ThreadSP thread_sp(m_thread_wp.lock());
1094 if (thread_sp) {
1095 if (!thread_sp->GetProcess()->GetUnixSignals()->GetShouldSuppress(
1096 m_value))
1097 thread_sp->SetResumeSignal(m_value);
1098 }
1099 }
1100
GetDescription()1101 const char *GetDescription() override {
1102 if (m_description.empty()) {
1103 ThreadSP thread_sp(m_thread_wp.lock());
1104 if (thread_sp) {
1105 StreamString strm;
1106 const char *signal_name =
1107 thread_sp->GetProcess()->GetUnixSignals()->GetSignalAsCString(
1108 m_value);
1109 if (signal_name)
1110 strm.Printf("signal %s", signal_name);
1111 else
1112 strm.Printf("signal %" PRIi64, m_value);
1113 m_description = std::string(strm.GetString());
1114 }
1115 }
1116 return m_description.c_str();
1117 }
1118 };
1119
1120 // StopInfoTrace
1121
1122 class StopInfoTrace : public StopInfo {
1123 public:
StopInfoTrace(Thread & thread)1124 StopInfoTrace(Thread &thread) : StopInfo(thread, LLDB_INVALID_UID) {}
1125
1126 ~StopInfoTrace() override = default;
1127
GetStopReason() const1128 StopReason GetStopReason() const override { return eStopReasonTrace; }
1129
GetDescription()1130 const char *GetDescription() override {
1131 if (m_description.empty())
1132 return "trace";
1133 else
1134 return m_description.c_str();
1135 }
1136 };
1137
1138 // StopInfoException
1139
1140 class StopInfoException : public StopInfo {
1141 public:
StopInfoException(Thread & thread,const char * description)1142 StopInfoException(Thread &thread, const char *description)
1143 : StopInfo(thread, LLDB_INVALID_UID) {
1144 if (description)
1145 SetDescription(description);
1146 }
1147
1148 ~StopInfoException() override = default;
1149
GetStopReason() const1150 StopReason GetStopReason() const override { return eStopReasonException; }
1151
GetDescription()1152 const char *GetDescription() override {
1153 if (m_description.empty())
1154 return "exception";
1155 else
1156 return m_description.c_str();
1157 }
1158 };
1159
1160 // StopInfoProcessorTrace
1161
1162 class StopInfoProcessorTrace : public StopInfo {
1163 public:
StopInfoProcessorTrace(Thread & thread,const char * description)1164 StopInfoProcessorTrace(Thread &thread, const char *description)
1165 : StopInfo(thread, LLDB_INVALID_UID) {
1166 if (description)
1167 SetDescription(description);
1168 }
1169
1170 ~StopInfoProcessorTrace() override = default;
1171
GetStopReason() const1172 StopReason GetStopReason() const override {
1173 return eStopReasonProcessorTrace;
1174 }
1175
GetDescription()1176 const char *GetDescription() override {
1177 if (m_description.empty())
1178 return "processor trace event";
1179 else
1180 return m_description.c_str();
1181 }
1182 };
1183
1184 // StopInfoThreadPlan
1185
1186 class StopInfoThreadPlan : public StopInfo {
1187 public:
StopInfoThreadPlan(ThreadPlanSP & plan_sp,ValueObjectSP & return_valobj_sp,ExpressionVariableSP & expression_variable_sp)1188 StopInfoThreadPlan(ThreadPlanSP &plan_sp, ValueObjectSP &return_valobj_sp,
1189 ExpressionVariableSP &expression_variable_sp)
1190 : StopInfo(plan_sp->GetThread(), LLDB_INVALID_UID), m_plan_sp(plan_sp),
1191 m_return_valobj_sp(return_valobj_sp),
1192 m_expression_variable_sp(expression_variable_sp) {}
1193
1194 ~StopInfoThreadPlan() override = default;
1195
GetStopReason() const1196 StopReason GetStopReason() const override { return eStopReasonPlanComplete; }
1197
GetDescription()1198 const char *GetDescription() override {
1199 if (m_description.empty()) {
1200 StreamString strm;
1201 m_plan_sp->GetDescription(&strm, eDescriptionLevelBrief);
1202 m_description = std::string(strm.GetString());
1203 }
1204 return m_description.c_str();
1205 }
1206
GetReturnValueObject()1207 ValueObjectSP GetReturnValueObject() { return m_return_valobj_sp; }
1208
GetExpressionVariable()1209 ExpressionVariableSP GetExpressionVariable() {
1210 return m_expression_variable_sp;
1211 }
1212
1213 protected:
ShouldStop(Event * event_ptr)1214 bool ShouldStop(Event *event_ptr) override {
1215 if (m_plan_sp)
1216 return m_plan_sp->ShouldStop(event_ptr);
1217 else
1218 return StopInfo::ShouldStop(event_ptr);
1219 }
1220
1221 private:
1222 ThreadPlanSP m_plan_sp;
1223 ValueObjectSP m_return_valobj_sp;
1224 ExpressionVariableSP m_expression_variable_sp;
1225 };
1226
1227 // StopInfoExec
1228
1229 class StopInfoExec : public StopInfo {
1230 public:
StopInfoExec(Thread & thread)1231 StopInfoExec(Thread &thread) : StopInfo(thread, LLDB_INVALID_UID) {}
1232
1233 ~StopInfoExec() override = default;
1234
ShouldStop(Event * event_ptr)1235 bool ShouldStop(Event *event_ptr) override {
1236 ThreadSP thread_sp(m_thread_wp.lock());
1237 if (thread_sp)
1238 return thread_sp->GetProcess()->GetStopOnExec();
1239 return false;
1240 }
1241
GetStopReason() const1242 StopReason GetStopReason() const override { return eStopReasonExec; }
1243
GetDescription()1244 const char *GetDescription() override { return "exec"; }
1245
1246 protected:
PerformAction(Event * event_ptr)1247 void PerformAction(Event *event_ptr) override {
1248 // Only perform the action once
1249 if (m_performed_action)
1250 return;
1251 m_performed_action = true;
1252 ThreadSP thread_sp(m_thread_wp.lock());
1253 if (thread_sp)
1254 thread_sp->GetProcess()->DidExec();
1255 }
1256
1257 bool m_performed_action = false;
1258 };
1259
1260 // StopInfoFork
1261
1262 class StopInfoFork : public StopInfo {
1263 public:
StopInfoFork(Thread & thread,lldb::pid_t child_pid,lldb::tid_t child_tid)1264 StopInfoFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
1265 : StopInfo(thread, child_pid), m_child_pid(child_pid),
1266 m_child_tid(child_tid) {}
1267
1268 ~StopInfoFork() override = default;
1269
ShouldStop(Event * event_ptr)1270 bool ShouldStop(Event *event_ptr) override { return false; }
1271
GetStopReason() const1272 StopReason GetStopReason() const override { return eStopReasonFork; }
1273
GetDescription()1274 const char *GetDescription() override { return "fork"; }
1275
1276 protected:
PerformAction(Event * event_ptr)1277 void PerformAction(Event *event_ptr) override {
1278 // Only perform the action once
1279 if (m_performed_action)
1280 return;
1281 m_performed_action = true;
1282 ThreadSP thread_sp(m_thread_wp.lock());
1283 if (thread_sp)
1284 thread_sp->GetProcess()->DidFork(m_child_pid, m_child_tid);
1285 }
1286
1287 bool m_performed_action = false;
1288
1289 private:
1290 lldb::pid_t m_child_pid;
1291 lldb::tid_t m_child_tid;
1292 };
1293
1294 // StopInfoVFork
1295
1296 class StopInfoVFork : public StopInfo {
1297 public:
StopInfoVFork(Thread & thread,lldb::pid_t child_pid,lldb::tid_t child_tid)1298 StopInfoVFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
1299 : StopInfo(thread, child_pid), m_child_pid(child_pid),
1300 m_child_tid(child_tid) {}
1301
1302 ~StopInfoVFork() override = default;
1303
ShouldStop(Event * event_ptr)1304 bool ShouldStop(Event *event_ptr) override { return false; }
1305
GetStopReason() const1306 StopReason GetStopReason() const override { return eStopReasonVFork; }
1307
GetDescription()1308 const char *GetDescription() override { return "vfork"; }
1309
1310 protected:
PerformAction(Event * event_ptr)1311 void PerformAction(Event *event_ptr) override {
1312 // Only perform the action once
1313 if (m_performed_action)
1314 return;
1315 m_performed_action = true;
1316 ThreadSP thread_sp(m_thread_wp.lock());
1317 if (thread_sp)
1318 thread_sp->GetProcess()->DidVFork(m_child_pid, m_child_tid);
1319 }
1320
1321 bool m_performed_action = false;
1322
1323 private:
1324 lldb::pid_t m_child_pid;
1325 lldb::tid_t m_child_tid;
1326 };
1327
1328 // StopInfoVForkDone
1329
1330 class StopInfoVForkDone : public StopInfo {
1331 public:
StopInfoVForkDone(Thread & thread)1332 StopInfoVForkDone(Thread &thread) : StopInfo(thread, 0) {}
1333
1334 ~StopInfoVForkDone() override = default;
1335
ShouldStop(Event * event_ptr)1336 bool ShouldStop(Event *event_ptr) override { return false; }
1337
GetStopReason() const1338 StopReason GetStopReason() const override { return eStopReasonVForkDone; }
1339
GetDescription()1340 const char *GetDescription() override { return "vforkdone"; }
1341
1342 protected:
PerformAction(Event * event_ptr)1343 void PerformAction(Event *event_ptr) override {
1344 // Only perform the action once
1345 if (m_performed_action)
1346 return;
1347 m_performed_action = true;
1348 ThreadSP thread_sp(m_thread_wp.lock());
1349 if (thread_sp)
1350 thread_sp->GetProcess()->DidVForkDone();
1351 }
1352
1353 bool m_performed_action = false;
1354 };
1355
1356 } // namespace lldb_private
1357
CreateStopReasonWithBreakpointSiteID(Thread & thread,break_id_t break_id)1358 StopInfoSP StopInfo::CreateStopReasonWithBreakpointSiteID(Thread &thread,
1359 break_id_t break_id) {
1360 return StopInfoSP(new StopInfoBreakpoint(thread, break_id));
1361 }
1362
CreateStopReasonWithBreakpointSiteID(Thread & thread,break_id_t break_id,bool should_stop)1363 StopInfoSP StopInfo::CreateStopReasonWithBreakpointSiteID(Thread &thread,
1364 break_id_t break_id,
1365 bool should_stop) {
1366 return StopInfoSP(new StopInfoBreakpoint(thread, break_id, should_stop));
1367 }
1368
1369 StopInfoSP
CreateStopReasonWithWatchpointID(Thread & thread,break_id_t watch_id,lldb::addr_t watch_hit_addr)1370 StopInfo::CreateStopReasonWithWatchpointID(Thread &thread, break_id_t watch_id,
1371 lldb::addr_t watch_hit_addr) {
1372 return StopInfoSP(new StopInfoWatchpoint(thread, watch_id, watch_hit_addr));
1373 }
1374
CreateStopReasonWithSignal(Thread & thread,int signo,const char * description)1375 StopInfoSP StopInfo::CreateStopReasonWithSignal(Thread &thread, int signo,
1376 const char *description) {
1377 thread.GetProcess()->GetUnixSignals()->IncrementSignalHitCount(signo);
1378 return StopInfoSP(new StopInfoUnixSignal(thread, signo, description));
1379 }
1380
CreateStopReasonToTrace(Thread & thread)1381 StopInfoSP StopInfo::CreateStopReasonToTrace(Thread &thread) {
1382 return StopInfoSP(new StopInfoTrace(thread));
1383 }
1384
CreateStopReasonWithPlan(ThreadPlanSP & plan_sp,ValueObjectSP return_valobj_sp,ExpressionVariableSP expression_variable_sp)1385 StopInfoSP StopInfo::CreateStopReasonWithPlan(
1386 ThreadPlanSP &plan_sp, ValueObjectSP return_valobj_sp,
1387 ExpressionVariableSP expression_variable_sp) {
1388 return StopInfoSP(new StopInfoThreadPlan(plan_sp, return_valobj_sp,
1389 expression_variable_sp));
1390 }
1391
CreateStopReasonWithException(Thread & thread,const char * description)1392 StopInfoSP StopInfo::CreateStopReasonWithException(Thread &thread,
1393 const char *description) {
1394 return StopInfoSP(new StopInfoException(thread, description));
1395 }
1396
CreateStopReasonProcessorTrace(Thread & thread,const char * description)1397 StopInfoSP StopInfo::CreateStopReasonProcessorTrace(Thread &thread,
1398 const char *description) {
1399 return StopInfoSP(new StopInfoProcessorTrace(thread, description));
1400 }
1401
CreateStopReasonWithExec(Thread & thread)1402 StopInfoSP StopInfo::CreateStopReasonWithExec(Thread &thread) {
1403 return StopInfoSP(new StopInfoExec(thread));
1404 }
1405
CreateStopReasonFork(Thread & thread,lldb::pid_t child_pid,lldb::tid_t child_tid)1406 StopInfoSP StopInfo::CreateStopReasonFork(Thread &thread,
1407 lldb::pid_t child_pid,
1408 lldb::tid_t child_tid) {
1409 return StopInfoSP(new StopInfoFork(thread, child_pid, child_tid));
1410 }
1411
1412
CreateStopReasonVFork(Thread & thread,lldb::pid_t child_pid,lldb::tid_t child_tid)1413 StopInfoSP StopInfo::CreateStopReasonVFork(Thread &thread,
1414 lldb::pid_t child_pid,
1415 lldb::tid_t child_tid) {
1416 return StopInfoSP(new StopInfoVFork(thread, child_pid, child_tid));
1417 }
1418
CreateStopReasonVForkDone(Thread & thread)1419 StopInfoSP StopInfo::CreateStopReasonVForkDone(Thread &thread) {
1420 return StopInfoSP(new StopInfoVForkDone(thread));
1421 }
1422
GetReturnValueObject(StopInfoSP & stop_info_sp)1423 ValueObjectSP StopInfo::GetReturnValueObject(StopInfoSP &stop_info_sp) {
1424 if (stop_info_sp &&
1425 stop_info_sp->GetStopReason() == eStopReasonPlanComplete) {
1426 StopInfoThreadPlan *plan_stop_info =
1427 static_cast<StopInfoThreadPlan *>(stop_info_sp.get());
1428 return plan_stop_info->GetReturnValueObject();
1429 } else
1430 return ValueObjectSP();
1431 }
1432
GetExpressionVariable(StopInfoSP & stop_info_sp)1433 ExpressionVariableSP StopInfo::GetExpressionVariable(StopInfoSP &stop_info_sp) {
1434 if (stop_info_sp &&
1435 stop_info_sp->GetStopReason() == eStopReasonPlanComplete) {
1436 StopInfoThreadPlan *plan_stop_info =
1437 static_cast<StopInfoThreadPlan *>(stop_info_sp.get());
1438 return plan_stop_info->GetExpressionVariable();
1439 } else
1440 return ExpressionVariableSP();
1441 }
1442
1443 lldb::ValueObjectSP
GetCrashingDereference(StopInfoSP & stop_info_sp,lldb::addr_t * crashing_address)1444 StopInfo::GetCrashingDereference(StopInfoSP &stop_info_sp,
1445 lldb::addr_t *crashing_address) {
1446 if (!stop_info_sp) {
1447 return ValueObjectSP();
1448 }
1449
1450 const char *description = stop_info_sp->GetDescription();
1451 if (!description) {
1452 return ValueObjectSP();
1453 }
1454
1455 ThreadSP thread_sp = stop_info_sp->GetThread();
1456 if (!thread_sp) {
1457 return ValueObjectSP();
1458 }
1459
1460 StackFrameSP frame_sp = thread_sp->GetSelectedFrame();
1461
1462 if (!frame_sp) {
1463 return ValueObjectSP();
1464 }
1465
1466 const char address_string[] = "address=";
1467
1468 const char *address_loc = strstr(description, address_string);
1469 if (!address_loc) {
1470 return ValueObjectSP();
1471 }
1472
1473 address_loc += (sizeof(address_string) - 1);
1474
1475 uint64_t address = strtoull(address_loc, nullptr, 0);
1476 if (crashing_address) {
1477 *crashing_address = address;
1478 }
1479
1480 return frame_sp->GuessValueForAddress(address);
1481 }
1482