Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 58 additions & 21 deletions lldb/include/lldb/Target/Target.h
Original file line number Diff line number Diff line change
Expand Up @@ -1356,7 +1356,11 @@ class Target : public std::enable_shared_from_this<Target>,
StopHook(const StopHook &rhs);
virtual ~StopHook() = default;

enum class StopHookKind : uint32_t { CommandBased = 0, ScriptBased };
enum class StopHookKind : uint32_t {
CommandBased = 0,
ScriptBased,
CodeBased,
};
enum class StopHookResult : uint32_t {
KeepStopped = 0,
RequestContinue,
Expand Down Expand Up @@ -1403,6 +1407,12 @@ class Target : public std::enable_shared_from_this<Target>,

bool GetRunAtInitialStop() const { return m_at_initial_stop; }

void SetSuppressOutput(bool suppress_output) {
m_suppress_output = suppress_output;
}

bool GetSuppressOutput() const { return m_suppress_output; }

void GetDescription(Stream &s, lldb::DescriptionLevel level) const;
virtual void GetSubclassDescription(Stream &s,
lldb::DescriptionLevel level) const = 0;
Expand All @@ -1414,6 +1424,7 @@ class Target : public std::enable_shared_from_this<Target>,
bool m_active = true;
bool m_auto_continue = false;
bool m_at_initial_stop = true;
bool m_suppress_output = false;

StopHook(lldb::TargetSP target_sp, lldb::user_id_t uid);
};
Expand All @@ -1433,8 +1444,8 @@ class Target : public std::enable_shared_from_this<Target>,

private:
StringList m_commands;
// Use CreateStopHook to make a new empty stop hook. The GetCommandPointer
// and fill it with commands, and SetSpecifier to set the specifier shared
// Use CreateStopHook to make a new empty stop hook. Use SetActionFromString
// to fill it with commands, and SetSpecifier to set the specifier shared
// pointer (can be null, that will match anything.)
StopHookCommandLine(lldb::TargetSP target_sp, lldb::user_id_t uid)
: StopHook(target_sp, uid) {}
Expand All @@ -1460,19 +1471,56 @@ class Target : public std::enable_shared_from_this<Target>,
StructuredDataImpl m_extra_args;
lldb::ScriptedStopHookInterfaceSP m_interface_sp;

/// Use CreateStopHook to make a new empty stop hook. The GetCommandPointer
/// and fill it with commands, and SetSpecifier to set the specifier shared
/// pointer (can be null, that will match anything.)
/// Use CreateStopHook to make a new empty stop hook. Use SetScriptCallback
/// to set the script to execute, and SetSpecifier to set the specifier
/// shared pointer (can be null, that will match anything.)
StopHookScripted(lldb::TargetSP target_sp, lldb::user_id_t uid)
: StopHook(target_sp, uid) {}
friend class Target;
};

class StopHookCoded : public StopHook {
public:
~StopHookCoded() override = default;

using HandleStopCallback = StopHookResult(ExecutionContext &exc_ctx,
lldb::StreamSP output);

void SetCallback(llvm::StringRef name, HandleStopCallback *callback) {
m_name = name;
m_callback = callback;
}

StopHookResult HandleStop(ExecutionContext &exc_ctx,
lldb::StreamSP output) override {
return m_callback(exc_ctx, output);
}

void GetSubclassDescription(Stream &s,
lldb::DescriptionLevel level) const override {
s.Indent();
s.Printf("%s (built-in)\n", m_name.c_str());
}

private:
std::string m_name;
HandleStopCallback *m_callback;

/// Use CreateStopHook to make a new empty stop hook. Use SetCallback to set
/// the callback to execute, and SetSpecifier to set the specifier shared
/// pointer (can be null, that will match anything.)
StopHookCoded(lldb::TargetSP target_sp, lldb::user_id_t uid)
: StopHook(target_sp, uid) {}
friend class Target;
};

void RegisterInternalStopHooks();

typedef std::shared_ptr<StopHook> StopHookSP;

/// Add an empty stop hook to the Target's stop hook list, and returns a
/// shared pointer to it in new_hook. Returns the id of the new hook.
StopHookSP CreateStopHook(StopHook::StopHookKind kind);
/// shared pointer to the new hook.
StopHookSP CreateStopHook(StopHook::StopHookKind kind, bool internal = false);

/// If you tried to create a stop hook, and that failed, call this to
/// remove the stop hook, as it will also reset the stop hook counter.
Expand Down Expand Up @@ -1504,19 +1552,7 @@ class Target : public std::enable_shared_from_this<Target>,

void SetAllStopHooksActiveState(bool active_state);

size_t GetNumStopHooks() const { return m_stop_hooks.size(); }

StopHookSP GetStopHookAtIndex(size_t index) {
if (index >= GetNumStopHooks())
return StopHookSP();
StopHookCollection::iterator pos = m_stop_hooks.begin();

while (index > 0) {
pos++;
index--;
}
return (*pos).second;
}
const std::vector<StopHookSP> GetStopHooks(bool internal = false) const;

lldb::PlatformSP GetPlatform() { return m_platform_sp; }

