[Lldb-commits] [lldb] [lldb] Interpret breakpoint-id "." as the location(s) of the current stop (PR #194272)
Dave Lee via lldb-commits
lldb-commits at lists.llvm.org
Tue Apr 28 13:03:25 PDT 2026
https://github.com/kastiglione updated https://github.com/llvm/llvm-project/pull/194272
>From a4cce4cabe507c26a015e11aa860c603a7794889 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Sun, 26 Apr 2026 16:26:02 -0700
Subject: [PATCH 1/7] [lldb] Interpret breakpoint-id "." as meaning the
locations of the current stop
---
.../lldb/Breakpoint/BreakpointIDList.h | 3 +-
lldb/source/Breakpoint/BreakpointIDList.cpp | 38 ++++++++++++++-
.../Commands/CommandObjectBreakpoint.cpp | 23 ++++-----
.../source/Commands/CommandObjectBreakpoint.h | 13 ++---
.../CommandObjectBreakpointCommand.cpp | 6 +--
lldb/source/Commands/CommandObjectProcess.cpp | 2 +-
.../test/API/commands/breakpoint/dot/Makefile | 3 ++
.../breakpoint/dot/TestBreakpointDot.py | 48 +++++++++++++++++++
lldb/test/API/commands/breakpoint/dot/main.c | 4 ++
9 files changed, 117 insertions(+), 23 deletions(-)
create mode 100644 lldb/test/API/commands/breakpoint/dot/Makefile
create mode 100644 lldb/test/API/commands/breakpoint/dot/TestBreakpointDot.py
create mode 100644 lldb/test/API/commands/breakpoint/dot/main.c
diff --git a/lldb/include/lldb/Breakpoint/BreakpointIDList.h b/lldb/include/lldb/Breakpoint/BreakpointIDList.h
index f2eaa60d95413..d361208c08164 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointIDList.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointIDList.h
@@ -51,7 +51,8 @@ class BreakpointIDList {
SplitIDRangeExpression(llvm::StringRef in_string);
static llvm::Error
- FindAndReplaceIDRanges(Args &old_args, Target *target, bool allow_locations,
+ FindAndReplaceIDRanges(Args &old_args, ExecutionContext &exe_ctx,
+ bool allow_locations,
BreakpointName::Permissions ::PermissionKinds purpose,
Args &new_args);
diff --git a/lldb/source/Breakpoint/BreakpointIDList.cpp b/lldb/source/Breakpoint/BreakpointIDList.cpp
index 8c46b39c02a9e..16f3616bca88a 100644
--- a/lldb/source/Breakpoint/BreakpointIDList.cpp
+++ b/lldb/source/Breakpoint/BreakpointIDList.cpp
@@ -11,9 +11,13 @@
#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/StreamString.h"
+#include "lldb/lldb-forward.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
@@ -55,6 +59,15 @@ bool BreakpointIDList::Contains(BreakpointID bp_id) const {
return llvm::is_contained(m_breakpoint_ids, bp_id);
}
+static std::string_view BreakpointIDForStop(StopInfoSP stop_info_sp,
+ uint32_t idx) {
+ break_id_t bp_id = stop_info_sp->GetStopReasonDataAtIndex(idx);
+ break_id_t loc_id = stop_info_sp->GetStopReasonDataAtIndex(idx + 1);
+ StreamString stream;
+ BreakpointID::GetCanonicalReference(&stream, bp_id, loc_id);
+ return stream.GetString();
+}
+
// This function takes OLD_ARGS, which is usually the result of breaking the
// command string arguments into
// an array of space-separated strings, and searches through the arguments for
@@ -69,8 +82,9 @@ bool BreakpointIDList::Contains(BreakpointID bp_id) const {
// by the members of the range.
llvm::Error BreakpointIDList::FindAndReplaceIDRanges(
- Args &old_args, Target *target, bool allow_locations,
+ Args &old_args, ExecutionContext &exe_ctx, bool allow_locations,
BreakpointName::Permissions ::PermissionKinds purpose, Args &new_args) {
+ Target *target = exe_ctx.GetTargetPtr();
llvm::StringRef range_from;
llvm::StringRef range_to;
llvm::StringRef current_arg;
@@ -80,6 +94,28 @@ llvm::Error BreakpointIDList::FindAndReplaceIDRanges(
bool is_range = false;
current_arg = old_args[i].ref();
+
+ if (current_arg == ".") {
+ Thread *thread = exe_ctx.GetThreadPtr();
+ if (!thread) {
+ new_args.Clear();
+ return llvm::createStringError("no current thread");
+ }
+ StopInfoSP stop_info_sp = thread->GetStopInfo();
+ if (!stop_info_sp ||
+ stop_info_sp->GetStopReason() != eStopReasonBreakpoint) {
+ new_args.Clear();
+ return llvm::createStringError(
+ "current thread is not stopped at a breakpoint.");
+ }
+
+ uint32_t data_count = stop_info_sp->GetStopReasonDataCount();
+ for (uint32_t j = 0; j < data_count; j += 2)
+ new_args.AppendArgument(BreakpointIDForStop(stop_info_sp, j));
+
+ continue;
+ }
+
if (!allow_locations && current_arg.contains('.')) {
new_args.Clear();
return llvm::createStringError(
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp
index 02ddb8aa5b4b3..bb71055ebb3cb 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.cpp
+++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp
@@ -2073,7 +2073,7 @@ class CommandObjectBreakpointModify : public CommandObjectParsed {
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids,
+ command, m_exe_ctx, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::disablePerm);
if (result.Succeeded()) {
@@ -2153,7 +2153,7 @@ class CommandObjectBreakpointEnable : public CommandObjectParsed {
// Particular breakpoint selected; enable that breakpoint.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids,
+ command, m_exe_ctx, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::disablePerm);
if (result.Succeeded()) {
@@ -2261,7 +2261,7 @@ the second re-enables the first location.");
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids,
+ command, m_exe_ctx, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::disablePerm);
if (result.Succeeded()) {
@@ -2406,7 +2406,7 @@ class CommandObjectBreakpointList : public CommandObjectParsed {
// Particular breakpoints selected; show info about that breakpoint.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids,
+ command, m_exe_ctx, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::listPerm);
if (result.Succeeded()) {
@@ -2685,7 +2685,7 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed {
if (!command.empty()) {
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &excluded_bp_ids,
+ command, m_exe_ctx, result, &excluded_bp_ids,
BreakpointName::Permissions::PermissionKinds::deletePerm);
if (!result.Succeeded())
return;
@@ -2704,7 +2704,7 @@ class CommandObjectBreakpointDelete : public CommandObjectParsed {
}
} else {
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids,
+ command, m_exe_ctx, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::deletePerm);
if (!result.Succeeded())
return;
@@ -3015,7 +3015,7 @@ class CommandObjectBreakpointNameAdd : public CommandObjectParsed {
// Particular breakpoint selected; disable that breakpoint.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
- command, target, result, &valid_bp_ids,
+ command, m_exe_ctx, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::listPerm);
if (result.Succeeded()) {
@@ -3089,7 +3089,7 @@ class CommandObjectBreakpointNameDelete : public CommandObjectParsed {
// Particular breakpoint selected; disable that breakpoint.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
- command, target, result, &valid_bp_ids,
+ command, m_exe_ctx, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::deletePerm);
if (result.Succeeded()) {
@@ -3562,7 +3562,7 @@ class CommandObjectBreakpointWrite : public CommandObjectParsed {
BreakpointIDList valid_bp_ids;
if (!command.empty()) {
CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs(
- command, target, result, &valid_bp_ids,
+ command, m_exe_ctx, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::listPerm);
if (!result.Succeeded()) {
@@ -3648,7 +3648,7 @@ CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint(
CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint() = default;
void CommandObjectMultiwordBreakpoint::VerifyIDs(
- Args &args, Target &target, bool allow_locations,
+ Args &args, ExecutionContext &exe_ctx, bool allow_locations,
CommandReturnObject &result, BreakpointIDList *valid_ids,
BreakpointName::Permissions ::PermissionKinds purpose) {
// args can be strings representing 1). integers (for breakpoint ids)
@@ -3662,6 +3662,7 @@ void CommandObjectMultiwordBreakpoint::VerifyIDs(
// If args is empty, we will use the last created breakpoint (if there is
// one.)
+ Target &target = exe_ctx.GetTargetRef();
Args temp_args;
if (args.empty()) {
@@ -3683,7 +3684,7 @@ void CommandObjectMultiwordBreakpoint::VerifyIDs(
// into TEMP_ARGS.
if (llvm::Error err = BreakpointIDList::FindAndReplaceIDRanges(
- args, &target, allow_locations, purpose, temp_args)) {
+ args, exe_ctx, allow_locations, purpose, temp_args)) {
result.SetError(std::move(err));
return;
}
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.h b/lldb/source/Commands/CommandObjectBreakpoint.h
index 40c67157e07c4..eaee254e0079f 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.h
+++ b/lldb/source/Commands/CommandObjectBreakpoint.h
@@ -23,22 +23,23 @@ class CommandObjectMultiwordBreakpoint : public CommandObjectMultiword {
~CommandObjectMultiwordBreakpoint() override;
static void VerifyBreakpointOrLocationIDs(
- Args &args, Target &target, CommandReturnObject &result,
+ Args &args, ExecutionContext &exe_ctx, CommandReturnObject &result,
BreakpointIDList *valid_ids,
BreakpointName::Permissions ::PermissionKinds purpose) {
- VerifyIDs(args, target, true, result, valid_ids, purpose);
+ VerifyIDs(args, exe_ctx, true, result, valid_ids, purpose);
}
static void
- VerifyBreakpointIDs(Args &args, Target &target, CommandReturnObject &result,
+ VerifyBreakpointIDs(Args &args, ExecutionContext &exe_ctx,
+ CommandReturnObject &result,
BreakpointIDList *valid_ids,
BreakpointName::Permissions::PermissionKinds purpose) {
- VerifyIDs(args, target, false, result, valid_ids, purpose);
+ VerifyIDs(args, exe_ctx, false, result, valid_ids, purpose);
}
private:
- static void VerifyIDs(Args &args, Target &target, bool allow_locations,
- CommandReturnObject &result,
+ static void VerifyIDs(Args &args, ExecutionContext &exe_ctx,
+ bool allow_locations, CommandReturnObject &result,
BreakpointIDList *valid_ids,
BreakpointName::Permissions::PermissionKinds purpose);
};
diff --git a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
index f9110d23042d5..03ca1e3e87748 100644
--- a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
+++ b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
@@ -344,7 +344,7 @@ are no syntax errors may indicate that a function was declared but never called.
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids,
+ command, m_exe_ctx, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::listPerm);
m_bp_options_vec.clear();
@@ -500,7 +500,7 @@ class CommandObjectBreakpointCommandDelete : public CommandObjectParsed {
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids,
+ command, m_exe_ctx, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::listPerm);
if (result.Succeeded()) {
@@ -567,7 +567,7 @@ class CommandObjectBreakpointCommandList : public CommandObjectParsed {
BreakpointIDList valid_bp_ids;
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- command, target, result, &valid_bp_ids,
+ command, m_exe_ctx, result, &valid_bp_ids,
BreakpointName::Permissions::PermissionKinds::listPerm);
if (result.Succeeded()) {
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp
index 32a2b32f294b2..e4ce38eea2ebb 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -533,7 +533,7 @@ class CommandObjectProcessContinue : public CommandObjectParsed {
// default breakpoint.
if (m_options.m_run_to_bkpt_args.GetArgumentCount() > 0)
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
- m_options.m_run_to_bkpt_args, target, result, &run_to_bkpt_ids,
+ m_options.m_run_to_bkpt_args, m_exe_ctx, result, &run_to_bkpt_ids,
BreakpointName::Permissions::disablePerm);
if (!result.Succeeded()) {
return;
diff --git a/lldb/test/API/commands/breakpoint/dot/Makefile b/lldb/test/API/commands/breakpoint/dot/Makefile
new file mode 100644
index 0000000000000..10495940055b6
--- /dev/null
+++ b/lldb/test/API/commands/breakpoint/dot/Makefile
@@ -0,0 +1,3 @@
+C_SOURCES := main.c
+
+include Makefile.rules
diff --git a/lldb/test/API/commands/breakpoint/dot/TestBreakpointDot.py b/lldb/test/API/commands/breakpoint/dot/TestBreakpointDot.py
new file mode 100644
index 0000000000000..2bc53963fdc36
--- /dev/null
+++ b/lldb/test/API/commands/breakpoint/dot/TestBreakpointDot.py
@@ -0,0 +1,48 @@
+"""Test breakpoint '.' ID - the current stopped breakpoint."""
+
+import lldb
+from lldbsuite.test.lldbtest import TestBase
+from lldbsuite.test import lldbutil
+
+
+class TestCase(TestBase):
+ def test_disable(self):
+ self.build()
+ _, _, _, bp = lldbutil.run_to_source_breakpoint(
+ self, "break here", lldb.SBFileSpec("main.c")
+ )
+
+ self.assertTrue(bp.FindLocationByID(1).IsEnabled())
+ self.expect("breakpoint disable .", startstr="1 breakpoints disabled.")
+ self.assertFalse(bp.FindLocationByID(1).IsEnabled())
+
+ def test_enable(self):
+ self.build()
+ _, _, _, bp = lldbutil.run_to_source_breakpoint(
+ self, "break here", lldb.SBFileSpec("main.c")
+ )
+
+ bp.FindLocationByID(1).SetEnabled(False)
+ self.assertFalse(bp.FindLocationByID(1).IsEnabled())
+ self.expect("breakpoint enable .", startstr="1 breakpoints enabled.")
+ self.assertTrue(bp.FindLocationByID(1).IsEnabled())
+
+ def test_delete(self):
+ self.build()
+ _, _, _, bp = lldbutil.run_to_source_breakpoint(
+ self, "break here", lldb.SBFileSpec("main.c")
+ )
+
+ self.expect(
+ "breakpoint delete .",
+ startstr="0 breakpoints deleted; 1 breakpoint locations disabled",
+ )
+ self.assertFalse(bp.FindLocationByID(1).IsEnabled())
+
+ def test_error_no_process(self):
+ self.build()
+ target = self.createTestTarget()
+ target.BreakpointCreateByLocation("main.c", 2)
+ self.expect(
+ "breakpoint disable .", error=True, substrs=["no current thread"]
+ )
diff --git a/lldb/test/API/commands/breakpoint/dot/main.c b/lldb/test/API/commands/breakpoint/dot/main.c
new file mode 100644
index 0000000000000..51083e9c9bac6
--- /dev/null
+++ b/lldb/test/API/commands/breakpoint/dot/main.c
@@ -0,0 +1,4 @@
+int main() {
+ int x = 1; // break here
+ return x;
+}
>From 60ade547b2cef667943784c9f4215a046c238db5 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Sun, 26 Apr 2026 16:39:32 -0700
Subject: [PATCH 2/7] formatting
---
lldb/include/lldb/Breakpoint/BreakpointIDList.h | 8 +++-----
lldb/source/Commands/CommandObjectBreakpoint.h | 3 +--
.../test/API/commands/breakpoint/dot/TestBreakpointDot.py | 4 +---
3 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/lldb/include/lldb/Breakpoint/BreakpointIDList.h b/lldb/include/lldb/Breakpoint/BreakpointIDList.h
index d361208c08164..3354a3a24893a 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointIDList.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointIDList.h
@@ -50,11 +50,9 @@ class BreakpointIDList {
static std::pair<llvm::StringRef, llvm::StringRef>
SplitIDRangeExpression(llvm::StringRef in_string);
- static llvm::Error
- FindAndReplaceIDRanges(Args &old_args, ExecutionContext &exe_ctx,
- bool allow_locations,
- BreakpointName::Permissions ::PermissionKinds purpose,
- Args &new_args);
+ static llvm::Error FindAndReplaceIDRanges(
+ Args &old_args, ExecutionContext &exe_ctx, bool allow_locations,
+ BreakpointName::Permissions ::PermissionKinds purpose, Args &new_args);
private:
BreakpointIDArray m_breakpoint_ids;
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.h b/lldb/source/Commands/CommandObjectBreakpoint.h
index eaee254e0079f..7e2fa045eb744 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.h
+++ b/lldb/source/Commands/CommandObjectBreakpoint.h
@@ -31,8 +31,7 @@ class CommandObjectMultiwordBreakpoint : public CommandObjectMultiword {
static void
VerifyBreakpointIDs(Args &args, ExecutionContext &exe_ctx,
- CommandReturnObject &result,
- BreakpointIDList *valid_ids,
+ CommandReturnObject &result, BreakpointIDList *valid_ids,
BreakpointName::Permissions::PermissionKinds purpose) {
VerifyIDs(args, exe_ctx, false, result, valid_ids, purpose);
}
diff --git a/lldb/test/API/commands/breakpoint/dot/TestBreakpointDot.py b/lldb/test/API/commands/breakpoint/dot/TestBreakpointDot.py
index 2bc53963fdc36..7bc2104961010 100644
--- a/lldb/test/API/commands/breakpoint/dot/TestBreakpointDot.py
+++ b/lldb/test/API/commands/breakpoint/dot/TestBreakpointDot.py
@@ -43,6 +43,4 @@ def test_error_no_process(self):
self.build()
target = self.createTestTarget()
target.BreakpointCreateByLocation("main.c", 2)
- self.expect(
- "breakpoint disable .", error=True, substrs=["no current thread"]
- )
+ self.expect("breakpoint disable .", error=True, substrs=["no current thread"])
>From b081f4311630d4488fa29989cbb89bf6bbcc6d47 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Mon, 27 Apr 2026 07:39:11 -0700
Subject: [PATCH 3/7] Update breakpt-id help text
---
lldb/source/Commands/CommandOptionArgumentTable.cpp | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lldb/source/Commands/CommandOptionArgumentTable.cpp b/lldb/source/Commands/CommandOptionArgumentTable.cpp
index e8e9307b62919..2af9e544e43de 100644
--- a/lldb/source/Commands/CommandOptionArgumentTable.cpp
+++ b/lldb/source/Commands/CommandOptionArgumentTable.cpp
@@ -49,7 +49,10 @@ llvm::StringRef BreakpointIDHelpTextCallback() {
"major "
"number, or the major number followed by a dot and the location "
"number (e.g. "
- "3 or 3.2 could both be valid breakpoint IDs.)";
+ "3 or 3.2 could both be valid breakpoint IDs.)\n"
+ "\n"
+ "You can use . to refer to the breakpoint location(s) on which the "
+ "process is currently stopped.";
}
llvm::StringRef BreakpointIDRangeHelpTextCallback() {
>From d1d7a690b8e6c8d16bee301f02db78976361a8ca Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Mon, 27 Apr 2026 08:19:58 -0700
Subject: [PATCH 4/7] remove full stop from error string
---
lldb/source/Breakpoint/BreakpointIDList.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lldb/source/Breakpoint/BreakpointIDList.cpp b/lldb/source/Breakpoint/BreakpointIDList.cpp
index 16f3616bca88a..9311e6716295f 100644
--- a/lldb/source/Breakpoint/BreakpointIDList.cpp
+++ b/lldb/source/Breakpoint/BreakpointIDList.cpp
@@ -106,7 +106,7 @@ llvm::Error BreakpointIDList::FindAndReplaceIDRanges(
stop_info_sp->GetStopReason() != eStopReasonBreakpoint) {
new_args.Clear();
return llvm::createStringError(
- "current thread is not stopped at a breakpoint.");
+ "current thread is not stopped at a breakpoint");
}
uint32_t data_count = stop_info_sp->GetStopReasonDataCount();
>From 3802f7b6b268fcab6866369c18e4f5b496e19710 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Mon, 27 Apr 2026 08:27:42 -0700
Subject: [PATCH 5/7] Add test for non-breakpoint stop
---
.../commands/breakpoint/dot/TestBreakpointDot.py | 16 ++++++++++++++++
lldb/test/API/commands/breakpoint/dot/main.c | 3 ++-
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/lldb/test/API/commands/breakpoint/dot/TestBreakpointDot.py b/lldb/test/API/commands/breakpoint/dot/TestBreakpointDot.py
index 7bc2104961010..42e688b7858f6 100644
--- a/lldb/test/API/commands/breakpoint/dot/TestBreakpointDot.py
+++ b/lldb/test/API/commands/breakpoint/dot/TestBreakpointDot.py
@@ -39,6 +39,22 @@ def test_delete(self):
)
self.assertFalse(bp.FindLocationByID(1).IsEnabled())
+ def test_error_not_breakpoint_stop(self):
+ self.build()
+ _, _, thread, bp = lldbutil.run_to_source_breakpoint(
+ self, "break here", lldb.SBFileSpec("main.c")
+ )
+
+ self.assertTrue(bp.FindLocationByID(1).IsEnabled())
+ thread.StepOver()
+ self.assertNotEqual(thread.stop_reason, lldb.eStopReasonBreakpoint)
+ self.expect(
+ "breakpoint disable .",
+ error=True,
+ startstr="error: current thread is not stopped at a breakpoint",
+ )
+ self.assertTrue(bp.FindLocationByID(1).IsEnabled())
+
def test_error_no_process(self):
self.build()
target = self.createTestTarget()
diff --git a/lldb/test/API/commands/breakpoint/dot/main.c b/lldb/test/API/commands/breakpoint/dot/main.c
index 51083e9c9bac6..f4a494dd4bc25 100644
--- a/lldb/test/API/commands/breakpoint/dot/main.c
+++ b/lldb/test/API/commands/breakpoint/dot/main.c
@@ -1,4 +1,5 @@
int main() {
int x = 1; // break here
- return x;
+ int y = 2;
+ return x + y;
}
>From 7f598d2592d8d2e370214bddd9d5d02acac1cef8 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Tue, 28 Apr 2026 12:16:05 -0700
Subject: [PATCH 6/7] Location . fine tuning
---
lldb/source/Breakpoint/BreakpointIDList.cpp | 13 +++++++------
lldb/source/Commands/CommandOptionArgumentTable.cpp | 4 ++--
.../commands/breakpoint/dot/TestBreakpointDot.py | 12 ++----------
3 files changed, 11 insertions(+), 18 deletions(-)
diff --git a/lldb/source/Breakpoint/BreakpointIDList.cpp b/lldb/source/Breakpoint/BreakpointIDList.cpp
index 9311e6716295f..ef987abe13bb2 100644
--- a/lldb/source/Breakpoint/BreakpointIDList.cpp
+++ b/lldb/source/Breakpoint/BreakpointIDList.cpp
@@ -59,13 +59,12 @@ bool BreakpointIDList::Contains(BreakpointID bp_id) const {
return llvm::is_contained(m_breakpoint_ids, bp_id);
}
-static std::string_view BreakpointIDForStop(StopInfoSP stop_info_sp,
- uint32_t idx) {
+static std::string LocationIDForStop(StopInfoSP stop_info_sp, uint32_t idx) {
break_id_t bp_id = stop_info_sp->GetStopReasonDataAtIndex(idx);
break_id_t loc_id = stop_info_sp->GetStopReasonDataAtIndex(idx + 1);
StreamString stream;
BreakpointID::GetCanonicalReference(&stream, bp_id, loc_id);
- return stream.GetString();
+ return stream.GetString().str();
}
// This function takes OLD_ARGS, which is usually the result of breaking the
@@ -95,7 +94,7 @@ llvm::Error BreakpointIDList::FindAndReplaceIDRanges(
current_arg = old_args[i].ref();
- if (current_arg == ".") {
+ if (allow_locations && current_arg == ".") {
Thread *thread = exe_ctx.GetThreadPtr();
if (!thread) {
new_args.Clear();
@@ -110,8 +109,10 @@ llvm::Error BreakpointIDList::FindAndReplaceIDRanges(
}
uint32_t data_count = stop_info_sp->GetStopReasonDataCount();
- for (uint32_t j = 0; j < data_count; j += 2)
- new_args.AppendArgument(BreakpointIDForStop(stop_info_sp, j));
+ for (uint32_t j = 0; j < data_count; j += 2) {
+ std::string location_id = LocationIDForStop(stop_info_sp, j);
+ new_args.AppendArgument(location_id);
+ }
continue;
}
diff --git a/lldb/source/Commands/CommandOptionArgumentTable.cpp b/lldb/source/Commands/CommandOptionArgumentTable.cpp
index 2af9e544e43de..4d267ba111e16 100644
--- a/lldb/source/Commands/CommandOptionArgumentTable.cpp
+++ b/lldb/source/Commands/CommandOptionArgumentTable.cpp
@@ -51,8 +51,8 @@ llvm::StringRef BreakpointIDHelpTextCallback() {
"number (e.g. "
"3 or 3.2 could both be valid breakpoint IDs.)\n"
"\n"
- "You can use . to refer to the breakpoint location(s) on which the "
- "process is currently stopped.";
+ "You can use . to refer to the breakpoint location(s) at which the "
+ "current thread is stopped.";
}
llvm::StringRef BreakpointIDRangeHelpTextCallback() {
diff --git a/lldb/test/API/commands/breakpoint/dot/TestBreakpointDot.py b/lldb/test/API/commands/breakpoint/dot/TestBreakpointDot.py
index 42e688b7858f6..5370372aaf220 100644
--- a/lldb/test/API/commands/breakpoint/dot/TestBreakpointDot.py
+++ b/lldb/test/API/commands/breakpoint/dot/TestBreakpointDot.py
@@ -6,7 +6,8 @@
class TestCase(TestBase):
- def test_disable(self):
+
+ def test_disable_enable(self):
self.build()
_, _, _, bp = lldbutil.run_to_source_breakpoint(
self, "break here", lldb.SBFileSpec("main.c")
@@ -15,15 +16,6 @@ def test_disable(self):
self.assertTrue(bp.FindLocationByID(1).IsEnabled())
self.expect("breakpoint disable .", startstr="1 breakpoints disabled.")
self.assertFalse(bp.FindLocationByID(1).IsEnabled())
-
- def test_enable(self):
- self.build()
- _, _, _, bp = lldbutil.run_to_source_breakpoint(
- self, "break here", lldb.SBFileSpec("main.c")
- )
-
- bp.FindLocationByID(1).SetEnabled(False)
- self.assertFalse(bp.FindLocationByID(1).IsEnabled())
self.expect("breakpoint enable .", startstr="1 breakpoints enabled.")
self.assertTrue(bp.FindLocationByID(1).IsEnabled())
>From c8fefdbda8344d7e13fbdf7b10ef70fde98fd836 Mon Sep 17 00:00:00 2001
From: Dave Lee <davelee.com at gmail.com>
Date: Tue, 28 Apr 2026 12:22:30 -0700
Subject: [PATCH 7/7] Rename tests
---
lldb/test/API/commands/breakpoint/{dot => location-dot}/Makefile | 0
.../TestBreakpointLocationDot.py} | 0
lldb/test/API/commands/breakpoint/{dot => location-dot}/main.c | 0
3 files changed, 0 insertions(+), 0 deletions(-)
rename lldb/test/API/commands/breakpoint/{dot => location-dot}/Makefile (100%)
rename lldb/test/API/commands/breakpoint/{dot/TestBreakpointDot.py => location-dot/TestBreakpointLocationDot.py} (100%)
rename lldb/test/API/commands/breakpoint/{dot => location-dot}/main.c (100%)
diff --git a/lldb/test/API/commands/breakpoint/dot/Makefile b/lldb/test/API/commands/breakpoint/location-dot/Makefile
similarity index 100%
rename from lldb/test/API/commands/breakpoint/dot/Makefile
rename to lldb/test/API/commands/breakpoint/location-dot/Makefile
diff --git a/lldb/test/API/commands/breakpoint/dot/TestBreakpointDot.py b/lldb/test/API/commands/breakpoint/location-dot/TestBreakpointLocationDot.py
similarity index 100%
rename from lldb/test/API/commands/breakpoint/dot/TestBreakpointDot.py
rename to lldb/test/API/commands/breakpoint/location-dot/TestBreakpointLocationDot.py
diff --git a/lldb/test/API/commands/breakpoint/dot/main.c b/lldb/test/API/commands/breakpoint/location-dot/main.c
similarity index 100%
rename from lldb/test/API/commands/breakpoint/dot/main.c
rename to lldb/test/API/commands/breakpoint/location-dot/main.c
More information about the lldb-commits
mailing list