clang 20.0.0 (based on r547379) from build 12806354. Bug: http://b/379133546 Test: N/A Change-Id: I2eb8938af55d809de674be63cb30cf27e801862b Upstream-Commit: ad834e67b1105d15ef907f6255d4c96e8e733f57
216 lines
8.0 KiB
C++
216 lines
8.0 KiB
C++
//===-- StopInfo.h ----------------------------------------------*- C++ -*-===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLDB_TARGET_STOPINFO_H
|
|
#define LLDB_TARGET_STOPINFO_H
|
|
|
|
#include <string>
|
|
|
|
#include "lldb/Target/Process.h"
|
|
#include "lldb/Utility/StructuredData.h"
|
|
#include "lldb/lldb-public.h"
|
|
|
|
namespace lldb_private {
|
|
|
|
class StopInfo : public std::enable_shared_from_this<StopInfo> {
|
|
friend class Process::ProcessEventData;
|
|
friend class ThreadPlanBase;
|
|
|
|
public:
|
|
// Constructors and Destructors
|
|
StopInfo(Thread &thread, uint64_t value);
|
|
|
|
virtual ~StopInfo() = default;
|
|
|
|
bool IsValid() const;
|
|
|
|
void SetThread(const lldb::ThreadSP &thread_sp) { m_thread_wp = thread_sp; }
|
|
|
|
lldb::ThreadSP GetThread() const { return m_thread_wp.lock(); }
|
|
|
|
// The value of the StopInfo depends on the StopReason.
|
|
//
|
|
// StopReason Meaning
|
|
// ------------------------------------------------
|
|
// eStopReasonBreakpoint BreakpointSiteID
|
|
// eStopReasonSignal Signal number
|
|
// eStopReasonWatchpoint WatchpointLocationID
|
|
// eStopReasonPlanComplete No significance
|
|
|
|
uint64_t GetValue() const { return m_value; }
|
|
|
|
virtual lldb::StopReason GetStopReason() const = 0;
|
|
|
|
// ShouldStopSynchronous will get called before any thread plans are
|
|
// consulted, and if it says we should resume the target, then we will just
|
|
// immediately resume. This should not run any code in or resume the target.
|
|
|
|
virtual bool ShouldStopSynchronous(Event *event_ptr) { return true; }
|
|
|
|
void OverrideShouldNotify(bool override_value) {
|
|
m_override_should_notify = override_value ? eLazyBoolYes : eLazyBoolNo;
|
|
}
|
|
|
|
// If should stop returns false, check if we should notify of this event
|
|
virtual bool ShouldNotify(Event *event_ptr) {
|
|
if (m_override_should_notify == eLazyBoolCalculate)
|
|
return DoShouldNotify(event_ptr);
|
|
else
|
|
return m_override_should_notify == eLazyBoolYes;
|
|
}
|
|
|
|
virtual void WillResume(lldb::StateType resume_state) {
|
|
// By default, don't do anything
|
|
}
|
|
|
|
virtual const char *GetDescription() { return m_description.c_str(); }
|
|
|
|
virtual void SetDescription(const char *desc_cstr) {
|
|
if (desc_cstr && desc_cstr[0])
|
|
m_description.assign(desc_cstr);
|
|
else
|
|
m_description.clear();
|
|
}
|
|
|
|
virtual bool IsValidForOperatingSystemThread(Thread &thread) { return true; }
|
|
|
|
/// A Continue operation can result in a false stop event
|
|
/// before any execution has happened. We need to detect this
|
|
/// and silently continue again one more time.
|
|
virtual bool WasContinueInterrupted(Thread &thread) { return false; }
|
|
|
|
// Sometimes the thread plan logic will know that it wants a given stop to
|
|
// stop or not, regardless of what the ordinary logic for that StopInfo would
|
|
// dictate. The main example of this is the ThreadPlanCallFunction, which
|
|
// for instance knows - based on how that particular expression was executed
|
|
// - whether it wants all breakpoints to auto-continue or not. Use
|
|
// OverrideShouldStop on the StopInfo to implement this.
|
|
|
|
void OverrideShouldStop(bool override_value) {
|
|
m_override_should_stop = override_value ? eLazyBoolYes : eLazyBoolNo;
|
|
}
|
|
|
|
bool GetOverrideShouldStop() {
|
|
return m_override_should_stop != eLazyBoolCalculate;
|
|
}
|
|
|
|
bool GetOverriddenShouldStopValue() {
|
|
return m_override_should_stop == eLazyBoolYes;
|
|
}
|
|
|
|
StructuredData::ObjectSP GetExtendedInfo() { return m_extended_info; }
|
|
|
|
static lldb::StopInfoSP
|
|
CreateStopReasonWithBreakpointSiteID(Thread &thread,
|
|
lldb::break_id_t break_id);
|
|
|
|
// This creates a StopInfo for the thread where the should_stop is already
|
|
// set, and won't be recalculated.
|
|
static lldb::StopInfoSP CreateStopReasonWithBreakpointSiteID(
|
|
Thread &thread, lldb::break_id_t break_id, bool should_stop);
|
|
|
|
static lldb::StopInfoSP
|
|
CreateStopReasonWithWatchpointID(Thread &thread, lldb::break_id_t watch_id,
|
|
bool silently_continue = false);
|
|
|
|
static lldb::StopInfoSP
|
|
CreateStopReasonWithSignal(Thread &thread, int signo,
|
|
const char *description = nullptr,
|
|
std::optional<int> code = std::nullopt);
|
|
|
|
static lldb::StopInfoSP
|
|
CreateStopReasonWithInterrupt(Thread &thread, int signo,
|
|
const char *description);
|
|
|
|
static lldb::StopInfoSP CreateStopReasonToTrace(Thread &thread);
|
|
|
|
static lldb::StopInfoSP
|
|
CreateStopReasonWithPlan(lldb::ThreadPlanSP &plan,
|
|
lldb::ValueObjectSP return_valobj_sp,
|
|
lldb::ExpressionVariableSP expression_variable_sp);
|
|
|
|
static lldb::StopInfoSP
|
|
CreateStopReasonWithException(Thread &thread, const char *description);
|
|
|
|
static lldb::StopInfoSP CreateStopReasonWithExec(Thread &thread);
|
|
|
|
static lldb::StopInfoSP
|
|
CreateStopReasonProcessorTrace(Thread &thread, const char *description);
|
|
|
|
static lldb::StopInfoSP CreateStopReasonFork(Thread &thread,
|
|
lldb::pid_t child_pid,
|
|
lldb::tid_t child_tid);
|
|
|
|
static lldb::StopInfoSP CreateStopReasonVFork(Thread &thread,
|
|
lldb::pid_t child_pid,
|
|
lldb::tid_t child_tid);
|
|
|
|
static lldb::StopInfoSP CreateStopReasonVForkDone(Thread &thread);
|
|
|
|
static lldb::ValueObjectSP
|
|
GetReturnValueObject(lldb::StopInfoSP &stop_info_sp);
|
|
|
|
static lldb::ExpressionVariableSP
|
|
GetExpressionVariable(lldb::StopInfoSP &stop_info_sp);
|
|
|
|
static lldb::ValueObjectSP
|
|
GetCrashingDereference(lldb::StopInfoSP &stop_info_sp,
|
|
lldb::addr_t *crashing_address = nullptr);
|
|
|
|
protected:
|
|
// Perform any action that is associated with this stop. This is done as the
|
|
// Event is removed from the event queue. ProcessEventData::DoOnRemoval does
|
|
// the job.
|
|
|
|
virtual void PerformAction(Event *event_ptr) {}
|
|
|
|
virtual bool DoShouldNotify(Event *event_ptr) { return false; }
|
|
|
|
// Stop the thread by default. Subclasses can override this to allow the
|
|
// thread to continue if desired. The ShouldStop method should not do
|
|
// anything that might run code. If you need to run code when deciding
|
|
// whether to stop at this StopInfo, that must be done in the PerformAction.
|
|
// The PerformAction will always get called before the ShouldStop. This is
|
|
// done by the ProcessEventData::DoOnRemoval, though the ThreadPlanBase needs
|
|
// to consult this later on.
|
|
virtual bool ShouldStop(Event *event_ptr) { return true; }
|
|
|
|
// Classes that inherit from StackID can see and modify these
|
|
lldb::ThreadWP m_thread_wp; // The thread corresponding to the stop reason.
|
|
uint32_t m_stop_id; // The process stop ID for which this stop info is valid
|
|
uint32_t m_resume_id; // This is the resume ID when we made this stop ID.
|
|
uint64_t m_value; // A generic value that can be used for things pertaining to
|
|
// this stop info
|
|
std::string m_description; // A textual description describing this stop.
|
|
LazyBool m_override_should_notify;
|
|
LazyBool m_override_should_stop;
|
|
|
|
StructuredData::ObjectSP
|
|
m_extended_info; // The extended info for this stop info
|
|
|
|
// This determines whether the target has run since this stop info. N.B.
|
|
// running to evaluate a user expression does not count.
|
|
bool HasTargetRunSinceMe();
|
|
|
|
// MakeStopInfoValid is necessary to allow saved stop infos to resurrect
|
|
// themselves as valid. It should only be used by
|
|
// Thread::RestoreThreadStateFromCheckpoint and to make sure the one-step
|
|
// needed for before-the-fact watchpoints does not prevent us from stopping
|
|
void MakeStopInfoValid();
|
|
|
|
private:
|
|
friend class Thread;
|
|
|
|
StopInfo(const StopInfo &) = delete;
|
|
const StopInfo &operator=(const StopInfo &) = delete;
|
|
};
|
|
|
|
} // namespace lldb_private
|
|
|
|
#endif // LLDB_TARGET_STOPINFO_H
|