Skip to content

Commit

Permalink
[lldb-dap] Add Tests: Show children for return values
Browse files Browse the repository at this point in the history
  • Loading branch information
Da-Viper committed Feb 12, 2025
1 parent d50238b commit a5e336a
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 11 deletions.
57 changes: 46 additions & 11 deletions lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,9 +341,9 @@ def do_test_scopes_variables_setVariable_evaluate(

verify_locals["argc"]["equals"]["value"] = "123"
verify_locals["pt"]["children"]["x"]["equals"]["value"] = "111"
verify_locals["x @ main.cpp:17"] = {"equals": {"type": "int", "value": "89"}}
verify_locals["x @ main.cpp:19"] = {"equals": {"type": "int", "value": "42"}}
verify_locals["x @ main.cpp:21"] = {"equals": {"type": "int", "value": "72"}}
verify_locals["x @ main.cpp:19"] = {"equals": {"type": "int", "value": "89"}}
verify_locals["x @ main.cpp:21"] = {"equals": {"type": "int", "value": "42"}}
verify_locals["x @ main.cpp:23"] = {"equals": {"type": "int", "value": "72"}}

self.verify_variables(verify_locals, self.dap_server.get_local_variables())

Expand All @@ -353,32 +353,32 @@ def do_test_scopes_variables_setVariable_evaluate(
self.dap_server.request_setVariable(1, "x @ main.cpp:0", 9)["success"]
)

self.assertTrue(
self.dap_server.request_setVariable(1, "x @ main.cpp:17", 17)["success"]
)
self.assertTrue(
self.dap_server.request_setVariable(1, "x @ main.cpp:19", 19)["success"]
)
self.assertTrue(
self.dap_server.request_setVariable(1, "x @ main.cpp:21", 21)["success"]
)
self.assertTrue(
self.dap_server.request_setVariable(1, "x @ main.cpp:23", 23)["success"]
)

# The following should have no effect
self.assertFalse(
self.dap_server.request_setVariable(1, "x @ main.cpp:21", "invalid")[
self.dap_server.request_setVariable(1, "x @ main.cpp:23", "invalid")[
"success"
]
)

verify_locals["x @ main.cpp:17"]["equals"]["value"] = "17"
verify_locals["x @ main.cpp:19"]["equals"]["value"] = "19"
verify_locals["x @ main.cpp:21"]["equals"]["value"] = "21"
verify_locals["x @ main.cpp:23"]["equals"]["value"] = "23"

self.verify_variables(verify_locals, self.dap_server.get_local_variables())

# The plain x variable shold refer to the innermost x
self.assertTrue(self.dap_server.request_setVariable(1, "x", 22)["success"])
verify_locals["x @ main.cpp:21"]["equals"]["value"] = "22"
verify_locals["x @ main.cpp:23"]["equals"]["value"] = "22"

self.verify_variables(verify_locals, self.dap_server.get_local_variables())

Expand All @@ -394,10 +394,10 @@ def do_test_scopes_variables_setVariable_evaluate(
locals = self.dap_server.get_local_variables()
names = [var["name"] for var in locals]
# The first shadowed x shouldn't have a suffix anymore
verify_locals["x"] = {"equals": {"type": "int", "value": "17"}}
self.assertNotIn("x @ main.cpp:17", names)
verify_locals["x"] = {"equals": {"type": "int", "value": "19"}}
self.assertNotIn("x @ main.cpp:19", names)
self.assertNotIn("x @ main.cpp:21", names)
self.assertNotIn("x @ main.cpp:23", names)

self.verify_variables(verify_locals, locals)

Expand Down Expand Up @@ -663,6 +663,41 @@ def do_test_indexedVariables(self, enableSyntheticChildDebugging: bool):
]["variables"]
self.verify_variables(verify_children, children)

def test_return_variables(self):
"""
Test the stepping out of a function with return value show the variable correctly.
"""
program = self.getBuildArtifact("a.out")
self.build_and_launch(program)

verify_locals = {
"(Return Value)": {"equals": {"type": "int", "value": "300"}},
"argc": {},
"argv": {},
"pt": {},
"x": {},
"return_result": {"equals": {"type": "int"}},
}

function_name = "test_return_variable"
breakpoint_ids = self.set_function_breakpoints([function_name])

self.assertEqual(len(breakpoint_ids), 1)
self.continue_to_breakpoints(breakpoint_ids)

threads = self.dap_server.get_threads()
for thread in threads:
if thread.get("reason") == "breakpoint":
# We have a thread that
thread_id = thread["id"]

self.stepOut(threadId=thread_id)

local_variables = self.dap_server.get_local_variables()
varref_dict = {}
self.verify_variables(verify_locals, local_variables, varref_dict)
break

@skipIfWindows
def test_indexedVariables(self):
self.do_test_indexedVariables(enableSyntheticChildDebugging=False)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,58 @@ def test_get_num_children(self):
"`script formatter.num_children_calls", context="repl"
)["body"]["result"],
)

