LLDB mainline
StopInfo.cpp
Go to the documentation of this file.
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
16#include "lldb/Core/Debugger.h"
18#include "lldb/Symbol/Block.h"
19#include "lldb/Target/Policy.h"
20#include "lldb/Target/Process.h"
22#include "lldb/Target/Target.h"
23#include "lldb/Target/Thread.h"
28#include "lldb/Utility/Log.h"
31
32using namespace lldb;
33using namespace lldb_private;
34
35StopInfo::StopInfo(Thread &thread, uint64_t value)
36 : m_thread_wp(thread.shared_from_this()),
37 m_stop_id(thread.GetProcess()->GetStopID()),
38 m_resume_id(thread.GetProcess()->GetResumeID()), m_value(value),
41
42bool StopInfo::IsValid() const {
43 ThreadSP thread_sp(m_thread_wp.lock());
44 if (thread_sp)
45 return thread_sp->GetProcess()->GetStopID() == m_stop_id;
46 return false;
47}
48
50 ThreadSP thread_sp(m_thread_wp.lock());
51 if (thread_sp) {
52 m_stop_id = thread_sp->GetProcess()->GetStopID();
53 m_resume_id = thread_sp->GetProcess()->GetResumeID();
54 }
55}
56
58 ThreadSP thread_sp(m_thread_wp.lock());
59
60 if (thread_sp) {
61 lldb::StateType ret_type = thread_sp->GetProcess()->GetPrivateState();
62 if (ret_type == eStateRunning) {
63 return true;
64 } else if (ret_type == eStateStopped) {
65 // This is a little tricky. We want to count "run and stopped again
66 // before you could ask this question as a "TRUE" answer to
67 // HasTargetRunSinceMe. But we don't want to include any running of the
68 // target done for expressions. So we track both resumes, and resumes
69 // caused by expressions, and check if there are any resumes
70 // NOT caused
71 // by expressions.
72
73 uint32_t curr_resume_id = thread_sp->GetProcess()->GetResumeID();
74 uint32_t last_user_expression_id =
75 thread_sp->GetProcess()->GetLastUserExpressionResumeID();
76 if (curr_resume_id == m_resume_id) {
77 return false;
78 } else if (curr_resume_id > last_user_expression_id) {
79 return true;
80 }
81 }
82 }
83 return false;
84}
85
86// StopInfoBreakpoint
87
88namespace lldb_private {
90public:
91 // We use a "breakpoint preserving BreakpointLocationCollection because we
92 // may need to hand out the "breakpoint hit" list as any point, potentially
93 // after the breakpoint has been deleted. But we still need to refer to them.
102
103 StopInfoBreakpoint(Thread &thread, break_id_t break_id, bool should_stop)
104 : StopInfo(thread, break_id), m_should_stop(should_stop),
107 m_was_all_internal(false), m_was_one_shot(false),
109 StoreBPInfo();
110 }
111
112 ~StopInfoBreakpoint() override = default;
113
114 void StoreBPInfo() {
115 ThreadSP thread_sp(m_thread_wp.lock());
116 if (thread_sp) {
118 if (bp_site_sp) {
119 uint32_t num_constituents = bp_site_sp->GetNumberOfConstituents();
120 if (num_constituents == 1) {
121 BreakpointLocationSP bp_loc_sp = bp_site_sp->GetConstituentAtIndex(0);
122 if (bp_loc_sp) {
123 Breakpoint & bkpt = bp_loc_sp->GetBreakpoint();
124 m_break_id = bkpt.GetID();
125 m_was_one_shot = bkpt.IsOneShot();
127 }
128 } else {
129 m_was_all_internal = true;
130 for (uint32_t i = 0; i < num_constituents; i++) {
131 if (!bp_site_sp->GetConstituentAtIndex(i)
132 ->GetBreakpoint()
133 .IsInternal()) {
134 m_was_all_internal = false;
135 break;
136 }
137 }
138 }
139 m_address = bp_site_sp->GetLoadAddress();
140 }
141 }
142 }
143
145 ProcessSP process_sp(thread.GetProcess());
146 if (process_sp) {
148 if (bp_site_sp)
149 return bp_site_sp->ValidForThisThread(thread);
150 }
151 return false;
152 }
153
154 StopReason GetStopReason() const override { return eStopReasonBreakpoint; }
155
156 bool ShouldStopSynchronous(Event *event_ptr) override {
157 // Breakpoint callbacks run on the PST during stop processing. Push
158 // private state context so callback code sees the private reality.
160
161 ThreadSP thread_sp(m_thread_wp.lock());
162 if (thread_sp) {
164 // Only check once if we should stop at a breakpoint
166 if (bp_site_sp) {
167 ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0));
168 StoppointCallbackContext context(event_ptr, exe_ctx, true);
169 bp_site_sp->BumpHitCounts();
171 bp_site_sp->ShouldStop(&context, m_async_stopped_locs);
172 } else {
174
175 LLDB_LOGF(log,
176 "Process::%s could not find breakpoint site id: %" PRId64
177 "...",
178 __FUNCTION__, m_value);
179
180 m_should_stop = true;
181 }
183 }
184 return m_should_stop;
185 }
186 return false;
187 }
188
189 bool DoShouldNotify(Event *event_ptr) override {
190 return !m_was_all_internal;
191 }
192
193 const char *GetDescription() override {
194 // FIXME: only print m_async_stopped_locs.
195 if (m_description.empty()) {
196 ThreadSP thread_sp(m_thread_wp.lock());
197 if (thread_sp) {
199 if (bp_site_sp) {
200 StreamString strm;
201 // If we have just hit an internal breakpoint, and it has a kind
202 // description, print that instead of the full breakpoint printing:
203 if (bp_site_sp->IsInternal()) {
204 size_t num_constituents = bp_site_sp->GetNumberOfConstituents();
205 for (size_t idx = 0; idx < num_constituents; idx++) {
206 const char *kind = bp_site_sp->GetConstituentAtIndex(idx)
207 ->GetBreakpoint()
208 .GetBreakpointKind();
209 if (kind != nullptr) {
210 m_description.assign(kind);
211 return kind;
212 }
213 }
214 }
215
216 strm.Printf("breakpoint ");
217 m_async_stopped_locs.GetDescription(&strm, eDescriptionLevelBrief);
218 m_description = std::string(strm.GetString());
219 } else {
220 StreamString strm;
222 BreakpointSP break_sp =
223 thread_sp->GetProcess()->GetTarget().GetBreakpointByID(
224 m_break_id);
225 if (break_sp) {
226 if (break_sp->IsInternal()) {
227 const char *kind = break_sp->GetBreakpointKind();
228 if (kind)
229 strm.Printf("internal %s breakpoint(%d).", kind, m_break_id);
230 else
231 strm.Printf("internal breakpoint(%d).", m_break_id);
232 } else {
233 strm.Printf("breakpoint %d.", m_break_id);
234 }
235 } else {
236 if (m_was_one_shot)
237 strm.Printf("one-shot breakpoint %d", m_break_id);
238 else
239 strm.Printf("breakpoint %d which has been deleted.",
240 m_break_id);
241 }
242 } else if (m_address == LLDB_INVALID_ADDRESS)
243 strm.Printf("breakpoint site %" PRIi64
244 " which has been deleted - unknown address",
245 m_value);
246 else
247 strm.Printf("breakpoint site %" PRIi64
248 " which has been deleted - was at 0x%" PRIx64,
250
251 m_description = std::string(strm.GetString());
252 }
253 }
254 }
255 return m_description.c_str();
256 }
257
258 uint32_t GetStopReasonDataCount() const override {
259 size_t num_async_locs = m_async_stopped_locs.GetSize();
260 // If we have async locations, they are the ones we should report:
261 if (num_async_locs > 0)
262 return num_async_locs * 2;
263
264 // Otherwise report the number of locations at this breakpoint's site.
266 if (bp_site_sp)
267 return bp_site_sp->GetNumberOfConstituents() * 2;
268 return 0; // Breakpoint must have cleared itself...
269 }
270
271 uint64_t GetStopReasonDataAtIndex(uint32_t idx) override {
272 uint32_t bp_index = idx / 2;
273 BreakpointLocationSP loc_to_report_sp;
274
275 size_t num_async_locs = m_async_stopped_locs.GetSize();
276 if (num_async_locs > 0) {
277 // GetByIndex returns an empty SP if we ask past its contents:
278 loc_to_report_sp = m_async_stopped_locs.GetByIndex(bp_index);
279 } else {
281 if (bp_site_sp)
282 loc_to_report_sp = bp_site_sp->GetConstituentAtIndex(bp_index);
283 }
284 if (loc_to_report_sp) {
285 if (idx & 1) {
286 // Odd idx, return the breakpoint location ID
287 return loc_to_report_sp->GetID();
288 } else {
289 // Even idx, return the breakpoint ID
290 return loc_to_report_sp->GetBreakpoint().GetID();
291 }
292 }
294 }
295
296 std::optional<uint32_t>
297 GetSuggestedStackFrameIndex(bool inlined_stack) override {
298 if (!inlined_stack)
299 return {};
300
301 ThreadSP thread_sp(m_thread_wp.lock());
302 if (!thread_sp)
303 return {};
305 if (!bp_site_sp)
306 return {};
307
308 return bp_site_sp->GetSuggestedStackFrameIndex();
309 }
310
311 bool ShouldShow() const override { return !m_was_all_internal; }
312
313 bool ShouldSelect() const override { return !m_was_all_internal; }
314
315protected:
316 bool ShouldStop(Event *event_ptr) override {
317 // This just reports the work done by PerformAction or the synchronous
318 // stop. It should only ever get called after they have had a chance to
319 // run.
321 return m_should_stop;
322 }
323
324 void PerformAction(Event *event_ptr) override {
326 return;
328 bool all_stopping_locs_internal = true;
329
330 ThreadSP thread_sp(m_thread_wp.lock());
331
332 if (thread_sp) {
334
335 if (!thread_sp->IsValid()) {
336 // This shouldn't ever happen, but just in case, don't do more harm.
337 LLDB_LOGF(log, "PerformAction got called with an invalid thread.");
338 m_should_stop = true;
340 return;
341 }
342
344 std::unordered_set<break_id_t> precondition_breakpoints;
345 // Breakpoints that fail their condition check are not considered to
346 // have been hit. If the only locations at this site have failed their
347 // conditions, we should change the stop-info to none. Otherwise, if we
348 // hit another breakpoint on a different thread which does stop, users
349 // will see a breakpont hit with a failed condition, which is wrong.
350 // Use this variable to tell us if that is true.
351 bool actually_hit_any_locations = false;
352 if (bp_site_sp) {
353 // Let's copy the constituents list out of the site and store them in a
354 // local list. That way if one of the breakpoint actions changes the
355 // site, then we won't be operating on a bad list.
356 BreakpointLocationCollection site_locations;
357 size_t num_constituents = m_async_stopped_locs.GetSize();
358
359 if (num_constituents == 0) {
360 m_should_stop = true;
361 actually_hit_any_locations = true; // We're going to stop, don't
362 // change the stop info.
363 } else {
364 // We go through each location, and test first its precondition -
365 // this overrides everything. Note, we only do this once per
366 // breakpoint - not once per location... Then check the condition.
367 // If the condition says to stop, then we run the callback for that
368 // location. If that callback says to stop as well, then we set
369 // m_should_stop to true; we are going to stop. But we still want to
370 // give all the breakpoints whose conditions say we are going to stop
371 // a chance to run their callbacks. Of course if any callback
372 // restarts the target by putting "continue" in the callback, then
373 // we're going to restart, without running the rest of the callbacks.
374 // And in this case we will end up not stopping even if another
375 // location said we should stop. But that's better than not running
376 // all the callbacks.
377
378 // There's one other complication here. We may have run an async
379 // breakpoint callback that said we should stop. We only want to
380 // override that if another breakpoint action says we shouldn't
381 // stop. If nobody else has an opinion, then we should stop if the
382 // async callback says we should. An example of this is the async
383 // shared library load notification breakpoint and the setting
384 // stop-on-sharedlibrary-events.
385 // We'll keep the async value in async_should_stop, and track whether
386 // anyone said we should NOT stop in actually_said_continue.
387 bool async_should_stop = false;
389 async_should_stop = m_should_stop;
390 bool actually_said_continue = false;
391
392 m_should_stop = false;
393
394 // We don't select threads as we go through them testing breakpoint
395 // conditions and running commands. So we need to set the thread for
396 // expression evaluation here:
397 ThreadList::ExpressionExecutionThreadPusher thread_pusher(thread_sp);
398
399 ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0));
400 Process *process = exe_ctx.GetProcessPtr();
401 Policy policy = PolicyStack::Get().Current();
403 process->GetModIDRef().IsRunningExpression()) {
404 // If we are in the middle of evaluating an expression, don't run
405 // asynchronous breakpoint commands or expressions. That could
406 // lead to infinite recursion if the command or condition re-calls
407 // the function with this breakpoint.
408 // TODO: We can keep a list of the breakpoints we've seen while
409 // running expressions in the nested
410 // PerformAction calls that can arise when the action runs a
411 // function that hits another breakpoint, and only stop running
412 // commands when we see the same breakpoint hit a second time.
413
415
416 // It is possible that the user has a breakpoint at the same site
417 // as the completed plan had (e.g. user has a breakpoint
418 // on a module entry point, and `ThreadPlanCallFunction` ends
419 // also there). We can't find an internal breakpoint in the loop
420 // later because it was already removed on the plan completion.
421 // So check if the plan was completed, and stop if so.
422 if (thread_sp->CompletedPlanOverridesBreakpoint()) {
423 m_should_stop = true;
424 thread_sp->ResetStopInfo();
425 return;
426 }
427
428 LLDB_LOGF(log, "StopInfoBreakpoint::PerformAction - Hit a "
429 "breakpoint while running an expression,"
430 " not running commands to avoid recursion.");
431 bool ignoring_breakpoints =
433 // Internal breakpoints should be allowed to do their job, we
434 // can make sure they don't do anything that would cause recursive
435 // command execution:
436 if (!m_was_all_internal) {
437 m_should_stop = !ignoring_breakpoints;
438 LLDB_LOGF(log,
439 "StopInfoBreakpoint::PerformAction - in expression, "
440 "continuing: %s.",
441 m_should_stop ? "true" : "false");
443 "hit breakpoint while running function, skipping commands "
444 "and conditions to prevent recursion",
445 process->GetTarget().GetDebugger().GetID());
446 return;
447 }
448 }
449
450 StoppointCallbackContext context(event_ptr, exe_ctx, false);
451
452 // For safety's sake let's also grab an extra reference to the
453 // breakpoint constituents of the locations we're going to examine,
454 // since the locations are going to have to get back to their
455 // breakpoints, and the locations don't keep their constituents alive.
456 // I'm just sticking the BreakpointSP's in a vector since I'm only
457 // using it to locally increment their retain counts.
458
459 // We are holding onto the breakpoint locations that were hit
460 // by this stop info between the "synchonous" ShouldStop and now.
461 // But an intervening action might have deleted one of the breakpoints
462 // we hit before we get here. So at the same time let's build a list
463 // of the still valid locations:
464 std::vector<lldb::BreakpointSP> location_constituents;
465
467 for (size_t j = 0; j < num_constituents; j++) {
468 BreakpointLocationSP loc_sp(m_async_stopped_locs.GetByIndex(j));
469 if (loc_sp->IsValid()) {
470 location_constituents.push_back(
471 loc_sp->GetBreakpoint().shared_from_this());
472 valid_locs.Add(loc_sp);
473 }
474 }
475
476 size_t num_valid_locs = valid_locs.GetSize();
477 for (size_t j = 0; j < num_valid_locs; j++) {
478 lldb::BreakpointLocationSP bp_loc_sp = valid_locs.GetByIndex(j);
479 StreamString loc_desc;
480 if (log) {
481 bp_loc_sp->GetDescription(&loc_desc, eDescriptionLevelBrief);
482 }
483 // If another action disabled this breakpoint or its location, then
484 // don't run the actions.
485 if (!bp_loc_sp->IsEnabled() ||
486 !bp_loc_sp->GetBreakpoint().IsEnabled())
487 continue;
488
489 // The breakpoint site may have many locations associated with it,
490 // not all of them valid for this thread. Skip the ones that
491 // aren't:
492 if (!bp_loc_sp->ValidForThisThread(*thread_sp)) {
493 LLDB_LOGF(log,
494 "Breakpoint %s hit on thread 0x%llx but it was not "
495 "for this thread, continuing.",
496 loc_desc.GetData(),
497 static_cast<unsigned long long>(thread_sp->GetID()));
498 continue;
499 }
500
501 // First run the precondition, but since the precondition is per
502 // breakpoint, only run it once per breakpoint.
503 std::pair<std::unordered_set<break_id_t>::iterator, bool> result =
504 precondition_breakpoints.insert(
505 bp_loc_sp->GetBreakpoint().GetID());
506 if (!result.second)
507 continue;
508
509 bool precondition_result =
510 bp_loc_sp->GetBreakpoint().EvaluatePrecondition(context);
511 if (!precondition_result) {
512 actually_said_continue = true;
513 continue;
514 }
515 // Next run the condition for the breakpoint. If that says we
516 // should stop, then we'll run the callback for the breakpoint. If
517 // the callback says we shouldn't stop that will win.
518
519 if (!bp_loc_sp->GetCondition())
520 actually_hit_any_locations = true;
521 else {
522 Status condition_error;
523 bool condition_says_stop =
524 bp_loc_sp->ConditionSaysStop(exe_ctx, condition_error);
525
526 if (!condition_error.Success()) {
527 // If the condition fails to evaluate, we are going to stop
528 // at it, so the location was hit.
529 actually_hit_any_locations = true;
530 const char *err_str =
531 condition_error.AsCString("<unknown error>");
532 LLDB_LOGF(log, "Error evaluating condition: \"%s\"\n", err_str);
533
534 StreamString strm;
535 strm << "stopped due to an error evaluating condition of "
536 "breakpoint ";
537 bp_loc_sp->GetDescription(&strm, eDescriptionLevelBrief);
538 strm << ": \"" << bp_loc_sp->GetCondition().GetText() << "\"\n";
539 strm << err_str;
540
542 strm.GetString().str(),
543 exe_ctx.GetTargetRef().GetDebugger().GetID());
544 } else {
545 LLDB_LOGF(log,
546 "Condition evaluated for breakpoint %s on thread "
547 "0x%llx condition_says_stop: %i.",
548 loc_desc.GetData(),
549 static_cast<unsigned long long>(thread_sp->GetID()),
550 condition_says_stop);
551 if (condition_says_stop)
552 actually_hit_any_locations = true;
553 else {
554 // We don't want to increment the hit count of breakpoints if
555 // the condition fails. We've already bumped it by the time
556 // we get here, so undo the bump:
557 bp_loc_sp->UndoBumpHitCount();
558 actually_said_continue = true;
559 continue;
560 }
561 }
562 }
563
564 // We've done all the checks whose failure means "we consider lldb
565 // not to have hit the breakpoint". Now we're going to check for
566 // conditions that might continue after hitting. Start with the
567 // ignore count:
568 if (!bp_loc_sp->IgnoreCountShouldStop()) {
569 actually_said_continue = true;
570 continue;
571 }
572
573 // Check the auto-continue bit on the location, do this before the
574 // callback since it may change this, but that would be for the
575 // NEXT hit. Note, you might think you could check auto-continue
576 // before the condition, and not evaluate the condition if it says
577 // to continue. But failing the condition means the breakpoint was
578 // effectively NOT HIT. So these two states are different.
579 bool auto_continue_says_stop = true;
580 if (bp_loc_sp->IsAutoContinue())
581 {
582 LLDB_LOGF(log,
583 "Continuing breakpoint %s as AutoContinue was set.",
584 loc_desc.GetData());
585 // We want this stop reported, so you will know we auto-continued
586 // but only for external breakpoints:
587 if (!bp_loc_sp->GetBreakpoint().IsInternal())
588 thread_sp->SetShouldReportStop(eVoteYes);
589 auto_continue_says_stop = false;
590 }
591
592 bool callback_says_stop = true;
593
594 // FIXME: For now the callbacks have to run in async mode - the
595 // first time we restart we need
596 // to get out of there. So set it here.
597 // When we figure out how to nest breakpoint hits then this will
598 // change.
599
600 // Don't run async callbacks in PerformAction. They have already
601 // been taken into account with async_should_stop.
602 if (!bp_loc_sp->IsCallbackSynchronous()) {
603 Debugger &debugger = thread_sp->CalculateTarget()->GetDebugger();
604 bool old_async = debugger.GetAsyncExecution();
605 debugger.SetAsyncExecution(true);
606
607 callback_says_stop = bp_loc_sp->InvokeCallback(&context);
608
609 debugger.SetAsyncExecution(old_async);
610
611 if (callback_says_stop && auto_continue_says_stop)
612 m_should_stop = true;
613 else
614 actually_said_continue = true;
615 }
616
617 if (m_should_stop && !bp_loc_sp->GetBreakpoint().IsInternal())
618 all_stopping_locs_internal = false;
619
620 // If we are going to stop for this breakpoint, then remove the
621 // breakpoint.
622 if (callback_says_stop && bp_loc_sp &&
623 bp_loc_sp->GetBreakpoint().IsOneShot()) {
624 thread_sp->GetProcess()->GetTarget().RemoveBreakpointByID(
625 bp_loc_sp->GetBreakpoint().GetID());
626 }
627 // Also make sure that the callback hasn't continued the target. If
628 // it did, when we'll set m_should_start to false and get out of
629 // here.
630 if (HasTargetRunSinceMe()) {
631 m_should_stop = false;
632 actually_said_continue = true;
633 break;
634 }
635 }
636 // At this point if nobody actually told us to continue, we should
637 // give the async breakpoint callback a chance to weigh in:
638 if (!actually_said_continue && !m_should_stop) {
639 m_should_stop = async_should_stop;
640 }
641 }
642 // We've figured out what this stop wants to do, so mark it as valid so
643 // we don't compute it again.
645 } else {
646 m_should_stop = true;
648 actually_hit_any_locations = true;
649 Log *log_process(GetLog(LLDBLog::Process));
650
651 LLDB_LOGF(log_process,
652 "Process::%s could not find breakpoint site id: %" PRId64
653 "...",
654 __FUNCTION__, m_value);
655 }
656
657 if ((!m_should_stop || all_stopping_locs_internal) &&
658 thread_sp->CompletedPlanOverridesBreakpoint()) {
659
660 // Override should_stop decision when we have completed step plan
661 // additionally to the breakpoint
662 m_should_stop = true;
663
664 // We know we're stopping for a completed plan and we don't want to
665 // show the breakpoint stop, so compute the public stop info immediately
666 // here.
667 thread_sp->CalculatePublicStopInfo();
668 } else if (!actually_hit_any_locations) {
669 // In the end, we didn't actually have any locations that passed their
670 // "was I hit" checks. So say we aren't stopped.
671 GetThread()->ResetStopInfo();
672 LLDB_LOGF(log, "Process::%s all locations failed condition checks.",
673 __FUNCTION__);
674 }
675
676 LLDB_LOGF(log,
677 "Process::%s returning from action with m_should_stop: %d.",
678 __FUNCTION__, m_should_stop);
679 }
680 }
681
682private:
685 return {};
686
687 ThreadSP thread_sp = GetThread();
688 if (!thread_sp)
689 return {};
690 ProcessSP process_sp = thread_sp->GetProcess();
691 if (!process_sp)
692 return {};
693
694 return process_sp->GetBreakpointSiteList().FindByID(m_value);
695 }
696
699 bool m_should_perform_action; // Since we are trying to preserve the "state"
700 // of the system even if we run functions
701 // etc. behind the users backs, we need to make sure we only REALLY perform
702 // the action once.
703 lldb::addr_t m_address; // We use this to capture the breakpoint site address
704 // when we create the StopInfo,
705 // in case somebody deletes it between the time the StopInfo is made and the
706 // description is asked for.
710 /// The StopInfoBreakpoint lives after the stop, and could get queried
711 /// at any time so we need to make sure that it keeps the breakpoints for
712 /// each of the locations it records alive while it is around. That's what
713 /// The BreakpointPreservingLocationCollection does.
715};
716
717// StopInfoWatchpoint
718
720public:
721 // Make sure watchpoint is properly disabled and subsequently enabled while
722 // performing watchpoint actions.
724 public:
726 watchpoint_sp(w_sp) {
727 if (process_sp && watchpoint_sp) {
728 const bool notify = false;
729 watchpoint_sp->TurnOnEphemeralMode();
730 process_sp->DisableWatchpoint(watchpoint_sp, notify);
731 process_sp->AddPreResumeAction(SentryPreResumeAction, this);
732 }
733 }
734
735 void DoReenable() {
736 if (process_sp && watchpoint_sp) {
737 bool was_disabled = watchpoint_sp->IsDisabledDuringEphemeralMode();
738 watchpoint_sp->TurnOffEphemeralMode();
739 const bool notify = false;
740 if (was_disabled) {
741 process_sp->DisableWatchpoint(watchpoint_sp, notify);
742 } else {
743 process_sp->EnableWatchpoint(watchpoint_sp, notify);
744 }
745 }
746 }
747
749 DoReenable();
750 if (process_sp)
751 process_sp->ClearPreResumeAction(SentryPreResumeAction, this);
752 }
753
754 static bool SentryPreResumeAction(void *sentry_void) {
755 WatchpointSentry *sentry = (WatchpointSentry *) sentry_void;
756 sentry->DoReenable();
757 return true;
758 }
759
760 private:
763 };
764
765 StopInfoWatchpoint(Thread &thread, break_id_t watch_id, bool silently_skip_wp)
766 : StopInfo(thread, watch_id), m_silently_skip_wp(silently_skip_wp) {}
767
768 ~StopInfoWatchpoint() override = default;
769
770 StopReason GetStopReason() const override { return eStopReasonWatchpoint; }
771
772 uint32_t GetStopReasonDataCount() const override { return 1; }
773 uint64_t GetStopReasonDataAtIndex(uint32_t idx) override {
774 if (idx == 0)
775 return GetValue();
776 return 0;
777 }
778
779 const char *GetDescription() override {
780 if (m_description.empty()) {
781 StreamString strm;
782 strm.Printf("watchpoint %" PRIi64, m_value);
783 m_description = std::string(strm.GetString());
784 }
785 return m_description.c_str();
786 }
787
788protected:
789 using StopInfoWatchpointSP = std::shared_ptr<StopInfoWatchpoint>;
790 // This plan is used to orchestrate stepping over the watchpoint for
791 // architectures (e.g. ARM) that report the watch before running the watched
792 // access. This is the sort of job you have to defer to the thread plans,
793 // if you try to do it directly in the stop info and there are other threads
794 // that needed to process this stop you will have yanked control away from
795 // them and they won't behave correctly.
797 public:
799 StopInfoWatchpointSP stop_info_sp,
800 WatchpointSP watch_sp)
801 : ThreadPlanStepInstruction(thread, false, true, eVoteNoOpinion,
803 m_stop_info_sp(stop_info_sp), m_watch_sp(watch_sp) {
804 assert(watch_sp);
805 }
806
807 bool DoWillResume(lldb::StateType resume_state,
808 bool current_plan) override {
809 if (resume_state == eStateSuspended)
810 return true;
811
812 if (!m_did_disable_wp) {
813 GetThread().GetProcess()->DisableWatchpoint(m_watch_sp, false);
814 m_did_disable_wp = true;
815 }
816 return true;
817 }
818
819 bool DoPlanExplainsStop(Event *event_ptr) override {
821 return true;
822 StopInfoSP stop_info_sp = GetThread().GetPrivateStopInfo();
823 // lldb-server resets the stop info for threads that didn't get to run,
824 // so we might have not gotten to run, but still have a watchpoint stop
825 // reason, in which case this will indeed be for us.
826 if (stop_info_sp
827 && stop_info_sp->GetStopReason() == eStopReasonWatchpoint)
828 return true;
829 return false;
830 }
831
832 void DidPop() override {
833 // Don't artifically keep the watchpoint alive.
834 m_watch_sp.reset();
835 }
836
837 bool ShouldStop(Event *event_ptr) override {
838 bool should_stop = ThreadPlanStepInstruction::ShouldStop(event_ptr);
839 bool plan_done = MischiefManaged();
840 if (plan_done) {
841 m_stop_info_sp->SetStepOverPlanComplete();
844 }
845 return should_stop;
846 }
847
849 return true;
850 }
851
852 protected:
854 if (!m_did_disable_wp)
855 return;
856 m_did_disable_wp = true;
857 GetThread().GetProcess()->EnableWatchpoint(m_watch_sp, true);
858 }
859
860 private:
863 bool m_did_disable_wp = false;
864 };
865
866 bool ShouldStopSynchronous(Event *event_ptr) override {
867 // Watchpoint callbacks run on the PST during stop processing. Push
868 // private state context so callback code sees the private reality.
870
871 // If we are running our step-over the watchpoint plan, stop if it's done
872 // and continue if it's not:
874 return m_should_stop;
875
876 // If we are running our step over plan, then stop here and let the regular
877 // ShouldStop figure out what we should do: Otherwise, give our plan
878 // more time to get run:
881
883 ThreadSP thread_sp(m_thread_wp.lock());
884 assert(thread_sp);
885
886 if (thread_sp->GetTemporaryResumeState() == eStateSuspended) {
887 // This is the second firing of a watchpoint so don't process it again.
888 LLDB_LOG(log, "We didn't run but stopped with a StopInfoWatchpoint, we "
889 "have already handled this one, don't do it again.");
890 m_should_stop = false;
892 return m_should_stop;
893 }
894
895 WatchpointSP wp_sp(
896 thread_sp->CalculateTarget()->GetWatchpointList().FindByID(GetValue()));
897 // If we can no longer find the watchpoint, we just have to stop:
898 if (!wp_sp) {
899
900 LLDB_LOGF(log,
901 "Process::%s could not find watchpoint location id: %" PRId64
902 "...",
903 __FUNCTION__, GetValue());
904
905 m_should_stop = true;
907 return true;
908 }
909
910 ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0));
911 StoppointCallbackContext context(event_ptr, exe_ctx, true);
912 m_should_stop = wp_sp->ShouldStop(&context);
913 if (!m_should_stop) {
914 // This won't happen at present because we only allow one watchpoint per
915 // watched range. So we won't stop at a watched address with a disabled
916 // watchpoint. If we start allowing overlapping watchpoints, then we
917 // will have to make watchpoints be real "WatchpointSite" and delegate to
918 // all the watchpoints sharing the site. In that case, the code below
919 // would be the right thing to do.
921 return m_should_stop;
922 }
923 // If this is a system where we need to execute the watchpoint by hand
924 // after the hit, queue a thread plan to do that, and then say not to stop.
925 // Otherwise, let the async action figure out whether the watchpoint should
926 // stop
927
928 ProcessSP process_sp = exe_ctx.GetProcessSP();
929 bool wp_triggers_after = process_sp->GetWatchpointReportedAfter();
930
931 if (!wp_triggers_after) {
932 // We have to step over the watchpoint before we know what to do:
933 StopInfoWatchpointSP me_as_siwp_sp
934 = std::static_pointer_cast<StopInfoWatchpoint>(shared_from_this());
935 ThreadPlanSP step_over_wp_sp =
936 std::make_shared<ThreadPlanStepOverWatchpoint>(*(thread_sp.get()),
937 me_as_siwp_sp, wp_sp);
938 // When this plan is done we want to stop, so set this as a Controlling
939 // plan.
940 step_over_wp_sp->SetIsControllingPlan(true);
941 step_over_wp_sp->SetOkayToDiscard(false);
942
944 error = thread_sp->QueueThreadPlan(step_over_wp_sp, false);
945 // If we couldn't push the thread plan, just stop here:
946 if (!error.Success()) {
947 LLDB_LOGF(log, "Could not push our step over watchpoint plan: %s",
948 error.AsCString());
949
950 m_should_stop = true;
952 return true;
953 } else {
954 // Otherwise, don't set m_should_stop, we don't know that yet. Just
955 // say we should continue, and tell the thread we really should do so:
956 thread_sp->SetShouldRunBeforePublicStop(true);
958 return false;
959 }
960 } else {
961 // We didn't have to do anything special
963 return m_should_stop;
964 }
965
966 return m_should_stop;
967 }
968
969 bool ShouldStop(Event *event_ptr) override {
970 // This just reports the work done by PerformAction or the synchronous
971 // stop. It should only ever get called after they have had a chance to
972 // run.
974 return m_should_stop;
975 }
976
977 void PerformAction(Event *event_ptr) override {
979
980 Policy policy = PolicyStack::Get().Current();
982 m_should_stop = false;
984 LLDB_LOGF(log, "StopInfoWatchpoint::PerformAction - Hit a "
985 "watchpoint while running an expression,"
986 " not running commands to avoid recursion.");
987 return;
988 }
989
990 // We're going to calculate if we should stop or not in some way during the
991 // course of this code. Also by default we're going to stop, so set that
992 // here.
993 m_should_stop = true;
994
995
996 ThreadSP thread_sp(m_thread_wp.lock());
997 if (thread_sp) {
998
999 WatchpointSP wp_sp(
1000 thread_sp->CalculateTarget()->GetWatchpointList().FindByID(
1001 GetValue()));
1002 if (wp_sp) {
1003 // This sentry object makes sure the current watchpoint is disabled
1004 // while performing watchpoint actions, and it is then enabled after we
1005 // are finished.
1006 ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0));
1007 ProcessSP process_sp = exe_ctx.GetProcessSP();
1008
1009 WatchpointSentry sentry(process_sp, wp_sp);
1010
1011 if (m_silently_skip_wp) {
1012 m_should_stop = false;
1013 wp_sp->UndoHitCount();
1014 }
1015
1016 if (wp_sp->GetHitCount() <= wp_sp->GetIgnoreCount()) {
1017 m_should_stop = false;
1019 }
1020
1021 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
1022
1023 if (m_should_stop && wp_sp->GetConditionText() != nullptr) {
1024 // We need to make sure the user sees any parse errors in their
1025 // condition, so we'll hook the constructor errors up to the
1026 // debugger's Async I/O.
1027 ExpressionResults result_code;
1028 EvaluateExpressionOptions expr_options;
1029 expr_options.SetUnwindOnError(true);
1030 expr_options.SetIgnoreBreakpoints(true);
1031 ValueObjectSP result_value_sp;
1032 result_code = UserExpression::Evaluate(
1033 exe_ctx, expr_options, wp_sp->GetConditionText(),
1034 llvm::StringRef(), result_value_sp);
1035
1036 if (result_code == eExpressionCompleted) {
1037 if (result_value_sp) {
1038 Scalar scalar_value;
1039 if (result_value_sp->ResolveValue(scalar_value)) {
1040 if (scalar_value.ULongLong(1) == 0) {
1041 // The condition failed, which we consider "not having hit
1042 // the watchpoint" so undo the hit count here.
1043 wp_sp->UndoHitCount();
1044 m_should_stop = false;
1045 } else
1046 m_should_stop = true;
1047 LLDB_LOGF(log,
1048 "Condition successfully evaluated, result is %s.\n",
1049 m_should_stop ? "true" : "false");
1050 } else {
1051 m_should_stop = true;
1052 LLDB_LOGF(
1053 log,
1054 "Failed to get an integer result from the expression.");
1055 }
1056 }
1057 } else {
1058 const char *err_str = "<unknown error>";
1059 if (result_value_sp)
1060 err_str = result_value_sp->GetError().AsCString();
1061
1062 LLDB_LOGF(log, "Error evaluating condition: \"%s\"\n", err_str);
1063
1064 StreamString strm;
1065 strm << "stopped due to an error evaluating condition of "
1066 "watchpoint ";
1067 wp_sp->GetDescription(&strm, eDescriptionLevelBrief);
1068 strm << ": \"" << wp_sp->GetConditionText() << "\"\n";
1069 strm << err_str;
1070
1071 Debugger::ReportError(strm.GetString().str(),
1072 exe_ctx.GetTargetRef().GetDebugger().GetID());
1073 }
1074 }
1075
1076 // If the condition says to stop, we run the callback to further decide
1077 // whether to stop.
1078 if (m_should_stop) {
1079 // FIXME: For now the callbacks have to run in async mode - the
1080 // first time we restart we need
1081 // to get out of there. So set it here.
1082 // When we figure out how to nest watchpoint hits then this will
1083 // change.
1084
1085 bool old_async = debugger.GetAsyncExecution();
1086 debugger.SetAsyncExecution(true);
1087
1088 StoppointCallbackContext context(event_ptr, exe_ctx, false);
1089 bool stop_requested = wp_sp->InvokeCallback(&context);
1090
1091 debugger.SetAsyncExecution(old_async);
1092
1093 // Also make sure that the callback hasn't continued the target. If
1094 // it did, when we'll set m_should_stop to false and get out of here.
1095 if (HasTargetRunSinceMe())
1096 m_should_stop = false;
1097
1098 if (m_should_stop && !stop_requested) {
1099 // We have been vetoed by the callback mechanism.
1100 m_should_stop = false;
1101 }
1102 }
1103
1104 // Don't stop if the watched region value is unmodified, and
1105 // this is a Modify-type watchpoint.
1106 if (m_should_stop && !wp_sp->WatchedValueReportable(exe_ctx)) {
1107 wp_sp->UndoHitCount();
1108 m_should_stop = false;
1109 }
1110
1111 // Finally, if we are going to stop, print out the new & old values:
1112 if (m_should_stop) {
1113 wp_sp->CaptureWatchedValue(exe_ctx);
1114
1115 Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
1116 StreamUP output_up = debugger.GetAsyncOutputStream();
1117 if (wp_sp->DumpSnapshots(output_up.get()))
1118 output_up->EOL();
1119 }
1120
1121 } else {
1122 Log *log_process(GetLog(LLDBLog::Process));
1123
1124 LLDB_LOGF(log_process,
1125 "Process::%s could not find watchpoint id: %" PRId64 "...",
1126 __FUNCTION__, m_value);
1127 }
1128 LLDB_LOGF(log,
1129 "Process::%s returning from action with m_should_stop: %d.",
1130 __FUNCTION__, m_should_stop);
1131
1133 }
1134 }
1135
1136private:
1141
1142 bool m_should_stop = false;
1144 // A false watchpoint hit has happened -
1145 // the thread stopped with a watchpoint
1146 // hit notification, but the watched region
1147 // was not actually accessed (as determined
1148 // by the gdb stub we're talking to).
1149 // Continue past this watchpoint without
1150 // notifying the user; on some targets this
1151 // may mean disable wp, instruction step,
1152 // re-enable wp, continue.
1153 // On others, just continue.
1157};
1158
1159// StopInfoUnixSignal
1160
1162public:
1163 StopInfoUnixSignal(Thread &thread, int signo, const char *description,
1164 std::optional<int> code)
1165 : StopInfo(thread, signo), m_code(code) {
1166 SetDescription(description);
1167 }
1168
1169 ~StopInfoUnixSignal() override = default;
1170
1171 StopReason GetStopReason() const override { return eStopReasonSignal; }
1172
1173 bool ShouldStopSynchronous(Event *event_ptr) override {
1174 ThreadSP thread_sp(m_thread_wp.lock());
1175 if (thread_sp)
1176 return thread_sp->GetProcess()->GetUnixSignals()->GetShouldStop(m_value);
1177 return false;
1178 }
1179
1180 bool ShouldStop(Event *event_ptr) override { return IsShouldStopSignal(); }
1181
1182 // If should stop returns false, check if we should notify of this event
1183 bool DoShouldNotify(Event *event_ptr) override {
1184 ThreadSP thread_sp(m_thread_wp.lock());
1185 if (thread_sp) {
1186 bool should_notify =
1187 thread_sp->GetProcess()->GetUnixSignals()->GetShouldNotify(m_value);
1188 if (should_notify) {
1189 StreamString strm;
1190 strm.Format(
1191 "thread {0:d} received signal: {1}", thread_sp->GetIndexID(),
1192 thread_sp->GetProcess()->GetUnixSignals()->GetSignalAsStringRef(
1193 m_value));
1195 strm.GetData());
1196 }
1197 return should_notify;
1198 }
1199 return true;
1200 }
1201
1202 void WillResume(lldb::StateType resume_state) override {
1203 ThreadSP thread_sp(m_thread_wp.lock());
1204 if (thread_sp) {
1205 if (!thread_sp->GetProcess()->GetUnixSignals()->GetShouldSuppress(
1206 m_value))
1207 thread_sp->SetResumeSignal(m_value);
1208 }
1209 }
1210
1211 const char *GetDescription() override {
1212 if (m_description.empty()) {
1213 ThreadSP thread_sp(m_thread_wp.lock());
1214 if (thread_sp) {
1215 UnixSignalsSP unix_signals = thread_sp->GetProcess()->GetUnixSignals();
1216 StreamString strm;
1217 strm << "signal ";
1218
1219 std::string signal_name =
1220 unix_signals->GetSignalDescription(m_value, m_code);
1221 if (signal_name.size())
1222 strm << signal_name;
1223 else
1224 strm.Printf("%" PRIi64, m_value);
1225
1226 m_description = std::string(strm.GetString());
1227 }
1228 }
1229 return m_description.c_str();
1230 }
1231
1232 bool ShouldSelect() const override { return IsShouldStopSignal(); }
1233
1234 uint32_t GetStopReasonDataCount() const override { return 1; }
1235 uint64_t GetStopReasonDataAtIndex(uint32_t idx) override {
1236 if (idx == 0)
1237 return GetValue();
1238 return 0;
1239 }
1240
1241private:
1242 // In siginfo_t terms, if m_value is si_signo, m_code is si_code.
1243 std::optional<int> m_code;
1244
1245 bool IsShouldStopSignal() const {
1246 if (ThreadSP thread_sp = m_thread_wp.lock())
1247 return thread_sp->GetProcess()->GetUnixSignals()->GetShouldStop(m_value);
1248 return false;
1249 }
1250};
1251
1252// StopInfoInterrupt
1253
1255public:
1256 StopInfoInterrupt(Thread &thread, int signo, const char *description)
1257 : StopInfo(thread, signo) {
1258 SetDescription(description);
1259 }
1260
1261 ~StopInfoInterrupt() override = default;
1262
1263 StopReason GetStopReason() const override {
1265 }
1266
1267 const char *GetDescription() override {
1268 if (m_description.empty()) {
1269 m_description = "async interrupt";
1270 }
1271 return m_description.c_str();
1272 }
1273
1274 uint32_t GetStopReasonDataCount() const override { return 1; }
1275 uint64_t GetStopReasonDataAtIndex(uint32_t idx) override {
1276 if (idx == 0)
1277 return GetValue();
1278 else
1279 return 0;
1280 }
1281};
1282
1283// StopInfoTrace
1284
1285class StopInfoTrace : public StopInfo {
1286public:
1288
1289 ~StopInfoTrace() override = default;
1290
1291 StopReason GetStopReason() const override { return eStopReasonTrace; }
1292
1293 const char *GetDescription() override {
1294 if (m_description.empty())
1295 return "trace";
1296 else
1297 return m_description.c_str();
1298 }
1299
1300 std::optional<uint32_t>
1301 GetSuggestedStackFrameIndex(bool inlined_stack) override {
1302 // Trace only knows how to adjust inlined stacks:
1303 if (!inlined_stack)
1304 return {};
1305
1306 ThreadSP thread_sp = GetThread();
1307 StackFrameSP frame_0_sp = thread_sp->GetStackFrameAtIndex(0);
1308 if (!frame_0_sp)
1309 return {};
1310 if (!frame_0_sp->IsInlined())
1311 return {};
1312 Block *block_ptr = frame_0_sp->GetFrameBlock();
1313 if (!block_ptr)
1314 return {};
1315 Address pc_address = frame_0_sp->GetFrameCodeAddress();
1316 AddressRange containing_range;
1317 if (!block_ptr->GetRangeContainingAddress(pc_address, containing_range) ||
1318 pc_address != containing_range.GetBaseAddress())
1319 return {};
1320
1321 int num_inlined_functions = 0;
1322
1323 for (Block *container_ptr = block_ptr->GetInlinedParent();
1324 container_ptr != nullptr;
1325 container_ptr = container_ptr->GetInlinedParent()) {
1326 if (!container_ptr->GetRangeContainingAddress(pc_address,
1327 containing_range))
1328 break;
1329 if (pc_address != containing_range.GetBaseAddress())
1330 break;
1331
1332 num_inlined_functions++;
1333 }
1334 inlined_stack = true;
1335 return num_inlined_functions + 1;
1336 }
1337};
1338
1339// StopInfoException
1340
1342public:
1343 StopInfoException(Thread &thread, const char *description)
1344 : StopInfo(thread, LLDB_INVALID_UID) {
1345 if (description)
1346 SetDescription(description);
1347 }
1348
1349 ~StopInfoException() override = default;
1350
1351 StopReason GetStopReason() const override { return eStopReasonException; }
1352
1353 const char *GetDescription() override {
1354 if (m_description.empty())
1355 return "exception";
1356 else
1357 return m_description.c_str();
1358 }
1359 uint32_t GetStopReasonDataCount() const override { return 1; }
1360 uint64_t GetStopReasonDataAtIndex(uint32_t idx) override {
1361 if (idx == 0)
1362 return GetValue();
1363 else
1364 return 0;
1365 }
1366};
1367
1368// StopInfoProcessorTrace
1369
1371public:
1372 StopInfoProcessorTrace(Thread &thread, const char *description)
1373 : StopInfo(thread, LLDB_INVALID_UID) {
1374 if (description)
1375 SetDescription(description);
1376 }
1377
1378 ~StopInfoProcessorTrace() override = default;
1379
1380 StopReason GetStopReason() const override {
1382 }
1383
1384 const char *GetDescription() override {
1385 if (m_description.empty())
1386 return "processor trace event";
1387 else
1388 return m_description.c_str();
1389 }
1390};
1391
1392// StopInfoHistoryBoundary
1393
1395public:
1396 StopInfoHistoryBoundary(Thread &thread, const char *description)
1397 : StopInfo(thread, LLDB_INVALID_UID) {
1398 if (description)
1399 SetDescription(description);
1400 }
1401
1402 ~StopInfoHistoryBoundary() override = default;
1403
1404 StopReason GetStopReason() const override {
1406 }
1407
1408 const char *GetDescription() override {
1409 if (m_description.empty())
1410 return "history boundary";
1411 return m_description.c_str();
1412 }
1413};
1414
1415// StopInfoThreadPlan
1416
1418public:
1419 StopInfoThreadPlan(ThreadPlanSP &plan_sp, ValueObjectSP &return_valobj_sp,
1420 ExpressionVariableSP &expression_variable_sp)
1421 : StopInfo(plan_sp->GetThread(), LLDB_INVALID_UID), m_plan_sp(plan_sp),
1422 m_return_valobj_sp(return_valobj_sp),
1423 m_expression_variable_sp(expression_variable_sp) {}
1424
1425 ~StopInfoThreadPlan() override = default;
1426
1428
1429 const char *GetDescription() override {
1430 if (m_description.empty()) {
1431 StreamString strm;
1432 m_plan_sp->GetDescription(&strm, eDescriptionLevelBrief);
1433 m_description = std::string(strm.GetString());
1434 }
1435 return m_description.c_str();
1436 }
1437
1439
1443
1444protected:
1445 bool ShouldStop(Event *event_ptr) override {
1446 if (m_plan_sp)
1447 return m_plan_sp->ShouldStop(event_ptr);
1448 else
1449 return StopInfo::ShouldStop(event_ptr);
1450 }
1451
1452private:
1456};
1457
1458// StopInfoExec
1459
1460class StopInfoExec : public StopInfo {
1461public:
1463
1464 ~StopInfoExec() override = default;
1465
1466 bool ShouldStop(Event *event_ptr) override {
1467 ThreadSP thread_sp(m_thread_wp.lock());
1468 if (thread_sp)
1469 return thread_sp->GetProcess()->GetStopOnExec();
1470 return false;
1471 }
1472
1473 StopReason GetStopReason() const override { return eStopReasonExec; }
1474
1475 const char *GetDescription() override { return "exec"; }
1476
1477protected:
1478 void PerformAction(Event *event_ptr) override {
1479 // Only perform the action once
1481 return;
1482 m_performed_action = true;
1483 ThreadSP thread_sp(m_thread_wp.lock());
1484 if (thread_sp)
1485 thread_sp->GetProcess()->DidExec();
1486 }
1487
1489};
1490
1491
1492// StopInfoFork
1493
1494class StopInfoFork : public StopInfo {
1495public:
1496 StopInfoFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
1497 : StopInfo(thread, child_pid), m_child_pid(child_pid),
1498 m_child_tid(child_tid) {}
1499
1500 ~StopInfoFork() override = default;
1501
1502 bool ShouldStop(Event *event_ptr) override {
1503 // During expression evaluation, return true so that the fork event
1504 // reaches RunThreadPlan as a real stop (not auto-restarted by
1505 // DoOnRemoval). RunThreadPlan decides whether to stop or continue
1506 // based on the stop-on-fork option.
1507 //
1508 // We check per-thread (not just process-wide IsRunningExpression)
1509 // because other threads may fork concurrently after the
1510 // try-all-threads timeout releases them.
1511 ThreadSP thread_sp(m_thread_wp.lock());
1512 if (thread_sp) {
1513 ProcessSP process_sp = thread_sp->GetProcess();
1514 if (process_sp && process_sp->GetModIDRef().IsRunningExpression() &&
1515 thread_sp->IsRunningCallFunctionPlan())
1516 return true;
1517 }
1518 return false;
1519 }
1520
1521 StopReason GetStopReason() const override { return eStopReasonFork; }
1522
1523 const char *GetDescription() override { return "fork"; }
1524
1525 uint32_t GetStopReasonDataCount() const override { return 1; }
1526 uint64_t GetStopReasonDataAtIndex(uint32_t idx) override {
1527 if (idx == 0)
1528 return GetValue();
1529 else
1530 return 0;
1531 }
1532
1533protected:
1534 void PerformAction(Event *event_ptr) override {
1535 // Only perform the action once
1537 return;
1538 m_performed_action = true;
1539 ThreadSP thread_sp(m_thread_wp.lock());
1540 if (thread_sp) {
1541 bool is_expression_fork =
1542 thread_sp->GetProcess()->GetModIDRef().IsRunningExpression() &&
1543 thread_sp->IsRunningCallFunctionPlan();
1544 thread_sp->GetProcess()->DidFork(m_child_pid, m_child_tid,
1545 is_expression_fork);
1546 }
1547 }
1548
1550
1551private:
1554};
1555
1556// StopInfoVFork
1557
1558class StopInfoVFork : public StopInfo {
1559public:
1560 StopInfoVFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
1561 : StopInfo(thread, child_pid), m_child_pid(child_pid),
1562 m_child_tid(child_tid) {}
1563
1564 ~StopInfoVFork() override = default;
1565
1566 bool ShouldStop(Event *event_ptr) override {
1567 ThreadSP thread_sp(m_thread_wp.lock());
1568 if (thread_sp) {
1569 ProcessSP process_sp = thread_sp->GetProcess();
1570 if (process_sp && process_sp->GetModIDRef().IsRunningExpression() &&
1571 thread_sp->IsRunningCallFunctionPlan())
1572 return true;
1573 }
1574 return false;
1575 }
1576
1577 StopReason GetStopReason() const override { return eStopReasonVFork; }
1578
1579 const char *GetDescription() override { return "vfork"; }
1580
1581 uint32_t GetStopReasonDataCount() const override { return 1; }
1582 uint64_t GetStopReasonDataAtIndex(uint32_t idx) override {
1583 if (idx == 0)
1584 return GetValue();
1585 return 0;
1586 }
1587
1588protected:
1589 void PerformAction(Event *event_ptr) override {
1590 // Only perform the action once
1592 return;
1593 m_performed_action = true;
1594 ThreadSP thread_sp(m_thread_wp.lock());
1595 if (thread_sp) {
1596 bool is_expression_fork =
1597 thread_sp->GetProcess()->GetModIDRef().IsRunningExpression() &&
1598 thread_sp->IsRunningCallFunctionPlan();
1599 thread_sp->GetProcess()->DidVFork(m_child_pid, m_child_tid,
1600 is_expression_fork);
1601 }
1602 }
1603
1605
1606private:
1609};
1610
1611// StopInfoVForkDone
1612
1614public:
1615 StopInfoVForkDone(Thread &thread) : StopInfo(thread, 0) {}
1616
1617 ~StopInfoVForkDone() override = default;
1618
1619 bool ShouldStop(Event *event_ptr) override {
1620 ThreadSP thread_sp(m_thread_wp.lock());
1621 if (thread_sp) {
1622 ProcessSP process_sp = thread_sp->GetProcess();
1623 if (process_sp && process_sp->GetModIDRef().IsRunningExpression() &&
1624 thread_sp->IsRunningCallFunctionPlan())
1625 return true;
1626 }
1627 return false;
1628 }
1629
1630 StopReason GetStopReason() const override { return eStopReasonVForkDone; }
1631
1632 const char *GetDescription() override { return "vforkdone"; }
1633
1634protected:
1635 void PerformAction(Event *event_ptr) override {
1636 // Only perform the action once
1638 return;
1639 m_performed_action = true;
1640 ThreadSP thread_sp(m_thread_wp.lock());
1641 if (thread_sp)
1642 thread_sp->GetProcess()->DidVForkDone();
1643 }
1644
1646};
1647
1648} // namespace lldb_private
1649
1651 break_id_t break_id) {
1652 thread.SetThreadHitBreakpointSite();
1653
1654 return std::make_shared<StopInfoBreakpoint>(thread, break_id);
1655}
1656
1658 break_id_t break_id,
1659 bool should_stop) {
1660 return std::make_shared<StopInfoBreakpoint>(thread, break_id, should_stop);
1661}
1662
1663// LWP_TODO: We'll need a CreateStopReasonWithWatchpointResourceID akin
1664// to CreateStopReasonWithBreakpointSiteID
1666 break_id_t watch_id,
1667 bool silently_continue) {
1668 return std::make_shared<StopInfoWatchpoint>(thread, watch_id,
1669 silently_continue);
1670}
1671
1673 const char *description,
1674 std::optional<int> code) {
1675 thread.GetProcess()->GetUnixSignals()->IncrementSignalHitCount(signo);
1676 return std::make_shared<StopInfoUnixSignal>(thread, signo, description, code);
1677}
1678
1680 const char *description) {
1681 return std::make_shared<StopInfoInterrupt>(thread, signo, description);
1682}
1683
1685 return std::make_shared<StopInfoTrace>(thread);
1686}
1687
1689 ThreadPlanSP &plan_sp, ValueObjectSP return_valobj_sp,
1690 ExpressionVariableSP expression_variable_sp) {
1691 return std::make_shared<StopInfoThreadPlan>(plan_sp, return_valobj_sp,
1692 expression_variable_sp);
1693}
1694
1696 const char *description) {
1697 return std::make_shared<StopInfoException>(thread, description);
1698}
1699
1701 const char *description) {
1702 return std::make_shared<StopInfoProcessorTrace>(thread, description);
1703}
1704
1706 const char *description) {
1707 return std::make_shared<StopInfoHistoryBoundary>(thread, description);
1708}
1709
1711 return std::make_shared<StopInfoExec>(thread);
1712}
1713
1715 lldb::pid_t child_pid,
1716 lldb::tid_t child_tid) {
1717 return std::make_shared<StopInfoFork>(thread, child_pid, child_tid);
1718}
1719
1720
1722 lldb::pid_t child_pid,
1723 lldb::tid_t child_tid) {
1724 return std::make_shared<StopInfoVFork>(thread, child_pid, child_tid);
1725}
1726
1728 return std::make_shared<StopInfoVForkDone>(thread);
1729}
1730
1732 if (stop_info_sp &&
1733 stop_info_sp->GetStopReason() == eStopReasonPlanComplete) {
1734 StopInfoThreadPlan *plan_stop_info =
1735 static_cast<StopInfoThreadPlan *>(stop_info_sp.get());
1736 return plan_stop_info->GetReturnValueObject();
1737 } else
1738 return ValueObjectSP();
1739}
1740
1742 if (stop_info_sp &&
1743 stop_info_sp->GetStopReason() == eStopReasonPlanComplete) {
1744 StopInfoThreadPlan *plan_stop_info =
1745 static_cast<StopInfoThreadPlan *>(stop_info_sp.get());
1746 return plan_stop_info->GetExpressionVariable();
1747 } else
1748 return ExpressionVariableSP();
1749}
1750
1753 lldb::addr_t *crashing_address) {
1754 if (!stop_info_sp) {
1755 return ValueObjectSP();
1756 }
1757
1758 const char *description = stop_info_sp->GetDescription();
1759 if (!description) {
1760 return ValueObjectSP();
1761 }
1762
1763 ThreadSP thread_sp = stop_info_sp->GetThread();
1764 if (!thread_sp) {
1765 return ValueObjectSP();
1766 }
1767
1768 StackFrameSP frame_sp =
1769 thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame);
1770
1771 if (!frame_sp) {
1772 return ValueObjectSP();
1773 }
1774
1775 const char address_string[] = "address=";
1776
1777 const char *address_loc = strstr(description, address_string);
1778 if (!address_loc) {
1779 return ValueObjectSP();
1780 }
1781
1782 address_loc += (sizeof(address_string) - 1);
1783
1784 uint64_t address = strtoull(address_loc, nullptr, 0);
1785 if (crashing_address) {
1786 *crashing_address = address;
1787 }
1788
1789 return frame_sp->GuessValueForAddress(address);
1790}
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:364
#define LLDB_LOGF(log,...)
Definition Log.h:378
A section + offset based address range class.
Address & GetBaseAddress()
Get accessor for the base address of the range.
A section + offset based address class.
Definition Address.h:62
A class that describes a single lexical block.
Definition Block.h:41
bool GetRangeContainingAddress(const Address &addr, AddressRange &range)
Definition Block.cpp:248
Block * GetInlinedParent()
Get the inlined parent block for this block.
Definition Block.cpp:212
lldb::BreakpointLocationSP GetByIndex(size_t i)
Returns a shared pointer to the breakpoint location with index i.
void Add(const lldb::BreakpointLocationSP &bp_loc_sp)
Add the breakpoint bp_loc_sp to the list.
size_t GetSize() const
Returns the number of elements in this breakpoint location list.
General Outline: A breakpoint has four main parts, a filter, a resolver, the list of breakpoint locat...
Definition Breakpoint.h:81
bool IsOneShot() const
Check the OneShot state.
bool IsInternal() const
Tell whether this breakpoint is an "internal" breakpoint.
A class to manage flag bits.
Definition Debugger.h:100
void SetAsyncExecution(bool async)
static void ReportWarning(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report warning events.
static void ReportError(std::string message, std::optional< lldb::user_id_t > debugger_id=std::nullopt, std::once_flag *once=nullptr)
Report error events.
lldb::StreamUP GetAsyncOutputStream()
void SetUnwindOnError(bool unwind=false)
Definition Target.h:395
void SetIgnoreBreakpoints(bool ignore=false)
Definition Target.h:399
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
const lldb::ProcessSP & GetProcessSP() const
Get accessor to get the process shared pointer.
Target & GetTargetRef() const
Returns a reference to the target object.
Process * GetProcessPtr() const
Returns a pointer to the process object.
RAII guard that pushes a policy on construction and pops on destruction.
Definition Policy.h:104
static PolicyStack & Get()
Definition Policy.h:87
Policy Current() const
Definition Policy.cpp:17
bool IsRunningExpression() const
Definition Process.h:281
bool GetIgnoreBreakpointsInExpressions() const
Definition Process.cpp:255
static void AddRestartedReason(Event *event_ptr, const char *reason)
Definition Process.cpp:4775
A plug-in interface definition class for debugging a process.
Definition Process.h:356
const ProcessModID & GetModIDRef() const
Definition Process.h:1488
Target & GetTarget()
Get the target object pointer for this module.
Definition Process.h:1254
unsigned long long ULongLong(unsigned long long fail_value=0) const
Definition Scalar.cpp:365
An error handling class.
Definition Status.h:118
const char * AsCString(const char *default_error_str="unknown error") const
Get the error string associated with the current error.
Definition Status.cpp:194
bool Success() const
Test for success condition.
Definition Status.cpp:303
void PerformAction(Event *event_ptr) override
Definition StopInfo.cpp:324
BreakpointSiteSP GetBreakpointSiteSP() const
Definition StopInfo.cpp:683
std::optional< uint32_t > GetSuggestedStackFrameIndex(bool inlined_stack) override
This gives the StopInfo a chance to suggest a stack frame to select.
Definition StopInfo.cpp:297
const char * GetDescription() override
Definition StopInfo.cpp:193
bool ShouldStopSynchronous(Event *event_ptr) override
Definition StopInfo.cpp:156
bool IsValidForOperatingSystemThread(Thread &thread) override
Definition StopInfo.cpp:144
bool DoShouldNotify(Event *event_ptr) override
Definition StopInfo.cpp:189
bool ShouldShow() const override
Returns true if this is a stop reason that should be shown to a user when viewing the thread with thi...
Definition StopInfo.cpp:311
uint32_t GetStopReasonDataCount() const override
Definition StopInfo.cpp:258
~StopInfoBreakpoint() override=default
bool ShouldSelect() const override
Returns true if this is a stop reason that should cause a thread to be selected when stopping.
Definition StopInfo.cpp:313
StopInfoBreakpoint(Thread &thread, break_id_t break_id, bool should_stop)
Definition StopInfo.cpp:103
StopInfoBreakpoint(Thread &thread, break_id_t break_id)
Definition StopInfo.cpp:94
BreakpointLocationCollection m_async_stopped_locs
The StopInfoBreakpoint lives after the stop, and could get queried at any time so we need to make sur...
Definition StopInfo.cpp:714
bool ShouldStop(Event *event_ptr) override
Definition StopInfo.cpp:316
uint64_t GetStopReasonDataAtIndex(uint32_t idx) override
Definition StopInfo.cpp:271
StopReason GetStopReason() const override
Definition StopInfo.cpp:154
uint64_t GetStopReasonDataAtIndex(uint32_t idx) override
const char * GetDescription() override
uint32_t GetStopReasonDataCount() const override
~StopInfoException() override=default
StopInfoException(Thread &thread, const char *description)
StopReason GetStopReason() const override
~StopInfoExec() override=default
StopInfoExec(Thread &thread)
const char * GetDescription() override
StopReason GetStopReason() const override
void PerformAction(Event *event_ptr) override
bool ShouldStop(Event *event_ptr) override
uint32_t GetStopReasonDataCount() const override
void PerformAction(Event *event_ptr) override
bool ShouldStop(Event *event_ptr) override
StopReason GetStopReason() const override
uint64_t GetStopReasonDataAtIndex(uint32_t idx) override
StopInfoFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
~StopInfoFork() override=default
const char * GetDescription() override
StopReason GetStopReason() const override
const char * GetDescription() override
~StopInfoHistoryBoundary() override=default
StopInfoHistoryBoundary(Thread &thread, const char *description)
uint32_t GetStopReasonDataCount() const override
StopInfoInterrupt(Thread &thread, int signo, const char *description)
const char * GetDescription() override
StopReason GetStopReason() const override
uint64_t GetStopReasonDataAtIndex(uint32_t idx) override
~StopInfoInterrupt() override=default
StopInfoProcessorTrace(Thread &thread, const char *description)
~StopInfoProcessorTrace() override=default
const char * GetDescription() override
StopReason GetStopReason() const override
bool ShouldStop(Event *event_ptr) override
~StopInfoThreadPlan() override=default
ExpressionVariableSP m_expression_variable_sp
ExpressionVariableSP GetExpressionVariable()
const char * GetDescription() override
StopReason GetStopReason() const override
StopInfoThreadPlan(ThreadPlanSP &plan_sp, ValueObjectSP &return_valobj_sp, ExpressionVariableSP &expression_variable_sp)
const char * GetDescription() override
~StopInfoTrace() override=default
StopReason GetStopReason() const override
StopInfoTrace(Thread &thread)
std::optional< uint32_t > GetSuggestedStackFrameIndex(bool inlined_stack) override
This gives the StopInfo a chance to suggest a stack frame to select.
StopInfoUnixSignal(Thread &thread, int signo, const char *description, std::optional< int > code)
void WillResume(lldb::StateType resume_state) override
bool DoShouldNotify(Event *event_ptr) override
~StopInfoUnixSignal() override=default
const char * GetDescription() override
std::optional< int > m_code
bool ShouldStopSynchronous(Event *event_ptr) override
uint32_t GetStopReasonDataCount() const override
bool ShouldStop(Event *event_ptr) override
StopReason GetStopReason() const override
uint64_t GetStopReasonDataAtIndex(uint32_t idx) override
bool ShouldSelect() const override
Returns true if this is a stop reason that should cause a thread to be selected when stopping.
const char * GetDescription() override
~StopInfoVForkDone() override=default
bool ShouldStop(Event *event_ptr) override
StopReason GetStopReason() const override
void PerformAction(Event *event_ptr) override
bool ShouldStop(Event *event_ptr) override
uint64_t GetStopReasonDataAtIndex(uint32_t idx) override
StopReason GetStopReason() const override
void PerformAction(Event *event_ptr) override
~StopInfoVFork() override=default
StopInfoVFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
const char * GetDescription() override
uint32_t GetStopReasonDataCount() const override
ThreadPlanStepOverWatchpoint(Thread &thread, StopInfoWatchpointSP stop_info_sp, WatchpointSP watch_sp)
Definition StopInfo.cpp:798
bool DoWillResume(lldb::StateType resume_state, bool current_plan) override
Definition StopInfo.cpp:807
WatchpointSentry(ProcessSP p_sp, WatchpointSP w_sp)
Definition StopInfo.cpp:725
static bool SentryPreResumeAction(void *sentry_void)
Definition StopInfo.cpp:754
~StopInfoWatchpoint() override=default
std::shared_ptr< StopInfoWatchpoint > StopInfoWatchpointSP
Definition StopInfo.cpp:789
StopInfoWatchpoint(Thread &thread, break_id_t watch_id, bool silently_skip_wp)
Definition StopInfo.cpp:765
uint32_t GetStopReasonDataCount() const override
Definition StopInfo.cpp:772
const char * GetDescription() override
Definition StopInfo.cpp:779
void PerformAction(Event *event_ptr) override
Definition StopInfo.cpp:977
bool ShouldStop(Event *event_ptr) override
Definition StopInfo.cpp:969
bool ShouldStopSynchronous(Event *event_ptr) override
Definition StopInfo.cpp:866
uint64_t GetStopReasonDataAtIndex(uint32_t idx) override
Definition StopInfo.cpp:773
StopReason GetStopReason() const override
Definition StopInfo.cpp:770
std::string m_description
Definition StopInfo.h:227
static lldb::StopInfoSP CreateStopReasonWithPlan(lldb::ThreadPlanSP &plan, lldb::ValueObjectSP return_valobj_sp, lldb::ExpressionVariableSP expression_variable_sp)
uint64_t GetValue() const
Definition StopInfo.h:46
static lldb::ExpressionVariableSP GetExpressionVariable(lldb::StopInfoSP &stop_info_sp)
static lldb::ValueObjectSP GetReturnValueObject(lldb::StopInfoSP &stop_info_sp)
static lldb::StopInfoSP CreateStopReasonToTrace(Thread &thread)
static lldb::StopInfoSP CreateStopReasonVFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
static lldb::StopInfoSP CreateStopReasonWithInterrupt(Thread &thread, int signo, const char *description)
bool IsValid() const
Definition StopInfo.cpp:42
StructuredData::ObjectSP m_extended_info
Definition StopInfo.h:232
static lldb::StopInfoSP CreateStopReasonWithSignal(Thread &thread, int signo, const char *description=nullptr, std::optional< int > code=std::nullopt)
lldb::ThreadSP GetThread() const
Definition StopInfo.h:35
static lldb::StopInfoSP CreateStopReasonFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
static lldb::StopInfoSP CreateStopReasonVForkDone(Thread &thread)
static lldb::StopInfoSP CreateStopReasonWithWatchpointID(Thread &thread, lldb::break_id_t watch_id, bool silently_continue=false)
virtual void SetDescription(const char *desc_cstr)
Definition StopInfo.h:74
static lldb::StopInfoSP CreateStopReasonWithException(Thread &thread, const char *description)
static lldb::StopInfoSP CreateStopReasonWithBreakpointSiteID(Thread &thread, lldb::break_id_t break_id)
static lldb::StopInfoSP CreateStopReasonHistoryBoundary(Thread &thread, const char *description)
static lldb::ValueObjectSP GetCrashingDereference(lldb::StopInfoSP &stop_info_sp, lldb::addr_t *crashing_address=nullptr)
LazyBool m_override_should_notify
Definition StopInfo.h:228
static lldb::StopInfoSP CreateStopReasonProcessorTrace(Thread &thread, const char *description)
static lldb::StopInfoSP CreateStopReasonWithExec(Thread &thread)
friend class Thread
Definition StopInfo.h:245
StopInfo(Thread &thread, uint64_t value)
Definition StopInfo.cpp:35
lldb::ThreadWP m_thread_wp
Definition StopInfo.h:222
LazyBool m_override_should_stop
Definition StopInfo.h:229
virtual bool ShouldStop(Event *event_ptr)
Definition StopInfo.h:219
General Outline: When we hit a breakpoint we need to package up whatever information is needed to eva...
lldb::break_id_t GetID() const
Definition Stoppoint.cpp:22
const char * GetData() const
llvm::StringRef GetString() const
void Format(const char *format, Args &&... args)
Forwards the arguments to llvm::formatv and writes to the stream.
Definition Stream.h:370
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
Debugger & GetDebugger() const
Definition Target.h:1323
bool DoPlanExplainsStop(Event *event_ptr) override
ThreadPlanStepInstruction(Thread &thread, bool step_over, bool stop_others, Vote report_stop_vote, Vote report_run_vote)
Thread & GetThread()
Returns the Thread that is using this thread plan.
virtual lldb::StopInfoSP GetPrivateStopInfo(bool calculate=true)
Definition Thread.cpp:401
void SetStopInfo(const lldb::StopInfoSP &stop_info_sp)
Definition Thread.cpp:479
lldb::ProcessSP GetProcess() const
Definition Thread.h:161
static lldb::ExpressionResults Evaluate(ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options, llvm::StringRef expr_cstr, llvm::StringRef expr_prefix, lldb::ValueObjectSP &result_valobj_sp, std::string *fixed_expression=nullptr, ValueObject *ctx_obj=nullptr)
Evaluate one expression in the scratch context of the target passed in the exe_ctx and return its res...
#define LLDB_INVALID_BREAK_ID
#define LLDB_INVALID_UID
#define LLDB_INVALID_ADDRESS
@ DoNoSelectMostRelevantFrame
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:327
std::shared_ptr< lldb_private::ThreadPlan > ThreadPlanSP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::BreakpointSite > BreakpointSiteSP
std::shared_ptr< lldb_private::BreakpointLocation > BreakpointLocationSP
@ eDescriptionLevelBrief
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::shared_ptr< lldb_private::ExpressionVariable > ExpressionVariableSP
std::shared_ptr< lldb_private::UnixSignals > UnixSignalsSP
StateType
Process and Thread States.
@ eStateStopped
Process or thread is stopped and can be examined.
@ eStateSuspended
Process or thread is in a suspended state as far as the debugger is concerned while other processes o...
@ eStateRunning
Process or thread is running and can't be examined.
std::shared_ptr< lldb_private::Breakpoint > BreakpointSP
ExpressionResults
The results of expression evaluation.
@ eExpressionCompleted
int32_t break_id_t
Definition lldb-types.h:87
std::shared_ptr< lldb_private::Process > ProcessSP
uint64_t pid_t
Definition lldb-types.h:83
std::shared_ptr< lldb_private::Watchpoint > WatchpointSP
std::shared_ptr< lldb_private::StopInfo > StopInfoSP
uint64_t addr_t
Definition lldb-types.h:80
StopReason
Thread stop reasons.
@ eStopReasonPlanComplete
@ eStopReasonHistoryBoundary
@ eStopReasonBreakpoint
@ eStopReasonExec
Program was re-exec'ed.
@ eStopReasonVForkDone
@ eStopReasonInterrupt
Thread requested interrupt.
@ eStopReasonProcessorTrace
@ eStopReasonException
@ eStopReasonWatchpoint
std::unique_ptr< lldb_private::Stream > StreamUP
uint64_t tid_t
Definition lldb-types.h:84
Describes what view of the process a thread should see and what operations it is allowed to perform.
Definition Policy.h:32
Capabilities capabilities
Definition Policy.h:55
static Policy PrivateState()
Definition Policy.h:59
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition UserID.h:47