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