Skip to content

Fix dap variable value format issue #90799

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 4 commits into from
May 3, 2024
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
34 changes: 21 additions & 13 deletions lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ def get_completions(self, text, frameId=None):
response = self.request_completions(text, frameId)
return response["body"]["targets"]

def get_scope_variables(self, scope_name, frameIndex=0, threadId=None):
def get_scope_variables(self, scope_name, frameIndex=0, threadId=None, is_hex=None):
stackFrame = self.get_stackFrame(frameIndex=frameIndex, threadId=threadId)
if stackFrame is None:
return []
Expand All @@ -462,7 +462,7 @@ def get_scope_variables(self, scope_name, frameIndex=0, threadId=None):
for scope in frame_scopes:
if scope["name"] == scope_name:
varRef = scope["variablesReference"]
variables_response = self.request_variables(varRef)
variables_response = self.request_variables(varRef, is_hex=is_hex)
if variables_response:
if "body" in variables_response:
body = variables_response["body"]
Expand All @@ -476,38 +476,42 @@ def get_global_variables(self, frameIndex=0, threadId=None):
"Globals", frameIndex=frameIndex, threadId=threadId
)

def get_local_variables(self, frameIndex=0, threadId=None):
def get_local_variables(self, frameIndex=0, threadId=None, is_hex=None):
return self.get_scope_variables(
"Locals", frameIndex=frameIndex, threadId=threadId
"Locals", frameIndex=frameIndex, threadId=threadId, is_hex=is_hex
)

def get_registers(self, frameIndex=0, threadId=None):
return self.get_scope_variables(
"Registers", frameIndex=frameIndex, threadId=threadId
)

def get_local_variable(self, name, frameIndex=0, threadId=None):
locals = self.get_local_variables(frameIndex=frameIndex, threadId=threadId)
def get_local_variable(self, name, frameIndex=0, threadId=None, is_hex=None):
locals = self.get_local_variables(
frameIndex=frameIndex, threadId=threadId, is_hex=is_hex
)
for local in locals:
if "name" in local and local["name"] == name:
return local
return None

def get_local_variable_value(self, name, frameIndex=0, threadId=None):
def get_local_variable_value(self, name, frameIndex=0, threadId=None, is_hex=None):
variable = self.get_local_variable(
name, frameIndex=frameIndex, threadId=threadId
name, frameIndex=frameIndex, threadId=threadId, is_hex=is_hex
)
if variable and "value" in variable:
return variable["value"]
return None

def get_local_variable_child(self, name, child_name, frameIndex=0, threadId=None):
def get_local_variable_child(
self, name, child_name, frameIndex=0, threadId=None, is_hex=None
):
local = self.get_local_variable(name, frameIndex, threadId)
if local["variablesReference"] == 0:
return None
children = self.request_variables(local["variablesReference"])["body"][
"variables"
]
children = self.request_variables(local["variablesReference"], is_hex=is_hex)[
"body"
]["variables"]
for child in children:
if child["name"] == child_name:
return child
Expand Down Expand Up @@ -1035,12 +1039,16 @@ def request_threads(self):
self.threads = None
return response

def request_variables(self, variablesReference, start=None, count=None):
def request_variables(
self, variablesReference, start=None, count=None, is_hex=None
):
args_dict = {"variablesReference": variablesReference}
if start is not None:
args_dict["start"] = start
if count is not None:
args_dict["count"] = count
if is_hex is not None:
args_dict["format"] = {"hex": is_hex}
command_dict = {
"command": "variables",
"type": "request",
Expand Down
40 changes: 40 additions & 0 deletions lldb/test/API/tools/lldb-dap/variables/TestDAP_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -754,3 +754,43 @@ def test_darwin_dwarf_missing_obj_with_symbol_ondemand_enabled(self):
"""
initCommands = ["settings set symbols.load-on-demand true"]
self.darwin_dwarf_missing_obj(initCommands)

@no_debug_info_test
@skipIfWindows
@skipIfRemote
def test_value_format(self):
"""
Test that toggle variables value format between decimal and hexical works.
"""
program = self.getBuildArtifact("a.out")
self.build_and_launch(program)
source = "main.cpp"
breakpoint1_line = line_number(source, "// breakpoint 1")
lines = [breakpoint1_line]

breakpoint_ids = self.set_source_breakpoints(source, lines)
self.assertEqual(
len(breakpoint_ids), len(lines), "expect correct number of breakpoints"
)
self.continue_to_breakpoints(breakpoint_ids)

# Verify locals value format decimal
is_hex = False
var_pt_x = self.dap_server.get_local_variable_child("pt", "x", is_hex=is_hex)
self.assertEquals(var_pt_x["value"], "11")
var_pt_y = self.dap_server.get_local_variable_child("pt", "y", is_hex=is_hex)
self.assertEquals(var_pt_y["value"], "22")

# Verify locals value format hexical
is_hex = True
var_pt_x = self.dap_server.get_local_variable_child("pt", "x", is_hex=is_hex)
self.assertEquals(var_pt_x["value"], "0x0000000b")
var_pt_y = self.dap_server.get_local_variable_child("pt", "y", is_hex=is_hex)
self.assertEquals(var_pt_y["value"], "0x00000016")

# Toggle and verify locals value format decimal again
is_hex = False
var_pt_x = self.dap_server.get_local_variable_child("pt", "x", is_hex=is_hex)
self.assertEquals(var_pt_x["value"], "11")
var_pt_y = self.dap_server.get_local_variable_child("pt", "y", is_hex=is_hex)
self.assertEquals(var_pt_y["value"], "22")
11 changes: 8 additions & 3 deletions lldb/tools/lldb-dap/JSONUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,6 @@ llvm::json::Value CreateStackFrame(lldb::SBFrame &frame) {
} else {
object.try_emplace("line", 0);
object.try_emplace("column", 0);
object.try_emplace("presentationHint", "subtle");
}

const auto pc = frame.GetPC();
Expand Down Expand Up @@ -988,8 +987,14 @@ VariableDescription::VariableDescription(lldb::SBValue v, bool format_hex,
display_type_name =
!raw_display_type_name.empty() ? raw_display_type_name : NO_TYPENAME;

if (format_hex)
v.SetFormat(lldb::eFormatHex);
// Only format hex/default if there is no existing special format.
if (v.GetFormat() == lldb::eFormatDefault ||
v.GetFormat() == lldb::eFormatHex) {
if (format_hex)
v.SetFormat(lldb::eFormatHex);
else
v.SetFormat(lldb::eFormatDefault);
}

llvm::raw_string_ostream os_display_value(display_value);

Expand Down