//===-- StopInfo.cpp ------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <array>
#include <cstdint>
#include <string>

#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Breakpoint/WatchpointResource.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Expression/UserExpression.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/ThreadPlan.h"
#include "lldb/Target/ThreadPlanStepInstruction.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Policy.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/ValueObject/ValueObject.h"

using namespace lldb;
using namespace lldb_private;

StopInfo::StopInfo(Thread &thread, uint64_t value)
    : m_thread_wp(thread.shared_from_this()),
      m_stop_id(thread.GetProcess()->GetStopID()),
      m_resume_id(thread.GetProcess()->GetResumeID()), m_value(value),
      m_description(), m_override_should_notify(eLazyBoolCalculate),
      m_override_should_stop(eLazyBoolCalculate), m_extended_info() {}

bool StopInfo::IsValid() const {
  ThreadSP thread_sp(m_thread_wp.lock());
  if (thread_sp)
    return thread_sp->GetProcess()->GetStopID() == m_stop_id;
  return false;
}

void StopInfo::MakeStopInfoValid() {
  ThreadSP thread_sp(m_thread_wp.lock());
  if (thread_sp) {
    m_stop_id = thread_sp->GetProcess()->GetStopID();
    m_resume_id = thread_sp->GetProcess()->GetResumeID();
  }
}

bool StopInfo::HasTargetRunSinceMe() {
  ThreadSP thread_sp(m_thread_wp.lock());

  if (thread_sp) {
    lldb::StateType ret_type = thread_sp->GetProcess()->GetPrivateState();
    if (ret_type == eStateRunning) {
      return true;
    } else if (ret_type == eStateStopped) {
      // This is a little tricky.  We want to count "run and stopped again
      // before you could ask this question as a "TRUE" answer to
      // HasTargetRunSinceMe.  But we don't want to include any running of the
      // target done for expressions.  So we track both resumes, and resumes
      // caused by expressions, and check if there are any resumes
      // NOT caused
      // by expressions.

      uint32_t curr_resume_id = thread_sp->GetProcess()->GetResumeID();
      uint32_t last_user_expression_id =
          thread_sp->GetProcess()->GetLastUserExpressionResumeID();
      if (curr_resume_id == m_resume_id) {
        return false;
      } else if (curr_resume_id > last_user_expression_id) {
        return true;
      }
    }
  }
  return false;
}

void StopInfo::SkipOverTrapInstruction() {
  Status error;
  Log *log = GetLog(LLDBLog::Process);

  // We don't expect to see byte sequences longer than four bytes long for
  // any breakpoint instructions known to LLDB.
  std::array<uint8_t, 4> bytes_at_pc = {0, 0, 0, 0};
  auto reg_ctx_sp = GetThread()->GetRegisterContext();
  auto process_sp = GetThread()->GetProcess();
  addr_t pc = reg_ctx_sp->GetPC();
  if (!process_sp->ReadMemory(pc, bytes_at_pc.data(), bytes_at_pc.size(),
                              error)) {
    // If this fails, we simply don't handle the step-over-break logic.
    LLDB_LOG(log, "failed to read program bytes at pc address {}, error {}", pc,
             error);
    return;
  }

  auto &target = process_sp->GetTarget();
  auto platform_sp = target.GetPlatform();
  size_t size_hint =
      platform_sp->GetTrapOpcodeSizeHint(target, Address(pc), bytes_at_pc);
  llvm::ArrayRef<uint8_t> platform_opcode =
      platform_sp->SoftwareTrapOpcodeBytes(target.GetArchitecture(), size_hint);

  Architecture *arch_plugin = target.GetArchitecturePlugin();
  llvm::ArrayRef<uint8_t> inst_bytes(bytes_at_pc.data(), bytes_at_pc.size());
  if (arch_plugin &&
      arch_plugin->IsValidTrapInstruction(platform_opcode, inst_bytes)) {
    LLDB_LOG(log, "stepping over breakpoint in inferior to new pc: {}",
             pc + platform_opcode.size());
    reg_ctx_sp->SetPC(pc + platform_opcode.size());
  }
}

// StopInfoBreakpoint

namespace lldb_private {
class StopInfoBreakpoint : public StopInfo {
public:
  // We use a "breakpoint preserving BreakpointLocationCollection because we
  // may need to hand out the "breakpoint hit" list as any point, potentially
  // after the breakpoint has been deleted.  But we still need to refer to them.
  StopInfoBreakpoint(Thread &thread, break_id_t break_id)
      : StopInfo(thread, break_id), m_should_stop(false),
        m_should_stop_is_valid(false), m_should_perform_action(true),
        m_address(LLDB_INVALID_ADDRESS), m_break_id(LLDB_INVALID_BREAK_ID),
        m_was_all_internal(false), m_was_one_shot(false),
        m_async_stopped_locs(true) {
    StoreBPInfo();
  }

  StopInfoBreakpoint(Thread &thread, break_id_t break_id, bool should_stop)
      : StopInfo(thread, break_id), m_should_stop(should_stop),
        m_should_stop_is_valid(true), m_should_perform_action(true),
        m_address(LLDB_INVALID_ADDRESS), m_break_id(LLDB_INVALID_BREAK_ID),
        m_was_all_internal(false), m_was_one_shot(false),
        m_async_stopped_locs(true) {
    StoreBPInfo();
  }

  ~StopInfoBreakpoint() override = default;

  void StoreBPInfo() {
    ThreadSP thread_sp(m_thread_wp.lock());
    if (thread_sp) {
      BreakpointSiteSP bp_site_sp = GetBreakpointSiteSP();
      if (bp_site_sp) {
        uint32_t num_constituents = bp_site_sp->GetNumberOfConstituents();
        if (num_constituents == 1) {
          BreakpointLocationSP bp_loc_sp = bp_site_sp->GetConstituentAtIndex(0);
          if (bp_loc_sp) {
            Breakpoint & bkpt = bp_loc_sp->GetBreakpoint();
            m_break_id = bkpt.GetID();
            m_was_one_shot = bkpt.IsOneShot();
            m_was_all_internal = bkpt.IsInternal();
          }
        } else {
          m_was_all_internal = true;
          for (uint32_t i = 0; i < num_constituents; i++) {
            if (!bp_site_sp->GetConstituentAtIndex(i)
                     ->GetBreakpoint()
                     .IsInternal()) {
              m_was_all_internal = false;
              break;
            }
          }
        }
        m_address = bp_site_sp->GetLoadAddress();
      }
    }
  }

  bool IsValidForOperatingSystemThread(Thread &thread) override {
    ProcessSP process_sp(thread.GetProcess());
    if (process_sp) {
      BreakpointSiteSP bp_site_sp = GetBreakpointSiteSP();
      if (bp_site_sp)
        return bp_site_sp->ValidForThisThread(thread);
    }
    return false;
  }

  StopReason GetStopReason() const override { return eStopReasonBreakpoint; }