Expand Down Expand Up @@ -1656,6 +1692,7 @@ class Target : public std::enable_shared_from_this<Target>,
typedef std::map<lldb::user_id_t, StopHookSP> StopHookCollection;
StopHookCollection m_stop_hooks;
lldb::user_id_t m_stop_hook_next_id;
std::vector<StopHookSP> m_internal_stop_hooks;
uint32_t m_latest_stop_hook_id; /// This records the last natural stop at
/// which we ran a stop-hook.
bool m_valid;
Expand Down
4 changes: 1 addition & 3 deletions lldb/source/Commands/CommandCompletions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -777,13 +777,11 @@ void CommandCompletions::StopHookIDs(CommandInterpreter &interpreter,
if (!target_sp)
return;

const size_t num = target_sp->GetNumStopHooks();
for (size_t idx = 0; idx < num; ++idx) {
for (auto &stophook_sp : target_sp->GetStopHooks()) {
StreamString strm;
// The value 11 is an offset to make the completion description looks
// neater.
strm.SetIndentLevel(11);
const Target::StopHookSP stophook_sp = target_sp->GetStopHookAtIndex(idx);
stophook_sp->GetDescription(strm, lldb::eDescriptionLevelInitial);
request.TryCompleteCurrentArg(std::to_string(stophook_sp->GetID()),
strm.GetString());
Expand Down
4 changes: 1 addition & 3 deletions lldb/source/Commands/CommandObjectBreakpoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1114,9 +1114,7 @@ class CommandObjectBreakpointList : public CommandObjectParsed {
CommandObjectBreakpointList(CommandInterpreter &interpreter)
: CommandObjectParsed(
interpreter, "breakpoint list",
"List some or all breakpoints at configurable levels of detail.",
nullptr) {
CommandArgumentData bp_id_arg;
"List some or all breakpoints at configurable levels of detail.") {

// Define the first (and only) variant of this arg.
AddSimpleArgumentList(eArgTypeBreakpointID, eArgRepeatOptional);
Expand Down
63 changes: 51 additions & 12 deletions lldb/source/Commands/CommandObjectTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5223,33 +5223,72 @@ class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
#pragma mark CommandObjectTargetStopHookList

// CommandObjectTargetStopHookList
#define LLDB_OPTIONS_target_stop_hook_list
#include "CommandOptions.inc"

class CommandObjectTargetStopHookList : public CommandObjectParsed {
public:
CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
: CommandObjectParsed(interpreter, "target stop-hook list",
"List all stop-hooks.", "target stop-hook list") {}
"List all stop-hooks.") {}

~CommandObjectTargetStopHookList() override = default;

Options *GetOptions() override { return &m_options; }

class CommandOptions : public Options {
public:
CommandOptions() = default;
~CommandOptions() override = default;

Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
ExecutionContext *execution_context) override {
Status error;
const int short_option = m_getopt_table[option_idx].val;

switch (short_option) {
case 'i':
m_internal = true;
break;
default:
llvm_unreachable("Unimplemented option");
}

return error;
}

void OptionParsingStarting(ExecutionContext *execution_context) override {
m_internal = false;
}

llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
return llvm::ArrayRef(g_target_stop_hook_list_options);
}

// Instance variables to hold the values for command options.
bool m_internal = false;
};

protected:
void DoExecute(Args &command, CommandReturnObject &result) override {
Target &target = GetTarget();

size_t num_hooks = target.GetNumStopHooks();
if (num_hooks == 0) {
result.GetOutputStream().PutCString("No stop hooks.\n");
} else {
for (size_t i = 0; i < num_hooks; i++) {
Target::StopHookSP this_hook = target.GetStopHookAtIndex(i);
if (i > 0)
result.GetOutputStream().PutCString("\n");
this_hook->GetDescription(result.GetOutputStream(),
eDescriptionLevelFull);
}
bool printed_hook = false;
for (auto &hook : target.GetStopHooks(m_options.m_internal)) {
if (printed_hook)
result.GetOutputStream().PutCString("\n");
hook->GetDescription(result.GetOutputStream(), eDescriptionLevelFull);
printed_hook = true;
}

if (!printed_hook)
result.GetOutputStream().PutCString("No stop hooks.\n");

result.SetStatus(eReturnStatusSuccessFinishResult);
}

private:
CommandOptions m_options;
};

#pragma mark CommandObjectMultiwordTargetStopHooks
Expand Down
10 changes: 8 additions & 2 deletions lldb/source/Commands/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ let Command = "breakpoint list" in {
// FIXME: We need to add an "internal" command, and then add this sort of
// thing to it. But I need to see it for now, and don't want to wait.
def blist_internal : Option<"internal", "i">,
Desc<"Show debugger ${i}nternal breakpoints">;
Desc<"Show debugger ${i}nternal breakpoints.">;
def blist_brief : Option<"brief", "b">,
Group<1>,
Desc<"Give a ${b}rief description of the breakpoint (no "
Expand Down Expand Up @@ -1686,7 +1686,7 @@ let Command = "target modules lookup" in {
"match, if a best match is available.">;
}

let Command = "target stop hook add" in {
let Command = "target stop_hook add" in {
def target_stop_hook_add_one_liner
: Option<"one-liner", "o">,
GroupRange<1, 3>,
Expand Down Expand Up @@ -1762,6 +1762,12 @@ let Command = "target stop hook add" in {
"Defaults to true.">;
}

let Command = "target stop_hook list" in {
def target_stop_hook_list_internal
: Option<"internal", "i">,
Desc<"Show debugger ${i}nternal stop hooks.">;
}

let Command = "thread backtrace" in {
def thread_backtrace_count : Option<"count", "c">,
Group<1>,
Expand Down
Loading
Loading