def test_return_variable_with_children(self):
"""
Test the stepping out of a function with return value show the children correctly
"""
program = self.getBuildArtifact("a.out")
self.build_and_launch(program)

function_name = "test_return_variable_with_children"
breakpoint_ids = self.set_function_breakpoints([function_name])

self.assertEqual(len(breakpoint_ids), 1)
self.continue_to_breakpoints(breakpoint_ids)

threads = self.dap_server.get_threads()
for thread in threads:
if thread.get("reason") == "breakpoint":
thread_id = thread.get("id")
self.assertIsNot(thread_id, None)

self.stepOut(threadId=thread_id)

local_variables = self.dap_server.get_local_variables()

# verify has return variable as local
result_variable = list(
filter(
lambda val: val.get("name") == "(Return Value)", local_variables
)
)
self.assertEqual(len(result_variable), 1)
result_variable = result_variable[0]

result_var_ref = result_variable.get("variablesReference")
self.assertIsNot(result_var_ref, None, "There is no result value")

result_value = self.dap_server.request_variables(result_var_ref)
result_children = result_value["body"]["variables"]
self.assertNotEqual(
result_children, None, "The result does not have children"
)

verify_children = {"buffer": '"hello world!"', "x": "10", "y": "20"}
for child in result_children:
actual_name = child["name"]
actual_value = child["value"]
verify_value = verify_children.get(actual_name)
self.assertNotEqual(verify_value, None)
self.assertEqual(
actual_value,
verify_value,
"Expected child value does not match",
)

break
12 changes: 12 additions & 0 deletions lldb/test/API/tools/lldb-dap/variables/children/main.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
struct Indexed {};
struct NotIndexed {};

#define BUFFER_SIZE 16
struct NonPrimitive {
char buffer[BUFFER_SIZE];
int x;
long y;
};

NonPrimitive test_return_variable_with_children() {
return NonPrimitive{"hello world!", 10, 20};
}

int main() {
Indexed indexed;
NotIndexed not_indexed;
NonPrimitive non_primitive_result = test_return_variable_with_children();
return 0; // break here
}
9 changes: 9 additions & 0 deletions lldb/test/API/tools/lldb-dap/variables/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ struct PointType {
int g_global = 123;
static int s_global = 234;
int test_indexedVariables();
int test_return_variable();

int main(int argc, char const *argv[]) {
static float s_local = 2.25;
PointType pt = {11, 22, {0}};
Expand All @@ -22,6 +24,9 @@ int main(int argc, char const *argv[]) {
s_global = x; // breakpoint 2
}
}
{
int return_result = test_return_variable();
}
return test_indexedVariables(); // breakpoint 3
}

Expand All @@ -34,3 +39,7 @@ int test_indexedVariables() {
large_vector.assign(200, 0);
return 0; // breakpoint 4
}

int test_return_variable() {
return 300; // breakpoint 5
}

0 comments on commit a5e336a

Please sign in to comment.