  bool ShouldStopSynchronous(Event *event_ptr) override {
    // Breakpoint callbacks run on the PST during stop processing. Push
    // private state context so callback code sees the private reality.
    PolicyStack::Guard policy_guard = PolicyStack::Get().PushPrivateState();

    ThreadSP thread_sp(m_thread_wp.lock());
    if (thread_sp) {
      if (!m_should_stop_is_valid) {
        // Only check once if we should stop at a breakpoint
        BreakpointSiteSP bp_site_sp = GetBreakpointSiteSP();
        if (bp_site_sp) {
          ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0));
          StoppointCallbackContext context(event_ptr, exe_ctx, true);
          bp_site_sp->BumpHitCounts();
          m_should_stop =
              bp_site_sp->ShouldStop(&context, m_async_stopped_locs);
        } else {
          Log *log = GetLog(LLDBLog::Process);

          LLDB_LOGF(log,
                    "Process::%s could not find breakpoint site id: %" PRId64
                    "...",
                    __FUNCTION__, m_value);

          m_should_stop = true;
        }
        m_should_stop_is_valid = true;
      }
      return m_should_stop;
    }
    return false;
  }

  bool DoShouldNotify(Event *event_ptr) override {
    return !m_was_all_internal;
  }

  const char *GetDescription() override {
    // FIXME: only print m_async_stopped_locs.
    if (m_description.empty()) {
      ThreadSP thread_sp(m_thread_wp.lock());
      if (thread_sp) {
        BreakpointSiteSP bp_site_sp = GetBreakpointSiteSP();
        if (bp_site_sp) {
          StreamString strm;
          // If we have just hit an internal breakpoint, and it has a kind
          // description, print that instead of the full breakpoint printing:
          if (bp_site_sp->IsInternal()) {
            size_t num_constituents = bp_site_sp->GetNumberOfConstituents();
            for (size_t idx = 0; idx < num_constituents; idx++) {
              const char *kind = bp_site_sp->GetConstituentAtIndex(idx)
                                     ->GetBreakpoint()
                                     .GetBreakpointKind();
              if (kind != nullptr) {
                m_description.assign(kind);
                return kind;
              }
            }
          }

          strm.PutCString("breakpoint ");
          m_async_stopped_locs.GetDescription(&strm, eDescriptionLevelBrief);
          m_description = std::string(strm.GetString());
        } else {
          StreamString strm;
          if (m_break_id != LLDB_INVALID_BREAK_ID) {
            BreakpointSP break_sp =
                thread_sp->GetProcess()->GetTarget().GetBreakpointByID(
                    m_break_id);
            if (break_sp) {
              if (break_sp->IsInternal()) {
                const char *kind = break_sp->GetBreakpointKind();
                if (kind)
                  strm.Printf("internal %s breakpoint(%d).", kind, m_break_id);
                else
                  strm.Printf("internal breakpoint(%d).", m_break_id);
              } else {
                strm.Printf("breakpoint %d.", m_break_id);
              }
            } else {
              if (m_was_one_shot)
                strm.Printf("one-shot breakpoint %d", m_break_id);
              else
                strm.Printf("breakpoint %d which has been deleted.",
                            m_break_id);
            }
          } else if (m_address == LLDB_INVALID_ADDRESS)
            strm.Printf("breakpoint site %" PRIi64
                        " which has been deleted - unknown address",
                        m_value);
          else
            strm.Printf("breakpoint site %" PRIi64
                        " which has been deleted - was at 0x%" PRIx64,
                        m_value, m_address);

          m_description = std::string(strm.GetString());
        }
      }
    }
    return m_description.c_str();
  }

  uint32_t GetStopReasonDataCount() const override {
    size_t num_async_locs = m_async_stopped_locs.GetSize();
    // If we have async locations, they are the ones we should report:
    if (num_async_locs > 0)
      return num_async_locs * 2;

    // Otherwise report the number of locations at this breakpoint's site.
    lldb::BreakpointSiteSP bp_site_sp = GetBreakpointSiteSP();
    if (bp_site_sp)
      return bp_site_sp->GetNumberOfConstituents() * 2;
    return 0; // Breakpoint must have cleared itself...
  }

  uint64_t GetStopReasonDataAtIndex(uint32_t idx) override {
    uint32_t bp_index = idx / 2;
    BreakpointLocationSP loc_to_report_sp;

    size_t num_async_locs = m_async_stopped_locs.GetSize();
    if (num_async_locs > 0) {
      // GetByIndex returns an empty SP if we ask past its contents:
      loc_to_report_sp = m_async_stopped_locs.GetByIndex(bp_index);
    } else {
      lldb::BreakpointSiteSP bp_site_sp = GetBreakpointSiteSP();
      if (bp_site_sp)
        loc_to_report_sp = bp_site_sp->GetConstituentAtIndex(bp_index);
    }
    if (loc_to_report_sp) {
      if (idx & 1) {
        // Odd idx, return the breakpoint location ID
        return loc_to_report_sp->GetID();
      } else {
        // Even idx, return the breakpoint ID
        return loc_to_report_sp->GetBreakpoint().GetID();
      }
    }
    return LLDB_INVALID_BREAK_ID;
  }

  std::optional<uint32_t>
  GetSuggestedStackFrameIndex(bool inlined_stack) override {
    if (!inlined_stack)
      return {};

    ThreadSP thread_sp(m_thread_wp.lock());
    if (!thread_sp)
      return {};
    BreakpointSiteSP bp_site_sp = GetBreakpointSiteSP();
    if (!bp_site_sp)
      return {};

    return bp_site_sp->GetSuggestedStackFrameIndex();
  }

  bool ShouldShow() const override { return !m_was_all_internal; }

  bool ShouldSelect() const override { return !m_was_all_internal; }

