[Lldb-commits] [lldb] c8b02ba - [lldb][test] Expand blocks test (#208406)
via lldb-commits
lldb-commits at lists.llvm.org
Fri Jul 10 07:34:05 PDT 2026
Author: Raphael Isemann
Date: 2026-07-10T15:34:00+01:00
New Revision: c8b02ba5ac7a37c4fa0100431b357da74f1b200f
URL: https://github.com/llvm/llvm-project/commit/c8b02ba5ac7a37c4fa0100431b357da74f1b200f
DIFF: https://github.com/llvm/llvm-project/commit/c8b02ba5ac7a37c4fa0100431b357da74f1b200f.diff
LOG: [lldb][test] Expand blocks test (#208406)
This moves some of the tested logic from the `types/` test that is about
to be deleted to the already existing c/blocks test.
See also #208402
assisted-by: claude
Added:
Modified:
lldb/test/API/lang/c/blocks/TestBlocks.py
lldb/test/API/lang/c/blocks/main.c
Removed:
################################################################################
diff --git a/lldb/test/API/lang/c/blocks/TestBlocks.py b/lldb/test/API/lang/c/blocks/TestBlocks.py
index 00714d003c10c..f16e35a09adcf 100644
--- a/lldb/test/API/lang/c/blocks/TestBlocks.py
+++ b/lldb/test/API/lang/c/blocks/TestBlocks.py
@@ -1,5 +1,4 @@
-"""Test that lldb can invoke blocks and access variables inside them"""
-
+"""Test that lldb can invoke blocks and read variables captured by blocks."""
import lldb
from lldbsuite.test.lldbtest import *
@@ -9,78 +8,68 @@
@skipIfWasm # no expression evaluation
class BlocksTestCase(TestBase):
- lines = []
-
- def setUp(self):
- # Call super's setUp().
- TestBase.setUp(self)
- # Find the line numbers to break at.
- self.lines.append(line_number("main.c", "// Set breakpoint 0 here."))
- self.lines.append(line_number("main.c", "// Set breakpoint 1 here."))
- self.lines.append(line_number("main.c", "// Set breakpoint 2 here."))
-
- def launch_common(self):
- self.build()
- exe = self.getBuildArtifact("a.out")
- self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
-
- self.is_started = False
-
- # Break inside the foo function which takes a bar_ptr argument.
- for line in self.lines:
- lldbutil.run_break_set_by_file_and_line(
- self, "main.c", line, num_expected_locations=1, loc_exact=True
- )
-
- self.wait_for_breakpoint()
-
@skipUnlessDarwin
- def test_expr(self):
- self.launch_common()
-
- self.expect("expression a + b", VARIABLES_DISPLAYED_CORRECTLY, substrs=["= 7"])
-
- self.expect("expression c", VARIABLES_DISPLAYED_CORRECTLY, substrs=["= 1"])
+ def test(self):
+ self.build()
+ src = lldb.SBFileSpec("main.c")
+ _, process, _, _ = lldbutil.run_to_source_breakpoint(
+ self, "Set breakpoint 0 here.", src
+ )
- self.wait_for_breakpoint()
+ # Inside the 'add' block we can read its arguments and the captured
+ # variable 'c'.
+ self.expect_expr("a + b", result_type="int", result_value="7")
+ self.expect_expr("c", result_type="int", result_value="1")
- # This should display correctly.
- self.expect(
- "expression (int)neg (-12)", VARIABLES_DISPLAYED_CORRECTLY, substrs=["= 12"]
+ # Calling a block from the expression evaluator works.
+ lldbutil.continue_to_source_breakpoint(
+ self, process, "Set breakpoint 1 here.", src
)
+ self.expect_expr("(int)neg(-12)", result_type="int", result_value="12")
- self.wait_for_breakpoint()
-
+ # A block taking a struct argument can be called from the evaluator.
+ lldbutil.continue_to_source_breakpoint(
+ self, process, "Set breakpoint 2 here.", src
+ )
self.expect_expr("h(cg)", result_type="int", result_value="42")
+ # Inside a block we can read captured variables of various types.
+ lldbutil.continue_to_source_breakpoint(
+ self, process, "Set breakpoint 3 here.", src
+ )
+ self.expect_var_path("captured_char", type="char", value="'a'")
+ self.expect_var_path("captured_int", type="int", value="42")
+ self.expect_var_path("captured_double", type="double", value="3.5")
+ self.expect_var_path("*captured_ptr", type="int", value="42")
+ self.expect_var_path("captured_struct.x", type="int", value="10")
+ self.expect_var_path("captured_struct.y", type="int", value="20")
+
+ # The same captured variables are also reachable from the expression
+ # evaluator.
+ self.expect_expr("captured_char", result_type="char", result_value="'a'")
+ self.expect_expr("captured_int", result_type="int", result_value="42")
+ self.expect_expr("captured_double", result_type="double", result_value="3.5")
+ self.expect_expr("*captured_ptr", result_type="int", result_value="42")
+ self.expect_expr("captured_struct.x", result_type="int", result_value="10")
+
@skipUnlessDarwin
def test_define(self):
- self.launch_common()
+ """Test defining and calling a block from the expression evaluator."""
+ self.build()
+ lldbutil.run_to_source_breakpoint(
+ self, "Set breakpoint 0 here.", lldb.SBFileSpec("main.c")
+ )
self.runCmd(
"expression int (^$add)(int, int) = ^int(int a, int b) { return a + b; };"
)
- self.expect(
- "expression $add(2,3)", VARIABLES_DISPLAYED_CORRECTLY, substrs=[" = 5"]
- )
+ self.expect_expr("$add(2,3)", result_type="int", result_value="5")
+ # Blocks defined in the expression evaluator cannot capture persistent
+ # variables.
self.runCmd("expression int $a = 3")
self.expect(
"expression int (^$addA)(int) = ^int(int b) { return $a + b; };",
"Proper error is reported on capture",
error=True,
)
-
- def wait_for_breakpoint(self):
- if not self.is_started:
- self.is_started = True
- self.runCmd("process launch", RUN_SUCCEEDED)
- else:
- self.runCmd("process continue", RUN_SUCCEEDED)
-
- # The stop reason of the thread should be breakpoint.
- self.expect(
- "thread list",
- STOPPED_DUE_TO_BREAKPOINT,
- substrs=["stopped", "stop reason = breakpoint"],
- )
diff --git a/lldb/test/API/lang/c/blocks/main.c b/lldb/test/API/lang/c/blocks/main.c
index b1b215ec2331b..6b487ddb44d8e 100644
--- a/lldb/test/API/lang/c/blocks/main.c
+++ b/lldb/test/API/lang/c/blocks/main.c
@@ -1,40 +1,52 @@
-#include <stdio.h>
-
-struct CG {int x; int y;};
+struct CG {
+ int x;
+ int y;
+};
int g(int (^callback)(struct CG)) {
- struct CG cg = {.x=1,.y=2};
+ struct CG cg = {.x = 1, .y = 2};
- int z = callback(cg); // Set breakpoint 2 here.
+ int z = callback(cg); // Set breakpoint 2 here.
- return z;
+ return z;
}
-int h(struct CG cg){return 42;}
+int h(struct CG cg) { return 42; }
+
+int main() {
+ int c = 1;
+
+ int (^add)(int, int) = ^int(int a, int b) {
+ return a + b + c; // Set breakpoint 0 here.
+ };
+
+ int (^neg)(int) = ^int(int a) {
+ return -a;
+ };
-int main()
-{
- int c = 1;
+ int sum = add(3, 4);
+ int negated = neg(-5); // Set breakpoint 1 here.
- int (^add)(int, int) = ^int(int a, int b)
- {
- return a + b + c; // Set breakpoint 0 here.
- };
+ int (^add_struct)(struct CG) = ^int(struct CG cg) {
+ return cg.x + cg.y;
+ };
- int (^neg)(int) = ^int(int a)
- {
- return -a;
- };
+ g(add_struct);
- printf("%d\n", add(3, 4));
- printf("%d\n", neg(-5)); // Set breakpoint 1 here.
+ // A block that captures variables of several
diff erent types so we can check
+ // that lldb reads captured variables of each type correctly.
+ char captured_char = 'a';
+ int captured_int = 42;
+ double captured_double = 3.5;
+ int *captured_ptr = &captured_int;
+ struct CG captured_struct = {.x = 10, .y = 20};
- int (^add_struct)(struct CG) = ^int(struct CG cg)
- {
- return cg.x + cg.y;
- };
+ int (^types_block)() = ^int() {
+ return captured_char + captured_int + (int)captured_double + *captured_ptr +
+ captured_struct.x; // Set breakpoint 3 here.
+ };
- g(add_struct);
+ int result = types_block();
- return 0;
+ return sum + negated + result;
}
More information about the lldb-commits
mailing list