https://github.com/ashgti updated https://github.com/llvm/llvm-project/pull/184222
>From 0e4436f7ef573e456a9eda568eb9515ab348317e Mon Sep 17 00:00:00 2001 From: John Harrison <[email protected]> Date: Mon, 2 Mar 2026 11:57:20 -0800 Subject: [PATCH 1/5] [lldb] Expose block id in SBBlock. Exposing the block id in SBBlock. You can indirectly access this with 'GetDescription' but this should be more consistent. Additionally adding the `operator==` and `operator!=` for SBBlock. This should allow us to uniquely identify blocks in a SBFunction/SBFrame for a refactor to lldb-dap scope handling. --- lldb/include/lldb/API/SBBlock.h | 7 +++++++ lldb/source/API/SBBlock.cpp | 29 ++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/lldb/include/lldb/API/SBBlock.h b/lldb/include/lldb/API/SBBlock.h index de4bb22be2692..ab9918c9eb6fa 100644 --- a/lldb/include/lldb/API/SBBlock.h +++ b/lldb/include/lldb/API/SBBlock.h @@ -15,6 +15,7 @@ #include "lldb/API/SBFrame.h" #include "lldb/API/SBTarget.h" #include "lldb/API/SBValueList.h" +#include "lldb/lldb-types.h" namespace lldb { @@ -32,8 +33,14 @@ class LLDB_API SBBlock { explicit operator bool() const; + bool operator==(const lldb::SBBlock &rhs) const; + + bool operator!=(const lldb::SBBlock &rhs) const; + bool IsValid() const; + lldb::user_id_t GetID() const; + const char *GetInlinedName() const; lldb::SBFileSpec GetInlinedCallSiteFile() const; diff --git a/lldb/source/API/SBBlock.cpp b/lldb/source/API/SBBlock.cpp index 2ef4cc7227cf9..881ce961ec4f6 100644 --- a/lldb/source/API/SBBlock.cpp +++ b/lldb/source/API/SBBlock.cpp @@ -1,4 +1,4 @@ -//===-- SBBlock.cpp -------------------------------------------------------===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,10 +18,9 @@ #include "lldb/Symbol/Function.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/VariableList.h" -#include "lldb/Target/StackFrame.h" -#include "lldb/Target/Target.h" #include "lldb/Utility/Instrumentation.h" #include "lldb/ValueObject/ValueObjectVariable.h" +#include "lldb/lldb-types.h" using namespace lldb; using namespace lldb_private; @@ -54,6 +53,25 @@ SBBlock::operator bool() const { return m_opaque_ptr != nullptr; } +bool SBBlock::operator==(const SBBlock &rhs) const { + LLDB_INSTRUMENT_VA(this, rhs); + + return *m_opaque_ptr == *rhs.m_opaque_ptr; +} + +bool SBBlock::operator!=(const SBBlock &rhs) const { + LLDB_INSTRUMENT_VA(this, rhs); + + return *m_opaque_ptr != *rhs.m_opaque_ptr; +} + +user_id_t SBBlock::GetID() const { + LLDB_INSTRUMENT_VA(this); + if (m_opaque_ptr) + return m_opaque_ptr->GetID(); + return LLDB_INVALID_UID; +} + bool SBBlock::IsInlined() const { LLDB_INSTRUMENT_VA(this); @@ -116,8 +134,9 @@ void SBBlock::AppendVariables(bool can_create, bool get_parent_variables, lldb_private::VariableList *var_list) { if (IsValid()) { bool show_inline = true; - m_opaque_ptr->AppendVariables(can_create, get_parent_variables, show_inline, - [](Variable *) { return true; }, var_list); + m_opaque_ptr->AppendVariables( + can_create, get_parent_variables, show_inline, + [](Variable *) { return true; }, var_list); } } >From e276475b443d13a3a92ba16026a21e2bab2a5b02 Mon Sep 17 00:00:00 2001 From: John Harrison <[email protected]> Date: Tue, 3 Mar 2026 10:44:24 -0800 Subject: [PATCH 2/5] Creating unit tests and addressing a null ptr exception. --- lldb/source/API/SBBlock.cpp | 5 +- lldb/test/API/python_api/block/Makefile | 3 + lldb/test/API/python_api/block/TestBlocks.py | 68 ++++++++++++++++++++ lldb/test/API/python_api/block/main.c | 18 ++++++ 4 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 lldb/test/API/python_api/block/Makefile create mode 100644 lldb/test/API/python_api/block/TestBlocks.py create mode 100644 lldb/test/API/python_api/block/main.c diff --git a/lldb/source/API/SBBlock.cpp b/lldb/source/API/SBBlock.cpp index 881ce961ec4f6..759725b87e8cd 100644 --- a/lldb/source/API/SBBlock.cpp +++ b/lldb/source/API/SBBlock.cpp @@ -56,13 +56,14 @@ SBBlock::operator bool() const { bool SBBlock::operator==(const SBBlock &rhs) const { LLDB_INSTRUMENT_VA(this, rhs); - return *m_opaque_ptr == *rhs.m_opaque_ptr; + return m_opaque_ptr != nullptr && rhs.m_opaque_ptr != nullptr && + *m_opaque_ptr == *rhs.m_opaque_ptr; } bool SBBlock::operator!=(const SBBlock &rhs) const { LLDB_INSTRUMENT_VA(this, rhs); - return *m_opaque_ptr != *rhs.m_opaque_ptr; + return !(*this == rhs); } user_id_t SBBlock::GetID() const { diff --git a/lldb/test/API/python_api/block/Makefile b/lldb/test/API/python_api/block/Makefile new file mode 100644 index 0000000000000..10495940055b6 --- /dev/null +++ b/lldb/test/API/python_api/block/Makefile @@ -0,0 +1,3 @@ +C_SOURCES := main.c + +include Makefile.rules diff --git a/lldb/test/API/python_api/block/TestBlocks.py b/lldb/test/API/python_api/block/TestBlocks.py new file mode 100644 index 0000000000000..13ea26a284ea9 --- /dev/null +++ b/lldb/test/API/python_api/block/TestBlocks.py @@ -0,0 +1,68 @@ +""" +Use lldb Python SBBlock API to access specific scopes within a frame. +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + + +class BlockAPITestCase(TestBase): + def test_block_equality(self): + """Exercise SBBlock equality checks.""" + self.build() + exe = self.getBuildArtifact("a.out") + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + source = "main.c" + line1 = line_number(source, "// breakpoint 1") + line2 = line_number(source, "// breakpoint 2") + breakpoint1 = target.BreakpointCreateByLocation(source, line1) + breakpoint2 = target.BreakpointCreateByLocation(source, line2) + self.assertGreaterEqual(breakpoint1.GetNumLocations(), 1, PROCESS_IS_VALID) + self.assertGreaterEqual(breakpoint2.GetNumLocations(), 1, PROCESS_IS_VALID) + + # Now launch the process, and do not stop at the entry point. + process = target.LaunchSimple(None, None, self.get_process_working_directory()) + self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) + + threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint1) + self.assertEqual( + len(threads), 1, "There should be a thread stopped at breakpoint 1" + ) + + thread = threads[0] + self.assertTrue(thread.IsValid(), "Thread must be valid") + frame = thread.GetFrameAtIndex(0) + self.assertTrue(frame.IsValid(), "Frame must be valid") + + main_frame_block = frame.GetFrameBlock() + self.assertNotEqual(main_frame_block.GetID(), 0, "Invalid block id") + + # Continue to breakpoint 2 + process.Continue() + + threads = lldbutil.get_threads_stopped_at_breakpoint(process, breakpoint2) + self.assertEqual( + len(threads), 1, "There should be a thread stopped at breakpoint 2" + ) + + thread = threads[0] + self.assertTrue(thread.IsValid(), "Thread must be valid") + frame = thread.GetFrameAtIndex(0) + self.assertTrue(frame.IsValid(), "Frame must be valid") + + fn_frame_block = frame.GetFrameBlock() + self.assertNotEqual(fn_frame_block.GetID(), 0, "Invalid block id") + + fn_inner_block = frame.GetBlock() + self.assertNotEqual(fn_inner_block.GetID(), 0, "Invalid block id") + + # Check __eq__ / __ne__ + self.assertNotEqual(fn_inner_block, fn_frame_block) + self.assertNotEqual(main_frame_block, fn_frame_block) + self.assertEqual(fn_inner_block.GetParent(), fn_frame_block) diff --git a/lldb/test/API/python_api/block/main.c b/lldb/test/API/python_api/block/main.c new file mode 100644 index 0000000000000..4c7ac493877ec --- /dev/null +++ b/lldb/test/API/python_api/block/main.c @@ -0,0 +1,18 @@ +#include <stdio.h> + +int fn(int a, int b) { + if (a < b) { + int sum = a + b; + return sum; // breakpoint 2 + } + + return a * b; +} + +int main(int argc, char const *argv[]) { + int a = 3; + int b = 17; + int sum = fn(a, b); // breakpoint 1 + printf("fn(3, 17) returns %d\n", sum); + return 0; +} >From c144fd86af9154894f5faaa890686777db937c9d Mon Sep 17 00:00:00 2001 From: John Harrison <[email protected]> Date: Tue, 3 Mar 2026 10:48:24 -0800 Subject: [PATCH 3/5] Apply clang-format. --- lldb/test/API/python_api/block/main.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lldb/test/API/python_api/block/main.c b/lldb/test/API/python_api/block/main.c index 4c7ac493877ec..dca1fef5fb07a 100644 --- a/lldb/test/API/python_api/block/main.c +++ b/lldb/test/API/python_api/block/main.c @@ -1,18 +1,18 @@ #include <stdio.h> int fn(int a, int b) { - if (a < b) { - int sum = a + b; - return sum; // breakpoint 2 - } + if (a < b) { + int sum = a + b; + return sum; // breakpoint 2 + } - return a * b; + return a * b; } int main(int argc, char const *argv[]) { - int a = 3; - int b = 17; - int sum = fn(a, b); // breakpoint 1 - printf("fn(3, 17) returns %d\n", sum); - return 0; + int a = 3; + int b = 17; + int sum = fn(a, b); // breakpoint 1 + printf("fn(3, 17) returns %d\n", sum); + return 0; } >From 1b83018b18a7f318ee1fcc3185fb23de765b726d Mon Sep 17 00:00:00 2001 From: John Harrison <[email protected]> Date: Tue, 3 Mar 2026 13:44:42 -0800 Subject: [PATCH 4/5] Adjusting the SBBlock API to only expose an equality check, instead of GetID() since GetID() is not unique enough across object files. --- lldb/include/lldb/API/SBBlock.h | 2 -- lldb/source/API/SBBlock.cpp | 10 +++------- lldb/test/API/python_api/block/Makefile | 2 ++ lldb/test/API/python_api/block/TestBlocks.py | 13 ++++--------- lldb/test/API/python_api/block/fn.c | 8 ++++++++ lldb/test/API/python_api/block/main.c | 9 +-------- 6 files changed, 18 insertions(+), 26 deletions(-) create mode 100644 lldb/test/API/python_api/block/fn.c diff --git a/lldb/include/lldb/API/SBBlock.h b/lldb/include/lldb/API/SBBlock.h index ab9918c9eb6fa..153502a6f1122 100644 --- a/lldb/include/lldb/API/SBBlock.h +++ b/lldb/include/lldb/API/SBBlock.h @@ -39,8 +39,6 @@ class LLDB_API SBBlock { bool IsValid() const; - lldb::user_id_t GetID() const; - const char *GetInlinedName() const; lldb::SBFileSpec GetInlinedCallSiteFile() const; diff --git a/lldb/source/API/SBBlock.cpp b/lldb/source/API/SBBlock.cpp index 759725b87e8cd..f8d9ba4f5431b 100644 --- a/lldb/source/API/SBBlock.cpp +++ b/lldb/source/API/SBBlock.cpp @@ -57,6 +57,9 @@ bool SBBlock::operator==(const SBBlock &rhs) const { LLDB_INSTRUMENT_VA(this, rhs); return m_opaque_ptr != nullptr && rhs.m_opaque_ptr != nullptr && + m_opaque_ptr->GetFunction() == rhs.m_opaque_ptr->GetFunction() && + m_opaque_ptr->GetFunction().GetCompileUnit() == + rhs.m_opaque_ptr->GetFunction().GetCompileUnit() && *m_opaque_ptr == *rhs.m_opaque_ptr; } @@ -66,13 +69,6 @@ bool SBBlock::operator!=(const SBBlock &rhs) const { return !(*this == rhs); } -user_id_t SBBlock::GetID() const { - LLDB_INSTRUMENT_VA(this); - if (m_opaque_ptr) - return m_opaque_ptr->GetID(); - return LLDB_INVALID_UID; -} - bool SBBlock::IsInlined() const { LLDB_INSTRUMENT_VA(this); diff --git a/lldb/test/API/python_api/block/Makefile b/lldb/test/API/python_api/block/Makefile index 10495940055b6..19331dd4b3c59 100644 --- a/lldb/test/API/python_api/block/Makefile +++ b/lldb/test/API/python_api/block/Makefile @@ -1,3 +1,5 @@ C_SOURCES := main.c +DYLIB_NAME := fn +DYLIB_C_SOURCES := fn.c include Makefile.rules diff --git a/lldb/test/API/python_api/block/TestBlocks.py b/lldb/test/API/python_api/block/TestBlocks.py index 13ea26a284ea9..07811e30615a2 100644 --- a/lldb/test/API/python_api/block/TestBlocks.py +++ b/lldb/test/API/python_api/block/TestBlocks.py @@ -18,11 +18,10 @@ def test_block_equality(self): target = self.dbg.CreateTarget(exe) self.assertTrue(target, VALID_TARGET) - source = "main.c" - line1 = line_number(source, "// breakpoint 1") - line2 = line_number(source, "// breakpoint 2") - breakpoint1 = target.BreakpointCreateByLocation(source, line1) - breakpoint2 = target.BreakpointCreateByLocation(source, line2) + line1 = line_number("main.c", "// breakpoint 1") + line2 = line_number("fn.c", "// breakpoint 2") + breakpoint1 = target.BreakpointCreateByLocation("main.c", line1) + breakpoint2 = target.BreakpointCreateByLocation("fn.c", line2) self.assertGreaterEqual(breakpoint1.GetNumLocations(), 1, PROCESS_IS_VALID) self.assertGreaterEqual(breakpoint2.GetNumLocations(), 1, PROCESS_IS_VALID) @@ -41,7 +40,6 @@ def test_block_equality(self): self.assertTrue(frame.IsValid(), "Frame must be valid") main_frame_block = frame.GetFrameBlock() - self.assertNotEqual(main_frame_block.GetID(), 0, "Invalid block id") # Continue to breakpoint 2 process.Continue() @@ -57,10 +55,7 @@ def test_block_equality(self): self.assertTrue(frame.IsValid(), "Frame must be valid") fn_frame_block = frame.GetFrameBlock() - self.assertNotEqual(fn_frame_block.GetID(), 0, "Invalid block id") - fn_inner_block = frame.GetBlock() - self.assertNotEqual(fn_inner_block.GetID(), 0, "Invalid block id") # Check __eq__ / __ne__ self.assertNotEqual(fn_inner_block, fn_frame_block) diff --git a/lldb/test/API/python_api/block/fn.c b/lldb/test/API/python_api/block/fn.c new file mode 100644 index 0000000000000..80ea7e5baa11e --- /dev/null +++ b/lldb/test/API/python_api/block/fn.c @@ -0,0 +1,8 @@ +extern int fn(int a, int b) { + if (a < b) { + int sum = a + b; + return sum; // breakpoint 2 + } + + return a * b; +} diff --git a/lldb/test/API/python_api/block/main.c b/lldb/test/API/python_api/block/main.c index dca1fef5fb07a..8200ecf5bdf4f 100644 --- a/lldb/test/API/python_api/block/main.c +++ b/lldb/test/API/python_api/block/main.c @@ -1,13 +1,6 @@ #include <stdio.h> -int fn(int a, int b) { - if (a < b) { - int sum = a + b; - return sum; // breakpoint 2 - } - - return a * b; -} +extern int fn(int a, int b); int main(int argc, char const *argv[]) { int a = 3; >From 9a348ffb39ef323a1ea19275733e12862fe4a8a3 Mon Sep 17 00:00:00 2001 From: John Harrison <[email protected]> Date: Tue, 3 Mar 2026 14:02:24 -0800 Subject: [PATCH 5/5] Breakpoints should resolve later. --- lldb/test/API/python_api/block/TestBlocks.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/lldb/test/API/python_api/block/TestBlocks.py b/lldb/test/API/python_api/block/TestBlocks.py index 07811e30615a2..7d2759abf1578 100644 --- a/lldb/test/API/python_api/block/TestBlocks.py +++ b/lldb/test/API/python_api/block/TestBlocks.py @@ -22,8 +22,6 @@ def test_block_equality(self): line2 = line_number("fn.c", "// breakpoint 2") breakpoint1 = target.BreakpointCreateByLocation("main.c", line1) breakpoint2 = target.BreakpointCreateByLocation("fn.c", line2) - self.assertGreaterEqual(breakpoint1.GetNumLocations(), 1, PROCESS_IS_VALID) - self.assertGreaterEqual(breakpoint2.GetNumLocations(), 1, PROCESS_IS_VALID) # Now launch the process, and do not stop at the entry point. process = target.LaunchSimple(None, None, self.get_process_working_directory()) _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