protected:
  bool ShouldStop(Event *event_ptr) override {
    // This just reports the work done by PerformAction or the synchronous
    // stop. It should only ever get called after they have had a chance to
    // run.
    assert(m_should_stop_is_valid);
    return m_should_stop;
  }

  void PerformAction(Event *event_ptr) override {
    if (!m_should_perform_action)
      return;
    m_should_perform_action = false;
    bool all_stopping_locs_internal = true;

    ThreadSP thread_sp(m_thread_wp.lock());

    if (thread_sp) {
      Log *log = GetLog(LLDBLog::Breakpoints | LLDBLog::Step);

      if (!thread_sp->IsValid()) {
        // This shouldn't ever happen, but just in case, don't do more harm.
        LLDB_LOGF(log, "PerformAction got called with an invalid thread.");
        m_should_stop = true;
        m_should_stop_is_valid = true;
        return;
      }

      BreakpointSiteSP bp_site_sp = GetBreakpointSiteSP();
      std::unordered_set<break_id_t> precondition_breakpoints;
      // Breakpoints that fail their condition check are not considered to
      // have been hit.  If the only locations at this site have failed their
      // conditions, we should change the stop-info to none.  Otherwise, if we
      // hit another breakpoint on a different thread which does stop, users
      // will see a breakpont hit with a failed condition, which is wrong.
      // Use this variable to tell us if that is true.
      bool actually_hit_any_locations = false;
      if (bp_site_sp) {
        // Let's copy the constituents list out of the site and store them in a
        // local list.  That way if one of the breakpoint actions changes the
        // site, then we won't be operating on a bad list.
        BreakpointLocationCollection site_locations;
        size_t num_constituents = m_async_stopped_locs.GetSize();

        if (num_constituents == 0) {
          m_should_stop = true;
          actually_hit_any_locations = true;  // We're going to stop, don't 
                                              // change the stop info.
        } else {
          // We go through each location, and test first its precondition -
          // this overrides everything.  Note, we only do this once per
          // breakpoint - not once per location... Then check the condition.
          // If the condition says to stop, then we run the callback for that
          // location.  If that callback says to stop as well, then we set
          // m_should_stop to true; we are going to stop. But we still want to
          // give all the breakpoints whose conditions say we are going to stop
          // a chance to run their callbacks. Of course if any callback
          // restarts the target by putting "continue" in the callback, then
          // we're going to restart, without running the rest of the callbacks.
          // And in this case we will end up not stopping even if another
          // location said we should stop. But that's better than not running
          // all the callbacks.

          // There's one other complication here.  We may have run an async
          // breakpoint callback that said we should stop.  We only want to
          // override that if another breakpoint action says we shouldn't
          // stop.  If nobody else has an opinion, then we should stop if the
          // async callback says we should.  An example of this is the async
          // shared library load notification breakpoint and the setting
          // stop-on-sharedlibrary-events.
          // We'll keep the async value in async_should_stop, and track whether
          // anyone said we should NOT stop in actually_said_continue.
          bool async_should_stop = false;
          if (m_should_stop_is_valid)
            async_should_stop = m_should_stop;
          bool actually_said_continue = false;

          m_should_stop = false;

          // We don't select threads as we go through them testing breakpoint
          // conditions and running commands. So we need to set the thread for
          // expression evaluation here:
          ThreadList::ExpressionExecutionThreadPusher thread_pusher(thread_sp);

          ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0));
          Process *process = exe_ctx.GetProcessPtr();
          Policy policy = PolicyStack::Get().Current();
          if (!policy.capabilities.can_run_breakpoint_actions) {
            // If we are in the middle of evaluating an expression, don't run
            // asynchronous breakpoint commands or expressions.  That could
            // lead to infinite recursion if the command or condition re-calls
            // the function with this breakpoint.
            // TODO: We can keep a list of the breakpoints we've seen while
            // running expressions in the nested
            // PerformAction calls that can arise when the action runs a
            // function that hits another breakpoint, and only stop running
            // commands when we see the same breakpoint hit a second time.

            m_should_stop_is_valid = true;

            // It is possible that the user has a breakpoint at the same site
            // as the completed plan had (e.g. user has a breakpoint
            // on a module entry point, and `ThreadPlanCallFunction` ends
            // also there). We can't find an internal breakpoint in the loop
            // later because it was already removed on the plan completion.
            // So check if the plan was completed, and stop if so.
            if (thread_sp->CompletedPlanOverridesBreakpoint()) {
              m_should_stop = true;
              thread_sp->ResetStopInfo();
              return;
            }

            LLDB_LOGF(log, "StopInfoBreakpoint::PerformAction - Hit a "
                           "breakpoint while running an expression,"
                           " not running commands to avoid recursion.");
            bool ignoring_breakpoints =
                process->GetIgnoreBreakpointsInExpressions();
            // Internal breakpoints should be allowed to do their job, we
            // can make sure they don't do anything that would cause recursive
            // command execution:
            if (!m_was_all_internal) {
              m_should_stop = !ignoring_breakpoints;
              LLDB_LOGF(log,
                        "StopInfoBreakpoint::PerformAction - in expression, "
                        "continuing: %s.",
                        m_should_stop ? "true" : "false");
              Debugger::ReportWarning(
                  "hit breakpoint while running function, skipping commands "
                  "and conditions to prevent recursion",
                    process->GetTarget().GetDebugger().GetID());
              return;
            }
          }

          StoppointCallbackContext context(event_ptr, exe_ctx, false);

          // For safety's sake let's also grab an extra reference to the
          // breakpoint constituents of the locations we're going to examine,
          // since the locations are going to have to get back to their
          // breakpoints, and the locations don't keep their constituents alive.
          // I'm just sticking the BreakpointSP's in a vector since I'm only
          // using it to locally increment their retain counts.

          // We are holding onto the breakpoint locations that were hit
          // by this stop info between the "synchonous" ShouldStop and now.
          // But an intervening action might have deleted one of the breakpoints
          // we hit before we get here.  So at the same time let's build a list
          // of the still valid locations:
          std::vector<lldb::BreakpointSP> location_constituents;

          BreakpointLocationCollection valid_locs;
          for (size_t j = 0; j < num_constituents; j++) {
            BreakpointLocationSP loc_sp(m_async_stopped_locs.GetByIndex(j));
            if (loc_sp->IsValid()) {
              location_constituents.push_back(
                  loc_sp->GetBreakpoint().shared_from_this());
              valid_locs.Add(loc_sp);
            }
          }

          size_t num_valid_locs = valid_locs.GetSize();
          for (size_t j = 0; j < num_valid_locs; j++) {
            lldb::BreakpointLocationSP bp_loc_sp = valid_locs.GetByIndex(j);
            StreamString loc_desc;
            if (log) {
              bp_loc_sp->GetDescription(&loc_desc, eDescriptionLevelBrief);
            }
            // If another action disabled this breakpoint or its location, then
            // don't run the actions.
            if (!bp_loc_sp->IsEnabled() ||
                !bp_loc_sp->GetBreakpoint().IsEnabled())
              continue;

            // The breakpoint site may have many locations associated with it,
            // not all of them valid for this thread.  Skip the ones that
            // aren't:
            if (!bp_loc_sp->ValidForThisThread(*thread_sp)) {
              LLDB_LOGF(log,
                        "Breakpoint %s hit on thread 0x%llx but it was not "
                        "for this thread, continuing.",
                        loc_desc.GetData(),
                        static_cast<unsigned long long>(thread_sp->GetID()));
              continue;
            }

            // First run the precondition, but since the precondition is per
            // breakpoint, only run it once per breakpoint.
            std::pair<std::unordered_set<break_id_t>::iterator, bool> result =
                precondition_breakpoints.insert(
                    bp_loc_sp->GetBreakpoint().GetID());
            if (!result.second)
              continue;

            bool precondition_result =
                bp_loc_sp->GetBreakpoint().EvaluatePrecondition(context);
            if (!precondition_result) {
              actually_said_continue = true;
              continue;
            }
            // Next run the condition for the breakpoint.  If that says we
            // should stop, then we'll run the callback for the breakpoint.  If
            // the callback says we shouldn't stop that will win.

            if (!bp_loc_sp->GetCondition())
              actually_hit_any_locations = true;
            else {
              Status condition_error;
              bool condition_says_stop =
                  bp_loc_sp->ConditionSaysStop(exe_ctx, condition_error);

              if (!condition_error.Success()) {
                // If the condition fails to evaluate, we are going to stop 
                // at it, so the location was hit.
                actually_hit_any_locations = true;
                const char *err_str =
                    condition_error.AsCString("<unknown error>");
                LLDB_LOGF(log, "Error evaluating condition: \"%s\"\n", err_str);

                StreamString strm;
                strm << "stopped due to an error evaluating condition of "
                        "breakpoint ";
                bp_loc_sp->GetDescription(&strm, eDescriptionLevelBrief);
                strm << ": \"" << bp_loc_sp->GetCondition().GetText() << "\"\n";
                strm << err_str;

                Debugger::ReportError(
                    strm.GetString().str(),
                    exe_ctx.GetTargetRef().GetDebugger().GetID());
              } else {
                LLDB_LOGF(log,
                          "Condition evaluated for breakpoint %s on thread "
                          "0x%llx condition_says_stop: %i.",
                          loc_desc.GetData(),
                          static_cast<unsigned long long>(thread_sp->GetID()),
                          condition_says_stop);
                if (condition_says_stop) 
                  actually_hit_any_locations = true;
                else {
                  // We don't want to increment the hit count of breakpoints if
                  // the condition fails. We've already bumped it by the time
                  // we get here, so undo the bump:
                  bp_loc_sp->UndoBumpHitCount();
                  actually_said_continue = true;
                  continue;
                }
              }
            }

            // We've done all the checks whose failure means "we consider lldb
            // not to have hit the breakpoint".  Now we're going to check for
            // conditions that might continue after hitting.  Start with the
            // ignore count:
            if (!bp_loc_sp->IgnoreCountShouldStop()) {
              actually_said_continue = true;
              continue;
            }

            // Check the auto-continue bit on the location, do this before the
            // callback since it may change this, but that would be for the
            // NEXT hit.  Note, you might think you could check auto-continue
            // before the condition, and not evaluate the condition if it says
            // to continue.  But failing the condition means the breakpoint was
            // effectively NOT HIT.  So these two states are different.
            bool auto_continue_says_stop = true;
            if (bp_loc_sp->IsAutoContinue())
            {
              LLDB_LOGF(log,
                        "Continuing breakpoint %s as AutoContinue was set.",
                        loc_desc.GetData());
              // We want this stop reported, so you will know we auto-continued
              // but only for external breakpoints:
              if (!bp_loc_sp->GetBreakpoint().IsInternal())
                thread_sp->SetShouldReportStop(eVoteYes);
              auto_continue_says_stop = false;
            }

            bool callback_says_stop = true;

            // FIXME: For now the callbacks have to run in async mode - the
            // first time we restart we need
            // to get out of there.  So set it here.
            // When we figure out how to nest breakpoint hits then this will
            // change.

            // Don't run async callbacks in PerformAction.  They have already
            // been taken into account with async_should_stop.
            if (!bp_loc_sp->IsCallbackSynchronous()) {
              Debugger &debugger = thread_sp->CalculateTarget()->GetDebugger();
              bool old_async = debugger.GetAsyncExecution();
              debugger.SetAsyncExecution(true);

              callback_says_stop = bp_loc_sp->InvokeCallback(&context);

              debugger.SetAsyncExecution(old_async);

              if (callback_says_stop && auto_continue_says_stop)
                m_should_stop = true;
              else
                actually_said_continue = true;
            }

            if (m_should_stop && !bp_loc_sp->GetBreakpoint().IsInternal())
              all_stopping_locs_internal = false;

            // If we are going to stop for this breakpoint, then remove the
            // breakpoint.
            if (callback_says_stop && bp_loc_sp &&
                bp_loc_sp->GetBreakpoint().IsOneShot()) {
              thread_sp->GetProcess()->GetTarget().RemoveBreakpointByID(
                  bp_loc_sp->GetBreakpoint().GetID());
            }
            // Also make sure that the callback hasn't continued the target. If
            // it did, when we'll set m_should_start to false and get out of
            // here.
            if (HasTargetRunSinceMe()) {
              m_should_stop = false;
              actually_said_continue = true;
              break;
            }
          }
          // At this point if nobody actually told us to continue, we should
          // give the async breakpoint callback a chance to weigh in:
          if (!actually_said_continue && !m_should_stop) {
            m_should_stop = async_should_stop;
          }
        }
        // We've figured out what this stop wants to do, so mark it as valid so
        // we don't compute it again.
        m_should_stop_is_valid = true;
      } else {
        m_should_stop = true;
        m_should_stop_is_valid = true;
        actually_hit_any_locations = true;
        Log *log_process(GetLog(LLDBLog::Process));

        LLDB_LOGF(log_process,
                  "Process::%s could not find breakpoint site id: %" PRId64
                  "...",
                  __FUNCTION__, m_value);
      }

      if ((!m_should_stop || all_stopping_locs_internal) &&
          thread_sp->CompletedPlanOverridesBreakpoint()) {

        // Override should_stop decision when we have completed step plan
        // additionally to the breakpoint
        m_should_stop = true;

        // We know we're stopping for a completed plan and we don't want to
        // show the breakpoint stop, so compute the public stop info immediately
        // here.
        thread_sp->CalculatePublicStopInfo();
      } else if (!actually_hit_any_locations) {
        // In the end, we didn't actually have any locations that passed their
        // "was I hit" checks.  So say we aren't stopped.
        GetThread()->ResetStopInfo();
        LLDB_LOGF(log, "Process::%s all locations failed condition checks.",
          __FUNCTION__);
      }

      LLDB_LOGF(log,
                "Process::%s returning from action with m_should_stop: %d.",
                __FUNCTION__, m_should_stop);
    }
  }

