1 //===-- StopInfo.cpp ------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
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"
30 using namespace lldb_private
;
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() {}
39 bool StopInfo::IsValid() const {
40 ThreadSP
thread_sp(m_thread_wp
.lock());
42 return thread_sp
->GetProcess()->GetStopID() == m_stop_id
;
46 void StopInfo::MakeStopInfoValid() {
47 ThreadSP
thread_sp(m_thread_wp
.lock());
49 m_stop_id
= thread_sp
->GetProcess()->GetStopID();
50 m_resume_id
= thread_sp
->GetProcess()->GetResumeID();
54 bool StopInfo::HasTargetRunSinceMe() {
55 ThreadSP
thread_sp(m_thread_wp
.lock());
58 lldb::StateType ret_type
= thread_sp
->GetProcess()->GetPrivateState();
59 if (ret_type
== eStateRunning
) {
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
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
) {
75 } else if (curr_resume_id
> last_user_expression_id
) {
85 namespace lldb_private
{
86 class StopInfoBreakpoint
: public StopInfo
{
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) {
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) {
104 ~StopInfoBreakpoint() override
= default;
107 ThreadSP
thread_sp(m_thread_wp
.lock());
109 BreakpointSiteSP
bp_site_sp(
110 thread_sp
->GetProcess()->GetBreakpointSiteList().FindByID(m_value
));
112 uint32_t num_owners
= bp_site_sp
->GetNumberOfOwners();
113 if (num_owners
== 1) {
114 BreakpointLocationSP bp_loc_sp
= bp_site_sp
->GetOwnerAtIndex(0);
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();
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;
130 m_address
= bp_site_sp
->GetLoadAddress();
135 bool IsValidForOperatingSystemThread(Thread
&thread
) override
{
136 ProcessSP
process_sp(thread
.GetProcess());
138 BreakpointSiteSP
bp_site_sp(
139 process_sp
->GetBreakpointSiteList().FindByID(m_value
));
141 return bp_site_sp
->ValidForThisThread(thread
);
146 StopReason
GetStopReason() const override
{ return eStopReasonBreakpoint
; }
148 bool ShouldStopSynchronous(Event
*event_ptr
) override
{
149 ThreadSP
thread_sp(m_thread_wp
.lock());
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
));
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
);
161 Log
*log
= GetLog(LLDBLog::Process
);
164 "Process::%s could not find breakpoint site id: %" PRId64
166 __FUNCTION__
, m_value
);
168 m_should_stop
= true;
170 m_should_stop_is_valid
= true;
172 return m_should_stop
;
177 bool DoShouldNotify(Event
*event_ptr
) override
{
178 return !m_was_all_internal
;
181 const char *GetDescription() override
{
182 if (m_description
.empty()) {
183 ThreadSP
thread_sp(m_thread_wp
.lock());
185 BreakpointSiteSP
bp_site_sp(
186 thread_sp
->GetProcess()->GetBreakpointSiteList().FindByID(m_value
));
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
)
196 .GetBreakpointKind();
197 if (kind
!= nullptr) {
198 m_description
.assign(kind
);
204 strm
.Printf("breakpoint ");
205 bp_site_sp
->GetDescription(&strm
, eDescriptionLevelBrief
);
206 m_description
= std::string(strm
.GetString());
209 if (m_break_id
!= LLDB_INVALID_BREAK_ID
) {
210 BreakpointSP break_sp
=
211 thread_sp
->GetProcess()->GetTarget().GetBreakpointByID(
214 if (break_sp
->IsInternal()) {
215 const char *kind
= break_sp
->GetBreakpointKind();
217 strm
.Printf("internal %s breakpoint(%d).", kind
, m_break_id
);
219 strm
.Printf("internal breakpoint(%d).", m_break_id
);
221 strm
.Printf("breakpoint %d.", m_break_id
);
225 strm
.Printf("one-shot breakpoint %d", m_break_id
);
227 strm
.Printf("breakpoint %d which has been deleted.",
230 } else if (m_address
== LLDB_INVALID_ADDRESS
)
231 strm
.Printf("breakpoint site %" PRIi64
232 " which has been deleted - unknown address",
235 strm
.Printf("breakpoint site %" PRIi64
236 " which has been deleted - was at 0x%" PRIx64
,
239 m_description
= std::string(strm
.GetString());
243 return m_description
.c_str();
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
251 assert(m_should_stop_is_valid
);
252 return m_should_stop
;
255 void PerformAction(Event
*event_ptr
) override
{
256 if (!m_should_perform_action
)
258 m_should_perform_action
= false;
259 bool all_stopping_locs_internal
= true;
261 ThreadSP
thread_sp(m_thread_wp
.lock());
264 Log
*log
= GetLog(LLDBLog::Breakpoints
| LLDBLog::Step
);
266 if (!thread_sp
->IsValid()) {
267 // This shouldn't ever happen, but just in case, don't do more harm.
269 LLDB_LOGF(log
, "PerformAction got called with an invalid thread.");
271 m_should_stop
= true;
272 m_should_stop_is_valid
= true;
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;
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
);
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.
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.
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;
326 m_should_stop
= false;
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
);
333 ExecutionContext
exe_ctx(thread_sp
->GetStackFrameAtIndex(0));
334 Process
*process
= exe_ctx
.GetProcessPtr();
335 if (process
->GetModIDRef().IsRunningExpression()) {
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.
346 m_should_stop_is_valid
= true;
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();
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
;
371 "StopInfoBreakpoint::PerformAction - in expression, "
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());
382 StoppointCallbackContext
context(event_ptr
, exe_ctx
, false);
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.
391 std::vector
<lldb::BreakpointSP
> location_owners
;
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());
398 for (size_t j
= 0; j
< num_owners
; j
++) {
399 lldb::BreakpointLocationSP bp_loc_sp
= site_locations
.GetByIndex(j
);
400 StreamString loc_desc
;
402 bp_loc_sp
->GetDescription(&loc_desc
, eDescriptionLevelBrief
);
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())
410 // The breakpoint site may have many locations associated with it,
411 // not all of them valid for this thread. Skip the ones that
413 if (!bp_loc_sp
->ValidForThisThread(*thread_sp
)) {
416 "Breakpoint %s hit on thread 0x%llx but it was not "
417 "for this thread, continuing.",
419 static_cast<unsigned long long>(thread_sp
->GetID()));
424 // First run the precondition, but since the precondition is per
425 // breakpoint, only run it once per breakpoint.
426 std::pair
<std::unordered_set
<break_id_t
>::iterator
, bool> result
=
427 precondition_breakpoints
.insert(
428 bp_loc_sp
->GetBreakpoint().GetID());
432 bool precondition_result
=
433 bp_loc_sp
->GetBreakpoint().EvaluatePrecondition(context
);
434 if (!precondition_result
) {
435 actually_said_continue
= true;
438 // Next run the condition for the breakpoint. If that says we
439 // should stop, then we'll run the callback for the breakpoint. If
440 // the callback says we shouldn't stop that will win.
442 if (bp_loc_sp
->GetConditionText() == nullptr)
443 actually_hit_any_locations
= true;
445 Status condition_error
;
446 bool condition_says_stop
=
447 bp_loc_sp
->ConditionSaysStop(exe_ctx
, condition_error
);
449 if (!condition_error
.Success()) {
450 // If the condition fails to evaluate, we are going to stop
451 // at it, so the location was hit.
452 actually_hit_any_locations
= true;
453 const char *err_str
=
454 condition_error
.AsCString("<unknown error>");
455 LLDB_LOGF(log
, "Error evaluating condition: \"%s\"\n", err_str
);
458 strm
<< "stopped due to an error evaluating condition of "
460 bp_loc_sp
->GetDescription(&strm
, eDescriptionLevelBrief
);
461 strm
<< ": \"" << bp_loc_sp
->GetConditionText() << "\"\n";
464 Debugger::ReportError(
465 strm
.GetString().str(),
466 exe_ctx
.GetTargetRef().GetDebugger().GetID());
469 "Condition evaluated for breakpoint %s on thread "
470 "0x%llx condition_says_stop: %i.",
472 static_cast<unsigned long long>(thread_sp
->GetID()),
473 condition_says_stop
);
474 if (condition_says_stop
)
475 actually_hit_any_locations
= true;
477 // We don't want to increment the hit count of breakpoints if
478 // the condition fails. We've already bumped it by the time
479 // we get here, so undo the bump:
480 bp_loc_sp
->UndoBumpHitCount();
481 actually_said_continue
= true;
487 // We've done all the checks whose failure means "we consider lldb
488 // not to have hit the breakpoint". Now we're going to check for
489 // conditions that might continue after hitting. Start with the
491 if (!bp_loc_sp
->IgnoreCountShouldStop()) {
492 actually_said_continue
= true;
496 // Check the auto-continue bit on the location, do this before the
497 // callback since it may change this, but that would be for the
498 // NEXT hit. Note, you might think you could check auto-continue
499 // before the condition, and not evaluate the condition if it says
500 // to continue. But failing the condition means the breakpoint was
501 // effectively NOT HIT. So these two states are different.
502 bool auto_continue_says_stop
= true;
503 if (bp_loc_sp
->IsAutoContinue())
506 "Continuing breakpoint %s as AutoContinue was set.",
508 // We want this stop reported, so you will know we auto-continued
509 // but only for external breakpoints:
510 if (!bp_loc_sp
->GetBreakpoint().IsInternal())
511 thread_sp
->SetShouldReportStop(eVoteYes
);
512 auto_continue_says_stop
= false;
515 bool callback_says_stop
= true;
517 // FIXME: For now the callbacks have to run in async mode - the
518 // first time we restart we need
519 // to get out of there. So set it here.
520 // When we figure out how to nest breakpoint hits then this will
523 // Don't run async callbacks in PerformAction. They have already
524 // been taken into account with async_should_stop.
525 if (!bp_loc_sp
->IsCallbackSynchronous()) {
526 Debugger
&debugger
= thread_sp
->CalculateTarget()->GetDebugger();
527 bool old_async
= debugger
.GetAsyncExecution();
528 debugger
.SetAsyncExecution(true);
530 callback_says_stop
= bp_loc_sp
->InvokeCallback(&context
);
532 debugger
.SetAsyncExecution(old_async
);
534 if (callback_says_stop
&& auto_continue_says_stop
)
535 m_should_stop
= true;
537 actually_said_continue
= true;
540 if (m_should_stop
&& !bp_loc_sp
->GetBreakpoint().IsInternal())
541 all_stopping_locs_internal
= false;
543 // If we are going to stop for this breakpoint, then remove the
545 if (callback_says_stop
&& bp_loc_sp
&&
546 bp_loc_sp
->GetBreakpoint().IsOneShot()) {
547 thread_sp
->GetProcess()->GetTarget().RemoveBreakpointByID(
548 bp_loc_sp
->GetBreakpoint().GetID());
550 // Also make sure that the callback hasn't continued the target. If
551 // it did, when we'll set m_should_start to false and get out of
553 if (HasTargetRunSinceMe()) {
554 m_should_stop
= false;
555 actually_said_continue
= true;
559 // At this point if nobody actually told us to continue, we should
560 // give the async breakpoint callback a chance to weigh in:
561 if (!actually_said_continue
&& !m_should_stop
) {
562 m_should_stop
= async_should_stop
;
565 // We've figured out what this stop wants to do, so mark it as valid so
566 // we don't compute it again.
567 m_should_stop_is_valid
= true;
569 m_should_stop
= true;
570 m_should_stop_is_valid
= true;
571 actually_hit_any_locations
= true;
572 Log
*log_process(GetLog(LLDBLog::Process
));
574 LLDB_LOGF(log_process
,
575 "Process::%s could not find breakpoint site id: %" PRId64
577 __FUNCTION__
, m_value
);
580 if ((!m_should_stop
|| all_stopping_locs_internal
) &&
581 thread_sp
->CompletedPlanOverridesBreakpoint()) {
583 // Override should_stop decision when we have completed step plan
584 // additionally to the breakpoint
585 m_should_stop
= true;
587 // We know we're stopping for a completed plan and we don't want to
588 // show the breakpoint stop, so compute the public stop info immediately
590 thread_sp
->CalculatePublicStopInfo();
591 } else if (!actually_hit_any_locations
) {
592 // In the end, we didn't actually have any locations that passed their
593 // "was I hit" checks. So say we aren't stopped.
594 GetThread()->ResetStopInfo();
595 LLDB_LOGF(log
, "Process::%s all locations failed condition checks.",
600 "Process::%s returning from action with m_should_stop: %d.",
601 __FUNCTION__
, m_should_stop
);
607 bool m_should_stop_is_valid
;
608 bool m_should_perform_action
; // Since we are trying to preserve the "state"
609 // of the system even if we run functions
610 // etc. behind the users backs, we need to make sure we only REALLY perform
612 lldb::addr_t m_address
; // We use this to capture the breakpoint site address
613 // when we create the StopInfo,
614 // in case somebody deletes it between the time the StopInfo is made and the
615 // description is asked for.
616 lldb::break_id_t m_break_id
;
617 bool m_was_all_internal
;
621 // StopInfoWatchpoint
623 class StopInfoWatchpoint
: public StopInfo
{
625 // Make sure watchpoint is properly disabled and subsequently enabled while
626 // performing watchpoint actions.
627 class WatchpointSentry
{
629 WatchpointSentry(ProcessSP p_sp
, WatchpointSP w_sp
) : process_sp(p_sp
),
630 watchpoint_sp(w_sp
) {
631 if (process_sp
&& watchpoint_sp
) {
632 const bool notify
= false;
633 watchpoint_sp
->TurnOnEphemeralMode();
634 process_sp
->DisableWatchpoint(watchpoint_sp
.get(), notify
);
635 process_sp
->AddPreResumeAction(SentryPreResumeAction
, this);
640 if (process_sp
&& watchpoint_sp
) {
641 bool was_disabled
= watchpoint_sp
->IsDisabledDuringEphemeralMode();
642 watchpoint_sp
->TurnOffEphemeralMode();
643 const bool notify
= false;
645 process_sp
->DisableWatchpoint(watchpoint_sp
.get(), notify
);
647 process_sp
->EnableWatchpoint(watchpoint_sp
.get(), notify
);
652 ~WatchpointSentry() {
655 process_sp
->ClearPreResumeAction(SentryPreResumeAction
, this);
658 static bool SentryPreResumeAction(void *sentry_void
) {
659 WatchpointSentry
*sentry
= (WatchpointSentry
*) sentry_void
;
660 sentry
->DoReenable();
665 ProcessSP process_sp
;
666 WatchpointSP watchpoint_sp
;
669 StopInfoWatchpoint(Thread
&thread
, break_id_t watch_id
, bool silently_skip_wp
)
670 : StopInfo(thread
, watch_id
), m_silently_skip_wp(silently_skip_wp
) {}
672 ~StopInfoWatchpoint() override
= default;
674 StopReason
GetStopReason() const override
{ return eStopReasonWatchpoint
; }
676 const char *GetDescription() override
{
677 if (m_description
.empty()) {
679 strm
.Printf("watchpoint %" PRIi64
, m_value
);
680 m_description
= std::string(strm
.GetString());
682 return m_description
.c_str();
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
{
695 ThreadPlanStepOverWatchpoint(Thread
&thread
,
696 StopInfoWatchpointSP stop_info_sp
,
697 WatchpointSP watch_sp
)
698 : ThreadPlanStepInstruction(thread
, false, true, eVoteNoOpinion
,
700 m_stop_info_sp(stop_info_sp
), m_watch_sp(watch_sp
) {
702 m_watch_index
= watch_sp
->GetHardwareIndex();
705 bool DoWillResume(lldb::StateType resume_state
,
706 bool current_plan
) override
{
707 if (resume_state
== eStateSuspended
)
710 if (!m_did_disable_wp
) {
711 GetThread().GetProcess()->DisableWatchpoint(m_watch_sp
.get(), false);
712 m_did_disable_wp
= true;
717 bool DoPlanExplainsStop(Event
*event_ptr
) override
{
718 if (ThreadPlanStepInstruction::DoPlanExplainsStop(event_ptr
))
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.
725 && stop_info_sp
->GetStopReason() == eStopReasonWatchpoint
)
730 void DidPop() override
{
731 // Don't artifically keep the watchpoint alive.
735 bool ShouldStop(Event
*event_ptr
) override
{
736 bool should_stop
= ThreadPlanStepInstruction::ShouldStop(event_ptr
);
737 bool plan_done
= MischiefManaged();
739 m_stop_info_sp
->SetStepOverPlanComplete();
740 GetThread().SetStopInfo(m_stop_info_sp
);
746 bool ShouldRunBeforePublicStop() override
{
751 void ResetWatchpoint() {
752 if (!m_did_disable_wp
)
754 m_did_disable_wp
= true;
755 GetThread().GetProcess()->EnableWatchpoint(m_watch_sp
.get(), true);
756 m_watch_sp
->SetHardwareIndex(m_watch_index
);
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;
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
;
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
;
778 Log
*log
= GetLog(LLDBLog::Process
);
779 ThreadSP
thread_sp(m_thread_wp
.lock());
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
;
792 thread_sp
->CalculateTarget()->GetWatchpointList().FindByID(GetValue()));
793 // If we can no longer find the watchpoint, we just have to stop:
797 "Process::%s could not find watchpoint location id: %" PRId64
799 __FUNCTION__
, GetValue());
801 m_should_stop
= true;
802 m_should_stop_is_valid
= true;
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
;
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
824 ProcessSP process_sp
= exe_ctx
.GetProcessSP();
825 bool wp_triggers_after
= process_sp
->GetWatchpointReportedAfter();
827 if (!wp_triggers_after
) {
828 // We have to step over the watchpoint before we know what to do:
829 StopInfoWatchpointSP me_as_siwp_sp
830 = std::static_pointer_cast
<StopInfoWatchpoint
>(shared_from_this());
831 ThreadPlanSP
step_over_wp_sp(new ThreadPlanStepOverWatchpoint(
832 *(thread_sp
.get()), me_as_siwp_sp
, wp_sp
));
833 // When this plan is done we want to stop, so set this as a Controlling
835 step_over_wp_sp
->SetIsControllingPlan(true);
836 step_over_wp_sp
->SetOkayToDiscard(false);
839 error
= thread_sp
->QueueThreadPlan(step_over_wp_sp
, false);
840 // If we couldn't push the thread plan, just stop here:
841 if (!error
.Success()) {
842 LLDB_LOGF(log
, "Could not push our step over watchpoint plan: %s",
845 m_should_stop
= true;
846 m_should_stop_is_valid
= true;
849 // Otherwise, don't set m_should_stop, we don't know that yet. Just
850 // say we should continue, and tell the thread we really should do so:
851 thread_sp
->SetShouldRunBeforePublicStop(true);
852 m_using_step_over_plan
= true;
856 // We didn't have to do anything special
857 m_should_stop_is_valid
= true;
858 return m_should_stop
;
861 return m_should_stop
;
864 bool ShouldStop(Event
*event_ptr
) override
{
865 // This just reports the work done by PerformAction or the synchronous
866 // stop. It should only ever get called after they have had a chance to
868 assert(m_should_stop_is_valid
);
869 return m_should_stop
;
872 void PerformAction(Event
*event_ptr
) override
{
873 Log
*log
= GetLog(LLDBLog::Watchpoints
);
874 // We're going to calculate if we should stop or not in some way during the
875 // course of this code. Also by default we're going to stop, so set that
877 m_should_stop
= true;
880 ThreadSP
thread_sp(m_thread_wp
.lock());
884 thread_sp
->CalculateTarget()->GetWatchpointList().FindByID(
887 // This sentry object makes sure the current watchpoint is disabled
888 // while performing watchpoint actions, and it is then enabled after we
890 ExecutionContext
exe_ctx(thread_sp
->GetStackFrameAtIndex(0));
891 ProcessSP process_sp
= exe_ctx
.GetProcessSP();
893 WatchpointSentry
sentry(process_sp
, wp_sp
);
895 if (m_silently_skip_wp
) {
896 m_should_stop
= false;
897 wp_sp
->UndoHitCount();
900 if (wp_sp
->GetHitCount() <= wp_sp
->GetIgnoreCount()) {
901 m_should_stop
= false;
902 m_should_stop_is_valid
= true;
905 Debugger
&debugger
= exe_ctx
.GetTargetRef().GetDebugger();
907 if (m_should_stop
&& wp_sp
->GetConditionText() != nullptr) {
908 // We need to make sure the user sees any parse errors in their
909 // condition, so we'll hook the constructor errors up to the
910 // debugger's Async I/O.
911 ExpressionResults result_code
;
912 EvaluateExpressionOptions expr_options
;
913 expr_options
.SetUnwindOnError(true);
914 expr_options
.SetIgnoreBreakpoints(true);
915 ValueObjectSP result_value_sp
;
917 result_code
= UserExpression::Evaluate(
918 exe_ctx
, expr_options
, wp_sp
->GetConditionText(),
919 llvm::StringRef(), result_value_sp
, error
);
921 if (result_code
== eExpressionCompleted
) {
922 if (result_value_sp
) {
924 if (result_value_sp
->ResolveValue(scalar_value
)) {
925 if (scalar_value
.ULongLong(1) == 0) {
926 // The condition failed, which we consider "not having hit
927 // the watchpoint" so undo the hit count here.
928 wp_sp
->UndoHitCount();
929 m_should_stop
= false;
931 m_should_stop
= true;
933 "Condition successfully evaluated, result is %s.\n",
934 m_should_stop
? "true" : "false");
936 m_should_stop
= true;
939 "Failed to get an integer result from the expression.");
943 const char *err_str
= error
.AsCString("<unknown error>");
944 LLDB_LOGF(log
, "Error evaluating condition: \"%s\"\n", err_str
);
947 strm
<< "stopped due to an error evaluating condition of "
949 wp_sp
->GetDescription(&strm
, eDescriptionLevelBrief
);
950 strm
<< ": \"" << wp_sp
->GetConditionText() << "\"\n";
953 Debugger::ReportError(strm
.GetString().str(),
954 exe_ctx
.GetTargetRef().GetDebugger().GetID());
958 // If the condition says to stop, we run the callback to further decide
961 // FIXME: For now the callbacks have to run in async mode - the
962 // first time we restart we need
963 // to get out of there. So set it here.
964 // When we figure out how to nest watchpoint hits then this will
967 bool old_async
= debugger
.GetAsyncExecution();
968 debugger
.SetAsyncExecution(true);
970 StoppointCallbackContext
context(event_ptr
, exe_ctx
, false);
971 bool stop_requested
= wp_sp
->InvokeCallback(&context
);
973 debugger
.SetAsyncExecution(old_async
);
975 // Also make sure that the callback hasn't continued the target. If
976 // it did, when we'll set m_should_stop to false and get out of here.
977 if (HasTargetRunSinceMe())
978 m_should_stop
= false;
980 if (m_should_stop
&& !stop_requested
) {
981 // We have been vetoed by the callback mechanism.
982 m_should_stop
= false;
986 // Don't stop if the watched region value is unmodified, and
987 // this is a Modify-type watchpoint.
988 if (m_should_stop
&& !wp_sp
->WatchedValueReportable(exe_ctx
))
989 m_should_stop
= false;
991 // Finally, if we are going to stop, print out the new & old values:
993 wp_sp
->CaptureWatchedValue(exe_ctx
);
995 Debugger
&debugger
= exe_ctx
.GetTargetRef().GetDebugger();
996 StreamSP output_sp
= debugger
.GetAsyncOutputStream();
997 wp_sp
->DumpSnapshots(output_sp
.get());
1003 Log
*log_process(GetLog(LLDBLog::Process
));
1005 LLDB_LOGF(log_process
,
1006 "Process::%s could not find watchpoint id: %" PRId64
"...",
1007 __FUNCTION__
, m_value
);
1010 "Process::%s returning from action with m_should_stop: %d.",
1011 __FUNCTION__
, m_should_stop
);
1013 m_should_stop_is_valid
= true;
1018 void SetStepOverPlanComplete() {
1019 assert(m_using_step_over_plan
);
1020 m_step_over_plan_complete
= true;
1023 bool m_should_stop
= false;
1024 bool m_should_stop_is_valid
= false;
1025 // A false watchpoint hit has happened -
1026 // the thread stopped with a watchpoint
1027 // hit notification, but the watched region
1028 // was not actually accessed (as determined
1029 // by the gdb stub we're talking to).
1030 // Continue past this watchpoint without
1031 // notifying the user; on some targets this
1032 // may mean disable wp, instruction step,
1033 // re-enable wp, continue.
1034 // On others, just continue.
1035 bool m_silently_skip_wp
= false;
1036 bool m_step_over_plan_complete
= false;
1037 bool m_using_step_over_plan
= false;
1040 // StopInfoUnixSignal
1042 class StopInfoUnixSignal
: public StopInfo
{
1044 StopInfoUnixSignal(Thread
&thread
, int signo
, const char *description
,
1045 std::optional
<int> code
)
1046 : StopInfo(thread
, signo
), m_code(code
) {
1047 SetDescription(description
);
1050 ~StopInfoUnixSignal() override
= default;
1052 StopReason
GetStopReason() const override
{ return eStopReasonSignal
; }
1054 bool ShouldStopSynchronous(Event
*event_ptr
) override
{
1055 ThreadSP
thread_sp(m_thread_wp
.lock());
1057 return thread_sp
->GetProcess()->GetUnixSignals()->GetShouldStop(m_value
);
1061 bool ShouldStop(Event
*event_ptr
) override
{
1062 ThreadSP
thread_sp(m_thread_wp
.lock());
1064 return thread_sp
->GetProcess()->GetUnixSignals()->GetShouldStop(m_value
);
1068 // If should stop returns false, check if we should notify of this event
1069 bool DoShouldNotify(Event
*event_ptr
) override
{
1070 ThreadSP
thread_sp(m_thread_wp
.lock());
1072 bool should_notify
=
1073 thread_sp
->GetProcess()->GetUnixSignals()->GetShouldNotify(m_value
);
1074 if (should_notify
) {
1077 "thread {0:d} received signal: {1}", thread_sp
->GetIndexID(),
1078 thread_sp
->GetProcess()->GetUnixSignals()->GetSignalAsStringRef(
1080 Process::ProcessEventData::AddRestartedReason(event_ptr
,
1083 return should_notify
;
1088 void WillResume(lldb::StateType resume_state
) override
{
1089 ThreadSP
thread_sp(m_thread_wp
.lock());
1091 if (!thread_sp
->GetProcess()->GetUnixSignals()->GetShouldSuppress(
1093 thread_sp
->SetResumeSignal(m_value
);
1097 const char *GetDescription() override
{
1098 if (m_description
.empty()) {
1099 ThreadSP
thread_sp(m_thread_wp
.lock());
1101 UnixSignalsSP unix_signals
= thread_sp
->GetProcess()->GetUnixSignals();
1105 std::string signal_name
=
1106 unix_signals
->GetSignalDescription(m_value
, m_code
);
1107 if (signal_name
.size())
1108 strm
<< signal_name
;
1110 strm
.Printf("%" PRIi64
, m_value
);
1112 m_description
= std::string(strm
.GetString());
1115 return m_description
.c_str();
1119 // In siginfo_t terms, if m_value is si_signo, m_code is si_code.
1120 std::optional
<int> m_code
;
1125 class StopInfoTrace
: public StopInfo
{
1127 StopInfoTrace(Thread
&thread
) : StopInfo(thread
, LLDB_INVALID_UID
) {}
1129 ~StopInfoTrace() override
= default;
1131 StopReason
GetStopReason() const override
{ return eStopReasonTrace
; }
1133 const char *GetDescription() override
{
1134 if (m_description
.empty())
1137 return m_description
.c_str();
1141 // StopInfoException
1143 class StopInfoException
: public StopInfo
{
1145 StopInfoException(Thread
&thread
, const char *description
)
1146 : StopInfo(thread
, LLDB_INVALID_UID
) {
1148 SetDescription(description
);
1151 ~StopInfoException() override
= default;
1153 StopReason
GetStopReason() const override
{ return eStopReasonException
; }
1155 const char *GetDescription() override
{
1156 if (m_description
.empty())
1159 return m_description
.c_str();
1163 // StopInfoProcessorTrace
1165 class StopInfoProcessorTrace
: public StopInfo
{
1167 StopInfoProcessorTrace(Thread
&thread
, const char *description
)
1168 : StopInfo(thread
, LLDB_INVALID_UID
) {
1170 SetDescription(description
);
1173 ~StopInfoProcessorTrace() override
= default;
1175 StopReason
GetStopReason() const override
{
1176 return eStopReasonProcessorTrace
;
1179 const char *GetDescription() override
{
1180 if (m_description
.empty())
1181 return "processor trace event";
1183 return m_description
.c_str();
1187 // StopInfoThreadPlan
1189 class StopInfoThreadPlan
: public StopInfo
{
1191 StopInfoThreadPlan(ThreadPlanSP
&plan_sp
, ValueObjectSP
&return_valobj_sp
,
1192 ExpressionVariableSP
&expression_variable_sp
)
1193 : StopInfo(plan_sp
->GetThread(), LLDB_INVALID_UID
), m_plan_sp(plan_sp
),
1194 m_return_valobj_sp(return_valobj_sp
),
1195 m_expression_variable_sp(expression_variable_sp
) {}
1197 ~StopInfoThreadPlan() override
= default;
1199 StopReason
GetStopReason() const override
{ return eStopReasonPlanComplete
; }
1201 const char *GetDescription() override
{
1202 if (m_description
.empty()) {
1204 m_plan_sp
->GetDescription(&strm
, eDescriptionLevelBrief
);
1205 m_description
= std::string(strm
.GetString());
1207 return m_description
.c_str();
1210 ValueObjectSP
GetReturnValueObject() { return m_return_valobj_sp
; }
1212 ExpressionVariableSP
GetExpressionVariable() {
1213 return m_expression_variable_sp
;
1217 bool ShouldStop(Event
*event_ptr
) override
{
1219 return m_plan_sp
->ShouldStop(event_ptr
);
1221 return StopInfo::ShouldStop(event_ptr
);
1225 ThreadPlanSP m_plan_sp
;
1226 ValueObjectSP m_return_valobj_sp
;
1227 ExpressionVariableSP m_expression_variable_sp
;
1232 class StopInfoExec
: public StopInfo
{
1234 StopInfoExec(Thread
&thread
) : StopInfo(thread
, LLDB_INVALID_UID
) {}
1236 ~StopInfoExec() override
= default;
1238 bool ShouldStop(Event
*event_ptr
) override
{
1239 ThreadSP
thread_sp(m_thread_wp
.lock());
1241 return thread_sp
->GetProcess()->GetStopOnExec();
1245 StopReason
GetStopReason() const override
{ return eStopReasonExec
; }
1247 const char *GetDescription() override
{ return "exec"; }
1250 void PerformAction(Event
*event_ptr
) override
{
1251 // Only perform the action once
1252 if (m_performed_action
)
1254 m_performed_action
= true;
1255 ThreadSP
thread_sp(m_thread_wp
.lock());
1257 thread_sp
->GetProcess()->DidExec();
1260 bool m_performed_action
= false;
1265 class StopInfoFork
: public StopInfo
{
1267 StopInfoFork(Thread
&thread
, lldb::pid_t child_pid
, lldb::tid_t child_tid
)
1268 : StopInfo(thread
, child_pid
), m_child_pid(child_pid
),
1269 m_child_tid(child_tid
) {}
1271 ~StopInfoFork() override
= default;
1273 bool ShouldStop(Event
*event_ptr
) override
{ return false; }
1275 StopReason
GetStopReason() const override
{ return eStopReasonFork
; }
1277 const char *GetDescription() override
{ return "fork"; }
1280 void PerformAction(Event
*event_ptr
) override
{
1281 // Only perform the action once
1282 if (m_performed_action
)
1284 m_performed_action
= true;
1285 ThreadSP
thread_sp(m_thread_wp
.lock());
1287 thread_sp
->GetProcess()->DidFork(m_child_pid
, m_child_tid
);
1290 bool m_performed_action
= false;
1293 lldb::pid_t m_child_pid
;
1294 lldb::tid_t m_child_tid
;
1299 class StopInfoVFork
: public StopInfo
{
1301 StopInfoVFork(Thread
&thread
, lldb::pid_t child_pid
, lldb::tid_t child_tid
)
1302 : StopInfo(thread
, child_pid
), m_child_pid(child_pid
),
1303 m_child_tid(child_tid
) {}
1305 ~StopInfoVFork() override
= default;
1307 bool ShouldStop(Event
*event_ptr
) override
{ return false; }
1309 StopReason
GetStopReason() const override
{ return eStopReasonVFork
; }
1311 const char *GetDescription() override
{ return "vfork"; }
1314 void PerformAction(Event
*event_ptr
) override
{
1315 // Only perform the action once
1316 if (m_performed_action
)
1318 m_performed_action
= true;
1319 ThreadSP
thread_sp(m_thread_wp
.lock());
1321 thread_sp
->GetProcess()->DidVFork(m_child_pid
, m_child_tid
);
1324 bool m_performed_action
= false;
1327 lldb::pid_t m_child_pid
;
1328 lldb::tid_t m_child_tid
;
1331 // StopInfoVForkDone
1333 class StopInfoVForkDone
: public StopInfo
{
1335 StopInfoVForkDone(Thread
&thread
) : StopInfo(thread
, 0) {}
1337 ~StopInfoVForkDone() override
= default;
1339 bool ShouldStop(Event
*event_ptr
) override
{ return false; }
1341 StopReason
GetStopReason() const override
{ return eStopReasonVForkDone
; }
1343 const char *GetDescription() override
{ return "vforkdone"; }
1346 void PerformAction(Event
*event_ptr
) override
{
1347 // Only perform the action once
1348 if (m_performed_action
)
1350 m_performed_action
= true;
1351 ThreadSP
thread_sp(m_thread_wp
.lock());
1353 thread_sp
->GetProcess()->DidVForkDone();
1356 bool m_performed_action
= false;
1359 } // namespace lldb_private
1361 StopInfoSP
StopInfo::CreateStopReasonWithBreakpointSiteID(Thread
&thread
,
1362 break_id_t break_id
) {
1363 return StopInfoSP(new StopInfoBreakpoint(thread
, break_id
));
1366 StopInfoSP
StopInfo::CreateStopReasonWithBreakpointSiteID(Thread
&thread
,
1367 break_id_t break_id
,
1369 return StopInfoSP(new StopInfoBreakpoint(thread
, break_id
, should_stop
));
1372 StopInfoSP
StopInfo::CreateStopReasonWithWatchpointID(Thread
&thread
,
1373 break_id_t watch_id
,
1374 bool silently_continue
) {
1376 new StopInfoWatchpoint(thread
, watch_id
, silently_continue
));
1379 StopInfoSP
StopInfo::CreateStopReasonWithSignal(Thread
&thread
, int signo
,
1380 const char *description
,
1381 std::optional
<int> code
) {
1382 thread
.GetProcess()->GetUnixSignals()->IncrementSignalHitCount(signo
);
1383 return StopInfoSP(new StopInfoUnixSignal(thread
, signo
, description
, code
));
1386 StopInfoSP
StopInfo::CreateStopReasonToTrace(Thread
&thread
) {
1387 return StopInfoSP(new StopInfoTrace(thread
));
1390 StopInfoSP
StopInfo::CreateStopReasonWithPlan(
1391 ThreadPlanSP
&plan_sp
, ValueObjectSP return_valobj_sp
,
1392 ExpressionVariableSP expression_variable_sp
) {
1393 return StopInfoSP(new StopInfoThreadPlan(plan_sp
, return_valobj_sp
,
1394 expression_variable_sp
));
1397 StopInfoSP
StopInfo::CreateStopReasonWithException(Thread
&thread
,
1398 const char *description
) {
1399 return StopInfoSP(new StopInfoException(thread
, description
));
1402 StopInfoSP
StopInfo::CreateStopReasonProcessorTrace(Thread
&thread
,
1403 const char *description
) {
1404 return StopInfoSP(new StopInfoProcessorTrace(thread
, description
));
1407 StopInfoSP
StopInfo::CreateStopReasonWithExec(Thread
&thread
) {
1408 return StopInfoSP(new StopInfoExec(thread
));
1411 StopInfoSP
StopInfo::CreateStopReasonFork(Thread
&thread
,
1412 lldb::pid_t child_pid
,
1413 lldb::tid_t child_tid
) {
1414 return StopInfoSP(new StopInfoFork(thread
, child_pid
, child_tid
));
1418 StopInfoSP
StopInfo::CreateStopReasonVFork(Thread
&thread
,
1419 lldb::pid_t child_pid
,
1420 lldb::tid_t child_tid
) {
1421 return StopInfoSP(new StopInfoVFork(thread
, child_pid
, child_tid
));
1424 StopInfoSP
StopInfo::CreateStopReasonVForkDone(Thread
&thread
) {
1425 return StopInfoSP(new StopInfoVForkDone(thread
));
1428 ValueObjectSP
StopInfo::GetReturnValueObject(StopInfoSP
&stop_info_sp
) {
1430 stop_info_sp
->GetStopReason() == eStopReasonPlanComplete
) {
1431 StopInfoThreadPlan
*plan_stop_info
=
1432 static_cast<StopInfoThreadPlan
*>(stop_info_sp
.get());
1433 return plan_stop_info
->GetReturnValueObject();
1435 return ValueObjectSP();
1438 ExpressionVariableSP
StopInfo::GetExpressionVariable(StopInfoSP
&stop_info_sp
) {
1440 stop_info_sp
->GetStopReason() == eStopReasonPlanComplete
) {
1441 StopInfoThreadPlan
*plan_stop_info
=
1442 static_cast<StopInfoThreadPlan
*>(stop_info_sp
.get());
1443 return plan_stop_info
->GetExpressionVariable();
1445 return ExpressionVariableSP();
1449 StopInfo::GetCrashingDereference(StopInfoSP
&stop_info_sp
,
1450 lldb::addr_t
*crashing_address
) {
1451 if (!stop_info_sp
) {
1452 return ValueObjectSP();
1455 const char *description
= stop_info_sp
->GetDescription();
1457 return ValueObjectSP();
1460 ThreadSP thread_sp
= stop_info_sp
->GetThread();
1462 return ValueObjectSP();
1465 StackFrameSP frame_sp
=
1466 thread_sp
->GetSelectedFrame(DoNoSelectMostRelevantFrame
);
1469 return ValueObjectSP();
1472 const char address_string
[] = "address=";
1474 const char *address_loc
= strstr(description
, address_string
);
1476 return ValueObjectSP();
1479 address_loc
+= (sizeof(address_string
) - 1);
1481 uint64_t address
= strtoull(address_loc
, nullptr, 0);
1482 if (crashing_address
) {
1483 *crashing_address
= address
;
1486 return frame_sp
->GuessValueForAddress(address
);