Skip to content

[lldb-vscode] Make descriptive summaries and raw child for synthetics configurable #65687

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from lldbsuite.test.lldbtest import *
import os
import vscode
import time

import vscode
from lldbsuite.test.lldbtest import *


class VSCodeTestCaseBase(TestBase):
NO_DEBUG_INFO_TESTCASE = True
Expand Down Expand Up @@ -267,7 +268,7 @@ def disassemble(self, threadId=None, frameIndex=None):

if memoryReference not in self.vscode.disassembled_instructions:
self.vscode.request_disassemble(memoryReference=memoryReference)

return self.vscode.disassembled_instructions[memoryReference]

def attach(
Expand Down Expand Up @@ -348,6 +349,8 @@ def launch(
runInTerminal=False,
expectFailure=False,
postRunCommands=None,
enableAutoVariableSummaries=False,
enableSyntheticChildDebugging=False,
):
"""Sending launch request to vscode"""

Expand Down Expand Up @@ -384,6 +387,8 @@ def cleanup():
sourceMap=sourceMap,
runInTerminal=runInTerminal,
postRunCommands=postRunCommands,
enableAutoVariableSummaries=enableAutoVariableSummaries,
enableSyntheticChildDebugging=enableSyntheticChildDebugging,
)

if expectFailure:
Expand Down Expand Up @@ -418,6 +423,8 @@ def build_and_launch(
disconnectAutomatically=True,
postRunCommands=None,
lldbVSCodeEnv=None,
enableAutoVariableSummaries=False,
enableSyntheticChildDebugging=False,
):
"""Build the default Makefile target, create the VSCode debug adaptor,
and launch the process.
Expand Down Expand Up @@ -446,4 +453,6 @@ def build_and_launch(
runInTerminal=runInTerminal,
disconnectAutomatically=disconnectAutomatically,
postRunCommands=postRunCommands,
enableAutoVariableSummaries=enableAutoVariableSummaries,
enableSyntheticChildDebugging=enableSyntheticChildDebugging,
)
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ def request_disconnect(self, terminateDebuggee=None):
"arguments": args_dict,
}
return self.send_recv(command_dict)

def request_disassemble(self, memoryReference, offset=-50, instructionCount=200, resolveSymbols=True):
args_dict = {
"memoryReference": memoryReference,
Expand Down Expand Up @@ -727,6 +727,8 @@ def request_launch(
sourceMap=None,
runInTerminal=False,
postRunCommands=None,
enableAutoVariableSummaries=False,
enableSyntheticChildDebugging=False,
):
args_dict = {"program": program}
if args:
Expand Down Expand Up @@ -768,6 +770,8 @@ def request_launch(
args_dict["runInTerminal"] = runInTerminal
if postRunCommands:
args_dict["postRunCommands"] = postRunCommands
args_dict["enableAutoVariableSummaries"] = enableAutoVariableSummaries
args_dict["enableSyntheticChildDebugging"] = enableSyntheticChildDebugging
command_dict = {"command": "launch", "type": "request", "arguments": args_dict}
response = self.send_recv(command_dict)

Expand Down
24 changes: 16 additions & 8 deletions lldb/test/API/tools/lldb-vscode/evaluate/TestVSCode_evaluate.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,17 @@ def assertEvaluateFailure(self, expression):
def isExpressionParsedExpected(self):
return self.context != "hover"

def run_test_evaluate_expressions(self, context=None):
def run_test_evaluate_expressions(
self, context=None, enableAutoVariableSummaries=False
):
"""
Tests the evaluate expression request at different breakpoints
"""
self.context = context
program = self.getBuildArtifact("a.out")
self.build_and_launch(program)
self.build_and_launch(
program, enableAutoVariableSummaries=enableAutoVariableSummaries
)
source = "main.cpp"
self.set_source_breakpoints(
source,
Expand All @@ -55,7 +59,9 @@ def run_test_evaluate_expressions(self, context=None):
self.assertEvaluate("var2", "21")
self.assertEvaluate("static_int", "42")
self.assertEvaluate("non_static_int", "43")
self.assertEvaluate("struct1", "{foo:15}")
self.assertEvaluate(
"struct1", "{foo:15}" if enableAutoVariableSummaries else "my_struct @ 0x"
)
self.assertEvaluate("struct1.foo", "15")
self.assertEvaluate("struct2->foo", "16")

Expand Down Expand Up @@ -85,7 +91,9 @@ def run_test_evaluate_expressions(self, context=None):
self.assertEvaluate(
"non_static_int", "10"
) # different variable with the same name
self.assertEvaluate("struct1", "{foo:15}")
self.assertEvaluate(
"struct1", "{foo:15}" if enableAutoVariableSummaries else "my_struct @ 0x"
)
self.assertEvaluate("struct1.foo", "15")
self.assertEvaluate("struct2->foo", "16")

Expand Down Expand Up @@ -146,22 +154,22 @@ def run_test_evaluate_expressions(self, context=None):
@skipIfRemote
def test_generic_evaluate_expressions(self):
# Tests context-less expression evaluations
self.run_test_evaluate_expressions()
self.run_test_evaluate_expressions(enableAutoVariableSummaries=False)

@skipIfWindows
@skipIfRemote
def test_repl_evaluate_expressions(self):
# Tests expression evaluations that are triggered from the Debug Console
self.run_test_evaluate_expressions("repl")
self.run_test_evaluate_expressions("repl", enableAutoVariableSummaries=True)

@skipIfWindows
@skipIfRemote
def test_watch_evaluate_expressions(self):
# Tests expression evaluations that are triggered from a watch expression
self.run_test_evaluate_expressions("watch")
self.run_test_evaluate_expressions("watch", enableAutoVariableSummaries=False)

@skipIfWindows
@skipIfRemote
def test_hover_evaluate_expressions(self):
# Tests expression evaluations that are triggered when hovering on the editor
self.run_test_evaluate_expressions("hover")
self.run_test_evaluate_expressions("hover", enableAutoVariableSummaries=True)
81 changes: 66 additions & 15 deletions lldb/test/API/tools/lldb-vscode/variables/TestVSCode_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,17 @@ def darwin_dwarf_missing_obj(self, initCommands):
varref_dict = {}
self.verify_variables(verify_locals, locals, varref_dict)

@skipIfWindows
@skipIfRemote
def test_scopes_variables_setVariable_evaluate(self):
def do_test_scopes_variables_setVariable_evaluate(
self, enableAutoVariableSummaries: bool
):
"""
Tests the "scopes", "variables", "setVariable", and "evaluate"
packets.
"""
program = self.getBuildArtifact("a.out")
self.build_and_launch(program)
self.build_and_launch(
program, enableAutoVariableSummaries=enableAutoVariableSummaries
)
source = "main.cpp"
breakpoint1_line = line_number(source, "// breakpoint 1")
lines = [breakpoint1_line]
Expand Down Expand Up @@ -219,12 +221,20 @@ def test_scopes_variables_setVariable_evaluate(self):
},
"pt": {
"equals": {"type": "PointType"},
"startswith": {"result": "{x:11, y:22}"},
"startswith": {
"result": "{x:11, y:22}"
if enableAutoVariableSummaries
else "PointType @ 0x"
},
"hasVariablesReference": True,
},
"pt.buffer": {
"equals": {"type": "int[32]"},
"startswith": {"result": "{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...}"},
"startswith": {
"result": "{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...}"
if enableAutoVariableSummaries
else "int[32] @ 0x"
},
"hasVariablesReference": True,
},
"argv": {
Expand Down Expand Up @@ -347,13 +357,27 @@ def test_scopes_variables_setVariable_evaluate(self):

@skipIfWindows
@skipIfRemote
def test_scopes_and_evaluate_expansion(self):
def test_scopes_variables_setVariable_evaluate(self):
self.do_test_scopes_variables_setVariable_evaluate(
enableAutoVariableSummaries=False
)

@skipIfWindows
@skipIfRemote
def test_scopes_variables_setVariable_evaluate_with_descriptive_summaries(self):
self.do_test_scopes_variables_setVariable_evaluate(
enableAutoVariableSummaries=True
)

def do_test_scopes_and_evaluate_expansion(self, enableAutoVariableSummaries: bool):
"""
Tests the evaluated expression expands successfully after "scopes" packets
and permanent expressions persist.
"""
program = self.getBuildArtifact("a.out")
self.build_and_launch(program)
self.build_and_launch(
program, enableAutoVariableSummaries=enableAutoVariableSummaries
)
source = "main.cpp"
breakpoint1_line = line_number(source, "// breakpoint 1")
lines = [breakpoint1_line]
Expand Down Expand Up @@ -410,7 +434,11 @@ def test_scopes_and_evaluate_expansion(self):
"name": "pt",
"response": {
"equals": {"type": "PointType"},
"startswith": {"result": "{x:11, y:22}"},
"startswith": {
"result": "{x:11, y:22}"
if enableAutoVariableSummaries
else "PointType @ 0x"
},
"missing": ["indexedVariables"],
"hasVariablesReference": True,
},
Expand Down Expand Up @@ -487,14 +515,24 @@ def test_scopes_and_evaluate_expansion(self):

@skipIfWindows
@skipIfRemote
def test_indexedVariables(self):
def test_scopes_and_evaluate_expansion(self):
self.do_test_scopes_and_evaluate_expansion(enableAutoVariableSummaries=False)

@skipIfWindows
@skipIfRemote
def test_scopes_and_evaluate_expansion_with_descriptive_summaries(self):
self.do_test_scopes_and_evaluate_expansion(enableAutoVariableSummaries=True)

def do_test_indexedVariables(self, enableSyntheticChildDebugging: bool):
"""
Tests that arrays and lldb.SBValue objects that have synthetic child
providers have "indexedVariables" key/value pairs. This helps the IDE
not to fetch too many children all at once.
"""
program = self.getBuildArtifact("a.out")
self.build_and_launch(program)
self.build_and_launch(
program, enableSyntheticChildDebugging=enableSyntheticChildDebugging
)
source = "main.cpp"
breakpoint1_line = line_number(source, "// breakpoint 4")
lines = [breakpoint1_line]
Expand All @@ -507,13 +545,14 @@ def test_indexedVariables(self):

# Verify locals
locals = self.vscode.get_local_variables()
# The vector variables will have one additional entry from the fake
# The vector variables might have one additional entry from the fake
# "[raw]" child.
raw_child_count = 1 if enableSyntheticChildDebugging else 0
verify_locals = {
"small_array": {"equals": {"indexedVariables": 5}},
"large_array": {"equals": {"indexedVariables": 200}},
"small_vector": {"equals": {"indexedVariables": 6}},
"large_vector": {"equals": {"indexedVariables": 201}},
"small_vector": {"equals": {"indexedVariables": 5 + raw_child_count}},
"large_vector": {"equals": {"indexedVariables": 200 + raw_child_count}},
"pt": {"missing": ["indexedVariables"]},
}
self.verify_variables(verify_locals, locals)
Expand All @@ -526,13 +565,25 @@ def test_indexedVariables(self):
"[2]": {"equals": {"type": "int", "value": "0"}},
"[3]": {"equals": {"type": "int", "value": "0"}},
"[4]": {"equals": {"type": "int", "value": "0"}},
"[raw]": {"contains": {"type": ["vector"]}},
}
if enableSyntheticChildDebugging:
verify_children["[raw]"] = ({"contains": {"type": ["vector"]}},)

children = self.vscode.request_variables(locals[2]["variablesReference"])[
"body"
]["variables"]
self.verify_variables(verify_children, children)

@skipIfWindows
@skipIfRemote
def test_indexedVariables(self):
self.do_test_indexedVariables(enableSyntheticChildDebugging=False)

@skipIfWindows
@skipIfRemote
def test_indexedVariables_with_raw_child_for_synthetics(self):
self.do_test_indexedVariables(enableSyntheticChildDebugging=True)

@skipIfWindows
@skipIfRemote
def test_registers(self):
Expand Down
12 changes: 11 additions & 1 deletion lldb/tools/lldb-vscode/JSONUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,12 @@ std::vector<std::string> GetStrings(const llvm::json::Object *obj,
/// glance.
static std::optional<std::string>
GetSyntheticSummaryForContainer(lldb::SBValue &v) {
// We gate this feature because it performs GetNumChildren(), which can
// cause performance issues because LLDB needs to complete possibly huge
// types.
if (!g_vsc.enable_auto_variable_summaries)
return std::nullopt;

if (v.TypeIsPointerType() || !v.MightHaveChildren())
return std::nullopt;
/// As this operation can be potentially slow, we limit the total time spent
Expand Down Expand Up @@ -191,6 +197,9 @@ GetSyntheticSummaryForContainer(lldb::SBValue &v) {
/// Return whether we should dereference an SBValue in order to generate a more
/// meaningful summary string.
static bool ShouldBeDereferencedForSummary(lldb::SBValue &v) {
if (!g_vsc.enable_auto_variable_summaries)
return false;

if (!v.GetType().IsPointerType() && !v.GetType().IsReferenceType())
return false;

Expand Down Expand Up @@ -1137,7 +1146,8 @@ llvm::json::Value CreateVariable(lldb::SBValue v, int64_t variablesReference,
// We create a "[raw]" fake child for each synthetic type, so we have to
// account for it when returning indexed variables. We don't need to do this
// for non-indexed ones.
int actual_num_children = num_children + (is_synthetic ? 1 : 0);
bool has_raw_child = is_synthetic && g_vsc.enable_synthetic_child_debugging;
int actual_num_children = num_children + (has_raw_child ? 1 : 0);
if (is_array) {
object.try_emplace("indexedVariables", actual_num_children);
} else if (num_children > 0) {
Expand Down
2 changes: 2 additions & 0 deletions lldb/tools/lldb-vscode/VSCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ VSCode::VSCode()
{"swift_throw", "Swift Throw", lldb::eLanguageTypeSwift}}),
focus_tid(LLDB_INVALID_THREAD_ID), sent_terminated_event(false),
stop_at_entry(false), is_attach(false),
enable_auto_variable_summaries(false),
enable_synthetic_child_debugging(false),
restarting_process_id(LLDB_INVALID_PROCESS_ID),
configuration_done_sent(false), waiting_for_run_in_terminal(false),
progress_event_reporter(
Expand Down
2 changes: 2 additions & 0 deletions lldb/tools/lldb-vscode/VSCode.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ struct VSCode {
std::atomic<bool> sent_terminated_event;
bool stop_at_entry;
bool is_attach;
bool enable_auto_variable_summaries;
bool enable_synthetic_child_debugging;
// The process event thread normally responds to process exited events by
// shutting down the entire adapter. When we're restarting, we keep the id of
// the old process here so we can detect this case and keep running.
Expand Down
11 changes: 10 additions & 1 deletion lldb/tools/lldb-vscode/lldb-vscode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,10 @@ void request_attach(const llvm::json::Object &request) {
std::vector<std::string> postRunCommands =
GetStrings(arguments, "postRunCommands");
const llvm::StringRef debuggerRoot = GetString(arguments, "debuggerRoot");
g_vsc.enable_auto_variable_summaries =
GetBoolean(arguments, "enableAutoVariableSummaries", false);
g_vsc.enable_synthetic_child_debugging =
GetBoolean(arguments, "enableSyntheticChildDebugging", false);

// This is a hack for loading DWARF in .o files on Mac where the .o files
// in the debug map of the main executable have relative paths which require
Expand Down Expand Up @@ -1794,6 +1798,10 @@ void request_launch(const llvm::json::Object &request) {
GetStrings(arguments, "postRunCommands");
g_vsc.stop_at_entry = GetBoolean(arguments, "stopOnEntry", false);
const llvm::StringRef debuggerRoot = GetString(arguments, "debuggerRoot");
g_vsc.enable_auto_variable_summaries =
GetBoolean(arguments, "enableAutoVariableSummaries", false);
g_vsc.enable_synthetic_child_debugging =
GetBoolean(arguments, "enableSyntheticChildDebugging", false);

// This is a hack for loading DWARF in .o files on Mac where the .o files
// in the debug map of the main executable have relative paths which require
Expand Down Expand Up @@ -3292,7 +3300,8 @@ void request_variables(const llvm::json::Object &request) {
// "[raw]" child that can be used to inspect the raw version of a
// synthetic member. That eliminates the need for the user to go to the
// debug console and type `frame var <variable> to get these values.
if (variable.IsSynthetic() && i == num_children)
if (g_vsc.enable_synthetic_child_debugging && variable.IsSynthetic() &&
i == num_children)
addChild(variable.GetNonSyntheticValue(), "[raw]");
}
}
Expand Down
Loading