private:
  BreakpointSiteSP GetBreakpointSiteSP() const {
    if (m_value == LLDB_INVALID_BREAK_ID)
      return {};

    ThreadSP thread_sp = GetThread();
    if (!thread_sp)
      return {};
    ProcessSP process_sp = thread_sp->GetProcess();
    if (!process_sp)
      return {};

    return process_sp->GetBreakpointSiteList().FindByID(m_value);
  }

  bool m_should_stop;
  bool m_should_stop_is_valid;
  bool m_should_perform_action; // Since we are trying to preserve the "state"
                                // of the system even if we run functions
  // etc. behind the users backs, we need to make sure we only REALLY perform
  // the action once.
  lldb::addr_t m_address; // We use this to capture the breakpoint site address
                          // when we create the StopInfo,
  // in case somebody deletes it between the time the StopInfo is made and the
  // description is asked for.
  lldb::break_id_t m_break_id;
  bool m_was_all_internal;
  bool m_was_one_shot;
  /// The StopInfoBreakpoint lives after the stop, and could get queried
  /// at any time so we need to make sure that it keeps the breakpoints for
  /// each of the locations it records alive while it is around.  That's what
  /// The BreakpointPreservingLocationCollection does.
  BreakpointLocationCollection m_async_stopped_locs;
};

// StopInfoWatchpoint

class StopInfoWatchpoint : public StopInfo {
public:
  // Make sure watchpoint is properly disabled and subsequently enabled while
  // performing watchpoint actions.
  class WatchpointSentry {
  public:
    WatchpointSentry(ProcessSP p_sp, WatchpointSP w_sp) : process_sp(p_sp),
                     watchpoint_sp(w_sp) {
      if (process_sp && watchpoint_sp) {
        const bool notify = false;
        watchpoint_sp->TurnOnEphemeralMode();
        process_sp->DisableWatchpoint(watchpoint_sp, notify);
        process_sp->AddPreResumeAction(SentryPreResumeAction, this);
      }
    }

    void DoReenable() {
      if (process_sp && watchpoint_sp) {
        bool was_disabled = watchpoint_sp->IsDisabledDuringEphemeralMode();
        watchpoint_sp->TurnOffEphemeralMode();
        const bool notify = false;
        if (was_disabled) {
          process_sp->DisableWatchpoint(watchpoint_sp, notify);
        } else {
          process_sp->EnableWatchpoint(watchpoint_sp, notify);
        }
      }
    }

    ~WatchpointSentry() {
        DoReenable();
        if (process_sp)
            process_sp->ClearPreResumeAction(SentryPreResumeAction, this);
    }

    static bool SentryPreResumeAction(void *sentry_void) {
        WatchpointSentry *sentry = (WatchpointSentry *) sentry_void;
        sentry->DoReenable();
        return true;
    }

  private:
    ProcessSP process_sp;
    WatchpointSP watchpoint_sp;
  };

  StopInfoWatchpoint(Thread &thread, break_id_t watch_id, bool silently_skip_wp)
      : StopInfo(thread, watch_id), m_silently_skip_wp(silently_skip_wp) {}

  ~StopInfoWatchpoint() override = default;

  StopReason GetStopReason() const override { return eStopReasonWatchpoint; }

  uint32_t GetStopReasonDataCount() const override { return 1; }
  uint64_t GetStopReasonDataAtIndex(uint32_t idx) override {
    if (idx == 0)
      return GetValue();
    return 0;
  }

  const char *GetDescription() override {
    if (m_description.empty()) {
      StreamString strm;
      strm.Printf("watchpoint %" PRIi64, m_value);
      m_description = std::string(strm.GetString());
    }
    return m_description.c_str();
  }

protected:
  using StopInfoWatchpointSP = std::shared_ptr<StopInfoWatchpoint>;
  // This plan is used to orchestrate stepping over the watchpoint for
  // architectures (e.g. ARM) that report the watch before running the watched
  // access.  This is the sort of job you have to defer to the thread plans,
  // if you try to do it directly in the stop info and there are other threads
  // that needed to process this stop you will have yanked control away from
  // them and they won't behave correctly.
  class ThreadPlanStepOverWatchpoint : public ThreadPlanStepInstruction {
  public:
    ThreadPlanStepOverWatchpoint(Thread &thread, 
                                 StopInfoWatchpointSP stop_info_sp,
                                 WatchpointSP watch_sp)
        : ThreadPlanStepInstruction(thread, false, true, eVoteNoOpinion,
                                    eVoteNoOpinion),
          m_stop_info_sp(stop_info_sp), m_watch_sp(watch_sp) {
      assert(watch_sp);
    }

    bool DoWillResume(lldb::StateType resume_state,
                      bool current_plan) override {
      if (resume_state == eStateSuspended)
        return true;

      if (!m_did_disable_wp) {
        GetThread().GetProcess()->DisableWatchpoint(m_watch_sp, false);
        m_did_disable_wp = true;
      }
      return true;
    }
    
