[Lldb-commits] [lldb] [lldb] Handle accelerator plugin breakpoint actions on the client (PR #201489)
David Spickett via lldb-commits
lldb-commits at lists.llvm.org
Fri Jun 5 08:41:04 PDT 2026
================
@@ -4124,6 +4143,181 @@ bool ProcessGDBRemote::NewThreadNotifyBreakpointHit(
return false;
}
+namespace {
+/// Baton that carries the breakpoint hit arguments to the accelerator plugin
+/// breakpoint callback.
+class AcceleratorBreakpointCallbackBaton
+ : public TypedBaton<AcceleratorBreakpointHitArgs> {
+public:
+ explicit AcceleratorBreakpointCallbackBaton(
+ std::unique_ptr<AcceleratorBreakpointHitArgs> data)
+ : TypedBaton(std::move(data)) {}
+};
+} // namespace
+
+Status
+ProcessGDBRemote::HandleAcceleratorActions(const AcceleratorActions &actions) {
+ Log *log = GetLog(GDBRLog::Process);
+
+ // The same set of actions can be delivered to the client more than once: a
+ // plugin may keep reporting the same actions (with the same identifier) on
+ // subsequent native stops until its state advances. The identifier uniquely
+ // names a set of actions for a plugin, so skip any set we have already
+ // processed to avoid re-running its side effects (e.g. setting the same
+ // breakpoints again).
+ auto it = m_processed_accelerator_actions.find(actions.plugin_name);
+ if (it != m_processed_accelerator_actions.end() &&
+ it->second == actions.identifier) {
+ LLDB_LOG(log,
+ "ProcessGDBRemote::HandleAcceleratorActions skipping already "
+ "processed actions for plugin '{0}' with identifier {1}",
+ actions.plugin_name, actions.identifier);
+ return Status();
+ }
+ m_processed_accelerator_actions[actions.plugin_name] = actions.identifier;
+
+ // Handle each kind of action. More action kinds will be handled here in the
+ // future, so only return early on error; otherwise fall through so the next
+ // kind of action still gets a chance to run.
+ if (!actions.breakpoints.empty()) {
+ if (Status error = HandleAcceleratorBreakpoints(actions); error.Fail())
+ return error;
+ }
+
+ return Status();
+}
+
+Status ProcessGDBRemote::HandleAcceleratorBreakpoints(
+ const AcceleratorActions &actions) {
+ Target &target = GetTarget();
+ Status error;
+ for (const AcceleratorBreakpointInfo &bp : actions.breakpoints) {
+ // Carry data with the breakpoint so the callback can notify the plugin
+ // when the breakpoint is hit.
+ auto args_up = std::make_unique<AcceleratorBreakpointHitArgs>();
+ args_up->plugin_name = actions.plugin_name;
+ args_up->breakpoint = bp;
+
+ // Each breakpoint must specify exactly one of by_name or by_address.
+ BreakpointSP bp_sp;
+ if (bp.by_name && bp.by_address) {
+ // Record the first error but keep setting the remaining breakpoints.
+ if (error.Success())
+ error = Status::FromErrorStringWithFormatv(
+ "accelerator breakpoint {0} specifies both a by_name and a "
+ "by_address specification",
+ bp.identifier);
+ continue;
+ } else if (bp.by_name) {
+ FileSpecList bp_modules;
+ if (bp.by_name->shlib && !bp.by_name->shlib->empty())
+ bp_modules.Append(FileSpec(*bp.by_name->shlib));
+ bp_sp = target.CreateBreakpoint(
+ bp_modules.GetSize() ? &bp_modules : nullptr, // Containing modules.
+ nullptr, // Containing source.
+ bp.by_name->function_name.c_str(), // Function name.
+ eFunctionNameTypeFull, // Function name type.
+ eLanguageTypeUnknown, // Language type.
+ 0, // Byte offset.
+ false, // Offset is insn count.
+ eLazyBoolNo, // Skip prologue.
+ true, // Internal breakpoint.
+ false); // Request hardware.
+ } else if (bp.by_address) {
+ bp_sp = target.CreateBreakpoint(bp.by_address->load_address,
+ /*internal=*/true,
+ /*request_hardware=*/false);
+ } else {
+ if (error.Success())
+ error = Status::FromErrorStringWithFormatv(
+ "accelerator breakpoint {0} has neither a by_name nor a by_address "
+ "specification",
+ bp.identifier);
+ continue;
+ }
+
+ if (!bp_sp) {
+ if (error.Success())
+ error = Status::FromErrorStringWithFormatv(
+ "failed to set accelerator breakpoint {0}", bp.identifier);
+ continue;
+ }
+
+ // Give the internal breakpoint a meaningful description for stop reasons.
+ bp_sp->SetBreakpointKind("accelerator-plugin");
----------------
DavidSpickett wrote:
It assume it would be nice to know the name of the plugin too. `accelerator plugin (AMDGPU)` maybe.
If you do add it, first check what `SetBreakpointKind` assumes about the lifetime of the string.
https://github.com/llvm/llvm-project/pull/201489
More information about the lldb-commits
mailing list