    bool DoPlanExplainsStop(Event *event_ptr) override {
      if (ThreadPlanStepInstruction::DoPlanExplainsStop(event_ptr))
        return true;
      StopInfoSP stop_info_sp = GetThread().GetPrivateStopInfo();
      // lldb-server resets the stop info for threads that didn't get to run,
      // so we might have not gotten to run, but still have a watchpoint stop
      // reason, in which case this will indeed be for us.
      if (stop_info_sp 
          && stop_info_sp->GetStopReason() == eStopReasonWatchpoint)
        return true;
      return false;
    }

    void DidPop() override {
      // Don't artifically keep the watchpoint alive.
      m_watch_sp.reset();
    }
    
    bool ShouldStop(Event *event_ptr) override {
      bool should_stop = ThreadPlanStepInstruction::ShouldStop(event_ptr);
      bool plan_done = MischiefManaged();
      if (plan_done) {
        m_stop_info_sp->SetStepOverPlanComplete();
        GetThread().SetStopInfo(m_stop_info_sp);
        ResetWatchpoint();
      }
      return should_stop;
    }
    
    bool ShouldRunBeforePublicStop() override {
        return true;
    }

  protected:
    void ResetWatchpoint() {
      if (!m_did_disable_wp)
        return;
      m_did_disable_wp = true;
      GetThread().GetProcess()->EnableWatchpoint(m_watch_sp, true);
    }

  private:
    StopInfoWatchpointSP m_stop_info_sp;
    WatchpointSP m_watch_sp;
    bool m_did_disable_wp = false;
  };

  bool ShouldStopSynchronous(Event *event_ptr) override {
    // Watchpoint callbacks run on the PST during stop processing. Push
    // private state context so callback code sees the private reality.
    PolicyStack::Guard policy_guard = PolicyStack::Get().PushPrivateState();

    // If we are running our step-over the watchpoint plan, stop if it's done
    // and continue if it's not:
    if (m_should_stop_is_valid)
      return m_should_stop;

    // If we are running our step over plan, then stop here and let the regular
    // ShouldStop figure out what we should do:  Otherwise, give our plan
    // more time to get run:
    if (m_using_step_over_plan)
      return m_step_over_plan_complete;

    Log *log = GetLog(LLDBLog::Process);
    ThreadSP thread_sp(m_thread_wp.lock());
    assert(thread_sp);
    
    if (thread_sp->GetTemporaryResumeState() == eStateSuspended) {
      // This is the second firing of a watchpoint so don't process it again.
      LLDB_LOG(log, "We didn't run but stopped with a StopInfoWatchpoint, we "
               "have already handled this one, don't do it again.");
      m_should_stop = false;
      m_should_stop_is_valid = true;
      return m_should_stop;
    }
    
    WatchpointSP wp_sp(
        thread_sp->CalculateTarget()->GetWatchpointList().FindByID(GetValue()));
    // If we can no longer find the watchpoint, we just have to stop:
    if (!wp_sp) {

      LLDB_LOGF(log,
                "Process::%s could not find watchpoint location id: %" PRId64
                "...",
                __FUNCTION__, GetValue());

      m_should_stop = true;
      m_should_stop_is_valid = true;
      return true;
    }

    ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0));
    StoppointCallbackContext context(event_ptr, exe_ctx, true);
    m_should_stop = wp_sp->ShouldStop(&context);
    if (!m_should_stop) {
      // This won't happen at present because we only allow one watchpoint per
      // watched range.  So we won't stop at a watched address with a disabled
      // watchpoint.  If we start allowing overlapping watchpoints, then we
      // will have to make watchpoints be real "WatchpointSite" and delegate to
      // all the watchpoints sharing the site.  In that case, the code below
      // would be the right thing to do.
      m_should_stop_is_valid = true;
      return m_should_stop;
    }
    // If this is a system where we need to execute the watchpoint by hand
    // after the hit, queue a thread plan to do that, and then say not to stop.
    // Otherwise, let the async action figure out whether the watchpoint should
    // stop

    ProcessSP process_sp = exe_ctx.GetProcessSP();
    bool wp_triggers_after = process_sp->GetWatchpointReportedAfter();

    if (!wp_triggers_after) {
      // We have to step over the watchpoint before we know what to do:   
      StopInfoWatchpointSP me_as_siwp_sp 
          = std::static_pointer_cast<StopInfoWatchpoint>(shared_from_this());
      ThreadPlanSP step_over_wp_sp =
          std::make_shared<ThreadPlanStepOverWatchpoint>(*(thread_sp.get()),
                                                         me_as_siwp_sp, wp_sp);
      // When this plan is done we want to stop, so set this as a Controlling
      // plan.    
      step_over_wp_sp->SetIsControllingPlan(true);
      step_over_wp_sp->SetOkayToDiscard(false);

      Status error;
      error = thread_sp->QueueThreadPlan(step_over_wp_sp, false);
      // If we couldn't push the thread plan, just stop here:
      if (!error.Success()) {
        LLDB_LOGF(log, "Could not push our step over watchpoint plan: %s", 
            error.AsCString());

        m_should_stop = true;
        m_should_stop_is_valid = true;
        return true;
      } else {
      // Otherwise, don't set m_should_stop, we don't know that yet.  Just 
      // say we should continue, and tell the thread we really should do so:
        thread_sp->SetShouldRunBeforePublicStop(true);
        m_using_step_over_plan = true;
        return false;
      }
    } else {
      // We didn't have to do anything special
      m_should_stop_is_valid = true;
      return m_should_stop;
    }
    
    return m_should_stop;
  }

  bool ShouldStop(Event *event_ptr) override {
    // This just reports the work done by PerformAction or the synchronous
    // stop. It should only ever get called after they have had a chance to
    // run.
    assert(m_should_stop_is_valid);
    return m_should_stop;
  }

  void PerformAction(Event *event_ptr) override {
    Log *log = GetLog(LLDBLog::Watchpoints);

    Policy policy = PolicyStack::Get().Current();
    if (!policy.capabilities.can_run_breakpoint_actions) {
      m_should_stop = false;
      m_should_stop_is_valid = true;
      LLDB_LOGF(log, "StopInfoWatchpoint::PerformAction - Hit a "
                     "watchpoint while running an expression,"
                     " not running commands to avoid recursion.");
      return;
    }

    // We're going to calculate if we should stop or not in some way during the
    // course of this code.  Also by default we're going to stop, so set that
    // here.
    m_should_stop = true;


    ThreadSP thread_sp(m_thread_wp.lock());
    if (thread_sp) {

      WatchpointSP wp_sp(
          thread_sp->CalculateTarget()->GetWatchpointList().FindByID(
              GetValue()));
      if (wp_sp) {
        // This sentry object makes sure the current watchpoint is disabled
        // while performing watchpoint actions, and it is then enabled after we
        // are finished.
        ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0));
        ProcessSP process_sp = exe_ctx.GetProcessSP();

        WatchpointSentry sentry(process_sp, wp_sp);

        if (m_silently_skip_wp) {
          m_should_stop = false;
          wp_sp->UndoHitCount();
        }

        if (wp_sp->GetHitCount() <= wp_sp->GetIgnoreCount()) {
          m_should_stop = false;
          m_should_stop_is_valid = true;
        }

        Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();

        if (m_should_stop && wp_sp->GetConditionText() != nullptr) {
          // We need to make sure the user sees any parse errors in their
          // condition, so we'll hook the constructor errors up to the
          // debugger's Async I/O.
          ExpressionResults result_code;
          EvaluateExpressionOptions expr_options;
          expr_options.SetUnwindOnError(true);
          expr_options.SetIgnoreBreakpoints(true);
          ValueObjectSP result_value_sp;
          result_code = UserExpression::Evaluate(
              exe_ctx, expr_options, wp_sp->GetConditionText(),
              llvm::StringRef(), result_value_sp);

          if (result_code == eExpressionCompleted) {
            if (result_value_sp) {
              Scalar scalar_value;
              if (result_value_sp->ResolveValue(scalar_value)) {
                if (scalar_value.ULongLong(1) == 0) {
                  // The condition failed, which we consider "not having hit
                  // the watchpoint" so undo the hit count here.
                  wp_sp->UndoHitCount();
                  m_should_stop = false;
                } else
                  m_should_stop = true;
                LLDB_LOGF(log,
                          "Condition successfully evaluated, result is %s.\n",
                          m_should_stop ? "true" : "false");
              } else {
                m_should_stop = true;
                LLDB_LOGF(
                    log,
                    "Failed to get an integer result from the expression.");
              }
            }
          } else {
            const char *err_str = "<unknown error>";
            if (result_value_sp)
              err_str = result_value_sp->GetError().AsCString();

            LLDB_LOGF(log, "Error evaluating condition: \"%s\"\n", err_str);

            StreamString strm;
            strm << "stopped due to an error evaluating condition of "
                    "watchpoint ";
            wp_sp->GetDescription(&strm, eDescriptionLevelBrief);
            strm << ": \"" << wp_sp->GetConditionText() << "\"\n";
            strm << err_str;

            Debugger::ReportError(strm.GetString().str(),
                                  exe_ctx.GetTargetRef().GetDebugger().GetID());
          }
        }

        // If the condition says to stop, we run the callback to further decide
        // whether to stop.
        if (m_should_stop) {
            // FIXME: For now the callbacks have to run in async mode - the
            // first time we restart we need
            // to get out of there.  So set it here.
            // When we figure out how to nest watchpoint hits then this will
            // change.

          bool old_async = debugger.GetAsyncExecution();
          debugger.SetAsyncExecution(true);

          StoppointCallbackContext context(event_ptr, exe_ctx, false);
          bool stop_requested = wp_sp->InvokeCallback(&context);

          debugger.SetAsyncExecution(old_async);

          // Also make sure that the callback hasn't continued the target. If
          // it did, when we'll set m_should_stop to false and get out of here.
          if (HasTargetRunSinceMe())
            m_should_stop = false;

          if (m_should_stop && !stop_requested) {
            // We have been vetoed by the callback mechanism.
            m_should_stop = false;
          }
        }

        // Don't stop if the watched region value is unmodified, and
        // this is a Modify-type watchpoint.
        if (m_should_stop && !wp_sp->WatchedValueReportable(exe_ctx)) {
          wp_sp->UndoHitCount();
          m_should_stop = false;
        }

        // Finally, if we are going to stop, print out the new & old values:
        if (m_should_stop) {
          wp_sp->CaptureWatchedValue(exe_ctx);

          Debugger &debugger = exe_ctx.GetTargetRef().GetDebugger();
          StreamUP output_up = debugger.GetAsyncOutputStream();
          if (wp_sp->DumpSnapshots(output_up.get()))
            output_up->EOL();
        }

      } else {
        Log *log_process(GetLog(LLDBLog::Process));

        LLDB_LOGF(log_process,
                  "Process::%s could not find watchpoint id: %" PRId64 "...",
                  __FUNCTION__, m_value);
      }
      LLDB_LOGF(log,
                "Process::%s returning from action with m_should_stop: %d.",
                __FUNCTION__, m_should_stop);

      m_should_stop_is_valid = true;
    }
  }

private:
  void SetStepOverPlanComplete() {
    assert(m_using_step_over_plan);
    m_step_over_plan_complete = true;
  }
  
  bool m_should_stop = false;
  bool m_should_stop_is_valid = false;
  // A false watchpoint hit has happened -
  // the thread stopped with a watchpoint
  // hit notification, but the watched region
  // was not actually accessed (as determined
  // by the gdb stub we're talking to).
  // Continue past this watchpoint without
  // notifying the user; on some targets this
  // may mean disable wp, instruction step,
  // re-enable wp, continue.
  // On others, just continue.
  bool m_silently_skip_wp = false;
  bool m_step_over_plan_complete = false;
  bool m_using_step_over_plan = false;
};

// StopInfoUnixSignal

class StopInfoUnixSignal : public StopInfo {
public:
  StopInfoUnixSignal(Thread &thread, int signo, const char *description,
                     std::optional<int> code)
      : StopInfo(thread, signo), m_code(code) {
    SetDescription(description);
  }

  ~StopInfoUnixSignal() override = default;

  StopReason GetStopReason() const override { return eStopReasonSignal; }

  bool ShouldStopSynchronous(Event *event_ptr) override {
    ThreadSP thread_sp(m_thread_wp.lock());
    if (thread_sp)
      return thread_sp->GetProcess()->GetUnixSignals()->GetShouldStop(m_value);
    return false;
  }

  void PerformAction([[maybe_unused]] Event *event_ptr) override {
    // A signal of SIGTRAP indicates that a trap instruction has been hit.
    if (m_value == SIGTRAP)
      SkipOverTrapInstruction();
  }

  bool ShouldStop(Event *event_ptr) override { return IsShouldStopSignal(); }

  // If should stop returns false, check if we should notify of this event
  bool DoShouldNotify(Event *event_ptr) override {
    ThreadSP thread_sp(m_thread_wp.lock());
    if (thread_sp) {
      bool should_notify =
          thread_sp->GetProcess()->GetUnixSignals()->GetShouldNotify(m_value);
      if (should_notify) {
        StreamString strm;
        strm.Format(
            "thread {0:d} received signal: {1}", thread_sp->GetIndexID(),
            thread_sp->GetProcess()->GetUnixSignals()->GetSignalAsStringRef(
                m_value));
        Process::ProcessEventData::AddRestartedReason(event_ptr,
                                                      strm.GetData());
      }
      return should_notify;
    }
    return true;
  }

  void WillResume(lldb::StateType resume_state) override {
    ThreadSP thread_sp(m_thread_wp.lock());
    if (thread_sp) {
      if (!thread_sp->GetProcess()->GetUnixSignals()->GetShouldSuppress(
              m_value))
        thread_sp->SetResumeSignal(m_value);
    }
  }

  const char *GetDescription() override {
    if (m_description.empty()) {
      ThreadSP thread_sp(m_thread_wp.lock());
      if (thread_sp) {
        UnixSignalsSP unix_signals = thread_sp->GetProcess()->GetUnixSignals();
        StreamString strm;
        strm << "signal ";

        std::string signal_name =
            unix_signals->GetSignalDescription(m_value, m_code);
        if (signal_name.size())
          strm << signal_name;
        else
          strm.Printf("%" PRIi64, m_value);

        m_description = std::string(strm.GetString());
      }
    }
    return m_description.c_str();
  }

  bool ShouldSelect() const override { return IsShouldStopSignal(); }

  uint32_t GetStopReasonDataCount() const override { return 1; }
  uint64_t GetStopReasonDataAtIndex(uint32_t idx) override {
    if (idx == 0)
      return GetValue();
    return 0;
  }

private:
  // In siginfo_t terms, if m_value is si_signo, m_code is si_code.
  std::optional<int> m_code;

  bool IsShouldStopSignal() const {
    if (ThreadSP thread_sp = m_thread_wp.lock())
      return thread_sp->GetProcess()->GetUnixSignals()->GetShouldStop(m_value);
    return false;
  }
};

// StopInfoInterrupt

class StopInfoInterrupt : public StopInfo {
public:
  StopInfoInterrupt(Thread &thread, int signo, const char *description)
      : StopInfo(thread, signo) {
    SetDescription(description);
  }

  ~StopInfoInterrupt() override = default;

  StopReason GetStopReason() const override {
    return lldb::eStopReasonInterrupt;
  }

  const char *GetDescription() override {
    if (m_description.empty()) {
      m_description = "async interrupt";
    }
    return m_description.c_str();
  }

  uint32_t GetStopReasonDataCount() const override { return 1; }
  uint64_t GetStopReasonDataAtIndex(uint32_t idx) override {
    if (idx == 0)
      return GetValue();
    else
      return 0;
  }
};

// StopInfoTrace

class StopInfoTrace : public StopInfo {
public:
  StopInfoTrace(Thread &thread) : StopInfo(thread, LLDB_INVALID_UID) {}

  ~StopInfoTrace() override = default;

  StopReason GetStopReason() const override { return eStopReasonTrace; }

  const char *GetDescription() override {
    if (m_description.empty())
      return "trace";
    else
      return m_description.c_str();
  }

  std::optional<uint32_t>
  GetSuggestedStackFrameIndex(bool inlined_stack) override {
    // Trace only knows how to adjust inlined stacks:
    if (!inlined_stack)
      return {};

    ThreadSP thread_sp = GetThread();
    StackFrameSP frame_0_sp = thread_sp->GetStackFrameAtIndex(0);
    if (!frame_0_sp)
      return {};
    if (!frame_0_sp->IsInlined())
      return {};
    Block *block_ptr = frame_0_sp->GetFrameBlock();
    if (!block_ptr)
      return {};
    Address pc_address = frame_0_sp->GetFrameCodeAddress();
    AddressRange containing_range;
    if (!block_ptr->GetRangeContainingAddress(pc_address, containing_range) ||
        pc_address != containing_range.GetBaseAddress())
      return {};

    int num_inlined_functions = 0;

    for (Block *container_ptr = block_ptr->GetInlinedParent();
         container_ptr != nullptr;
         container_ptr = container_ptr->GetInlinedParent()) {
      if (!container_ptr->GetRangeContainingAddress(pc_address,
                                                    containing_range))
        break;
      if (pc_address != containing_range.GetBaseAddress())
        break;

      num_inlined_functions++;
    }
    inlined_stack = true;
    return num_inlined_functions + 1;
  }
};

// StopInfoException

class StopInfoException : public StopInfo {
public:
  StopInfoException(Thread &thread, const char *description)
      : StopInfo(thread, LLDB_INVALID_UID) {
    if (description)
      SetDescription(description);
  }

  ~StopInfoException() override = default;

  StopReason GetStopReason() const override { return eStopReasonException; }

  const char *GetDescription() override {
    if (m_description.empty())
      return "exception";
    else
      return m_description.c_str();
  }
  uint32_t GetStopReasonDataCount() const override { return 1; }
  uint64_t GetStopReasonDataAtIndex(uint32_t idx) override {
    if (idx == 0)
      return GetValue();
    else
      return 0;
  }
};

// StopInfoProcessorTrace

class StopInfoProcessorTrace : public StopInfo {
public:
  StopInfoProcessorTrace(Thread &thread, const char *description)
      : StopInfo(thread, LLDB_INVALID_UID) {
    if (description)
      SetDescription(description);
  }

  ~StopInfoProcessorTrace() override = default;

  StopReason GetStopReason() const override {
    return eStopReasonProcessorTrace;
  }

  const char *GetDescription() override {
    if (m_description.empty())
      return "processor trace event";
    else
      return m_description.c_str();
  }
};

// StopInfoHistoryBoundary

class StopInfoHistoryBoundary : public StopInfo {
public:
  StopInfoHistoryBoundary(Thread &thread, const char *description)
      : StopInfo(thread, LLDB_INVALID_UID) {
    if (description)
      SetDescription(description);
  }

  ~StopInfoHistoryBoundary() override = default;

  StopReason GetStopReason() const override {
    return eStopReasonHistoryBoundary;
  }

  const char *GetDescription() override {
    if (m_description.empty())
      return "history boundary";
    return m_description.c_str();
  }
};

// StopInfoThreadPlan

class StopInfoThreadPlan : public StopInfo {
public:
  StopInfoThreadPlan(ThreadPlanSP &plan_sp, ValueObjectSP &return_valobj_sp,
                     ExpressionVariableSP &expression_variable_sp)
      : StopInfo(plan_sp->GetThread(), LLDB_INVALID_UID), m_plan_sp(plan_sp),
        m_return_valobj_sp(return_valobj_sp),
        m_expression_variable_sp(expression_variable_sp) {}

  ~StopInfoThreadPlan() override = default;

  StopReason GetStopReason() const override { return eStopReasonPlanComplete; }

  const char *GetDescription() override {
    if (m_description.empty()) {
      StreamString strm;
      m_plan_sp->GetDescription(&strm, eDescriptionLevelBrief);
      m_description = std::string(strm.GetString());
    }
    return m_description.c_str();
  }

  ValueObjectSP GetReturnValueObject() { return m_return_valobj_sp; }

  ExpressionVariableSP GetExpressionVariable() {
    return m_expression_variable_sp;
  }

protected:
  bool ShouldStop(Event *event_ptr) override {
    if (m_plan_sp)
      return m_plan_sp->ShouldStop(event_ptr);
    else
      return StopInfo::ShouldStop(event_ptr);
  }

private:
  ThreadPlanSP m_plan_sp;
  ValueObjectSP m_return_valobj_sp;
  ExpressionVariableSP m_expression_variable_sp;
};

// StopInfoExec

class StopInfoExec : public StopInfo {
public:
  StopInfoExec(Thread &thread) : StopInfo(thread, LLDB_INVALID_UID) {}

  ~StopInfoExec() override = default;

  bool ShouldStop(Event *event_ptr) override {
    ThreadSP thread_sp(m_thread_wp.lock());
    if (thread_sp)
      return thread_sp->GetProcess()->GetStopOnExec();
    return false;
  }

  StopReason GetStopReason() const override { return eStopReasonExec; }

  const char *GetDescription() override { return "exec"; }

protected:
  void PerformAction(Event *event_ptr) override {
    // Only perform the action once
    if (m_performed_action)
      return;
    m_performed_action = true;
    ThreadSP thread_sp(m_thread_wp.lock());
    if (thread_sp)
      thread_sp->GetProcess()->DidExec();
  }

  bool m_performed_action = false;
};


// StopInfoFork

class StopInfoFork : public StopInfo {
public:
  StopInfoFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
      : StopInfo(thread, child_pid), m_child_pid(child_pid),
        m_child_tid(child_tid) {}

  ~StopInfoFork() override = default;

  bool ShouldStop(Event *event_ptr) override {
    // During expression evaluation, return true so that the fork event
    // reaches RunThreadPlan as a real stop (not auto-restarted by
    // DoOnRemoval). RunThreadPlan decides whether to stop or continue
    // based on the stop-on-fork option.
    //
    // We check per-thread (not just process-wide IsRunningExpression)
    // because other threads may fork concurrently after the
    // try-all-threads timeout releases them.
    ThreadSP thread_sp(m_thread_wp.lock());
    if (thread_sp) {
      ProcessSP process_sp = thread_sp->GetProcess();
      if (process_sp && process_sp->GetModIDRef().IsRunningExpression() &&
          thread_sp->IsRunningCallFunctionPlan())
        return true;
    }
    return false;
  }

  StopReason GetStopReason() const override { return eStopReasonFork; }

  const char *GetDescription() override { return "fork"; }

  uint32_t GetStopReasonDataCount() const override { return 1; }
  uint64_t GetStopReasonDataAtIndex(uint32_t idx) override {
    if (idx == 0)
      return GetValue();
    else
      return 0;
  }

protected:
  void PerformAction(Event *event_ptr) override {
    // Only perform the action once
    if (m_performed_action)
      return;
    m_performed_action = true;
    ThreadSP thread_sp(m_thread_wp.lock());
    if (thread_sp) {
      bool is_expression_fork =
          thread_sp->GetProcess()->GetModIDRef().IsRunningExpression() &&
          thread_sp->IsRunningCallFunctionPlan();
      thread_sp->GetProcess()->DidFork(m_child_pid, m_child_tid,
                                       is_expression_fork);
    }
  }

  bool m_performed_action = false;

private:
  lldb::pid_t m_child_pid;
  lldb::tid_t m_child_tid;
};

// StopInfoVFork

class StopInfoVFork : public StopInfo {
public:
  StopInfoVFork(Thread &thread, lldb::pid_t child_pid, lldb::tid_t child_tid)
      : StopInfo(thread, child_pid), m_child_pid(child_pid),
        m_child_tid(child_tid) {}

  ~StopInfoVFork() override = default;

  bool ShouldStop(Event *event_ptr) override {
    ThreadSP thread_sp(m_thread_wp.lock());
    if (thread_sp) {
      ProcessSP process_sp = thread_sp->GetProcess();
      if (process_sp && process_sp->GetModIDRef().IsRunningExpression() &&
          thread_sp->IsRunningCallFunctionPlan())
        return true;
    }
    return false;
  }

  StopReason GetStopReason() const override { return eStopReasonVFork; }

  const char *GetDescription() override { return "vfork"; }

  uint32_t GetStopReasonDataCount() const override { return 1; }
  uint64_t GetStopReasonDataAtIndex(uint32_t idx) override {
    if (idx == 0)
      return GetValue();
    return 0;
  }

protected:
  void PerformAction(Event *event_ptr) override {
    // Only perform the action once
    if (m_performed_action)
      return;
    m_performed_action = true;
    ThreadSP thread_sp(m_thread_wp.lock());
    if (thread_sp) {
      bool is_expression_fork =
          thread_sp->GetProcess()->GetModIDRef().IsRunningExpression() &&
          thread_sp->IsRunningCallFunctionPlan();
      thread_sp->GetProcess()->DidVFork(m_child_pid, m_child_tid,
                                        is_expression_fork);
    }
  }

  bool m_performed_action = false;

private:
  lldb::pid_t m_child_pid;
  lldb::tid_t m_child_tid;
};

// StopInfoVForkDone

class StopInfoVForkDone : public StopInfo {
public:
  StopInfoVForkDone(Thread &thread) : StopInfo(thread, 0) {}

  ~StopInfoVForkDone() override = default;

  bool ShouldStop(Event *event_ptr) override {
    ThreadSP thread_sp(m_thread_wp.lock());
    if (thread_sp) {
      ProcessSP process_sp = thread_sp->GetProcess();
      if (process_sp && process_sp->GetModIDRef().IsRunningExpression() &&
          thread_sp->IsRunningCallFunctionPlan())
        return true;
    }
    return false;
  }

  StopReason GetStopReason() const override { return eStopReasonVForkDone; }

  const char *GetDescription() override { return "vforkdone"; }

protected:
  void PerformAction(Event *event_ptr) override {
    // Only perform the action once
    if (m_performed_action)
      return;
    m_performed_action = true;
    ThreadSP thread_sp(m_thread_wp.lock());
    if (thread_sp)
      thread_sp->GetProcess()->DidVForkDone();
  }

  bool m_performed_action = false;
};

} // namespace lldb_private

StopInfoSP StopInfo::CreateStopReasonWithBreakpointSiteID(Thread &thread,
                                                          break_id_t break_id) {
  thread.SetThreadHitBreakpointSite();

  return std::make_shared<StopInfoBreakpoint>(thread, break_id);
}

StopInfoSP StopInfo::CreateStopReasonWithBreakpointSiteID(Thread &thread,
                                                          break_id_t break_id,
                                                          bool should_stop) {
  return std::make_shared<StopInfoBreakpoint>(thread, break_id, should_stop);
}

// LWP_TODO: We'll need a CreateStopReasonWithWatchpointResourceID akin
// to CreateStopReasonWithBreakpointSiteID
StopInfoSP StopInfo::CreateStopReasonWithWatchpointID(Thread &thread,
                                                      break_id_t watch_id,
                                                      bool silently_continue) {
  return std::make_shared<StopInfoWatchpoint>(thread, watch_id,
                                              silently_continue);
}

StopInfoSP StopInfo::CreateStopReasonWithSignal(Thread &thread, int signo,
                                                const char *description,
                                                std::optional<int> code) {
  thread.GetProcess()->GetUnixSignals()->IncrementSignalHitCount(signo);
  return std::make_shared<StopInfoUnixSignal>(thread, signo, description, code);
}

StopInfoSP StopInfo::CreateStopReasonWithInterrupt(Thread &thread, int signo,
                                                   const char *description) {
  return std::make_shared<StopInfoInterrupt>(thread, signo, description);
}

StopInfoSP StopInfo::CreateStopReasonToTrace(Thread &thread) {
  return std::make_shared<StopInfoTrace>(thread);
}

StopInfoSP StopInfo::CreateStopReasonWithPlan(
    ThreadPlanSP &plan_sp, ValueObjectSP return_valobj_sp,
    ExpressionVariableSP expression_variable_sp) {
  return std::make_shared<StopInfoThreadPlan>(plan_sp, return_valobj_sp,
                                              expression_variable_sp);
}

StopInfoSP StopInfo::CreateStopReasonWithException(Thread &thread,
                                                   const char *description) {
  return std::make_shared<StopInfoException>(thread, description);
}

StopInfoSP StopInfo::CreateStopReasonProcessorTrace(Thread &thread,
                                                    const char *description) {
  return std::make_shared<StopInfoProcessorTrace>(thread, description);
}

StopInfoSP StopInfo::CreateStopReasonHistoryBoundary(Thread &thread,
                                                     const char *description) {
  return std::make_shared<StopInfoHistoryBoundary>(thread, description);
}

StopInfoSP StopInfo::CreateStopReasonWithExec(Thread &thread) {
  return std::make_shared<StopInfoExec>(thread);
}

StopInfoSP StopInfo::CreateStopReasonFork(Thread &thread,
                                          lldb::pid_t child_pid,
                                          lldb::tid_t child_tid) {
  return std::make_shared<StopInfoFork>(thread, child_pid, child_tid);
}


StopInfoSP StopInfo::CreateStopReasonVFork(Thread &thread,
                                           lldb::pid_t child_pid,
                                           lldb::tid_t child_tid) {
  return std::make_shared<StopInfoVFork>(thread, child_pid, child_tid);
}

StopInfoSP StopInfo::CreateStopReasonVForkDone(Thread &thread) {
  return std::make_shared<StopInfoVForkDone>(thread);
}

ValueObjectSP StopInfo::GetReturnValueObject(StopInfoSP &stop_info_sp) {
  if (stop_info_sp &&
      stop_info_sp->GetStopReason() == eStopReasonPlanComplete) {
    StopInfoThreadPlan *plan_stop_info =
        static_cast<StopInfoThreadPlan *>(stop_info_sp.get());
    return plan_stop_info->GetReturnValueObject();
  } else
    return ValueObjectSP();
}

ExpressionVariableSP StopInfo::GetExpressionVariable(StopInfoSP &stop_info_sp) {
  if (stop_info_sp &&
      stop_info_sp->GetStopReason() == eStopReasonPlanComplete) {
    StopInfoThreadPlan *plan_stop_info =
        static_cast<StopInfoThreadPlan *>(stop_info_sp.get());
    return plan_stop_info->GetExpressionVariable();
  } else
    return ExpressionVariableSP();
}

lldb::ValueObjectSP
StopInfo::GetCrashingDereference(StopInfoSP &stop_info_sp,
                                 lldb::addr_t *crashing_address) {
  if (!stop_info_sp) {
    return ValueObjectSP();
  }

  const char *description = stop_info_sp->GetDescription();
  if (!description) {
    return ValueObjectSP();
  }

  ThreadSP thread_sp = stop_info_sp->GetThread();
  if (!thread_sp) {
    return ValueObjectSP();
  }

  StackFrameSP frame_sp =
      thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame);

  if (!frame_sp) {
    return ValueObjectSP();
  }

  const char address_string[] = "address=";

  const char *address_loc = strstr(description, address_string);
  if (!address_loc) {
    return ValueObjectSP();
  }

  address_loc += (sizeof(address_string) - 1);

  uint64_t address = strtoull(address_loc, nullptr, 0);
  if (crashing_address) {
    *crashing_address = address;
  }

  return frame_sp->GuessValueForAddress(address);
}
