2 Test dwim-print with variables, variable paths, and expressions.
7 from lldbsuite
.test
.lldbtest
import *
8 from lldbsuite
.test
.decorators
import *
9 import lldbsuite
.test
.lldbutil
as lldbutil
12 class TestCase(TestBase
):
13 def _run_cmd(self
, cmd
: str) -> str:
14 """Run the given lldb command and return its output."""
15 result
= lldb
.SBCommandReturnObject()
16 self
.ci
.HandleCommand(cmd
, result
)
17 return result
.GetOutput().rstrip()
19 VAR_IDENT
= re
.compile(r
"(?:\$\d+|[\w.]+) = ")
21 def _strip_result_var(self
, string
: str) -> str:
23 Strip (persistent) result variables (ex '$0 = ', or 'someVar = ', etc).
25 This allows for using the output of `expression`/`frame variable`, to
26 compare it to `dwim-print` output, which disables result variables.
28 return self
.VAR_IDENT
.subn("", string
, 1)[0]
35 """Run dwim-print and verify the output against the expected command."""
36 # Resolve the dwim-print command to either `expression` or `frame variable`.
37 substitute_cmd
= dwim_cmd
.replace("dwim-print", actual_cmd
, 1)
38 interp
= self
.dbg
.GetCommandInterpreter()
39 result
= lldb
.SBCommandReturnObject()
40 interp
.ResolveCommand(substitute_cmd
, result
)
41 self
.assertTrue(result
.Succeeded(), result
.GetError())
43 resolved_cmd
= result
.GetOutput()
44 if actual_cmd
== "frame variable":
45 resolved_cmd
= resolved_cmd
.replace(" -- ", " ", 1)
47 resolved_cmd_output
= self
._run
_cmd
(resolved_cmd
)
48 dwim_cmd_output
= self
._strip
_result
_var
(resolved_cmd_output
)
50 # Verify dwim-print chose the expected command.
51 self
.runCmd("settings set dwim-print-verbosity full")
56 f
"note: ran `{resolved_cmd}`",
61 def test_variables(self
):
62 """Test dwim-print with variables."""
64 lldbutil
.run_to_name_breakpoint(self
, "main")
65 vars = ("argc", "argv")
67 self
._expect
_cmd
(f
"dwim-print {var}", "frame variable")
69 def test_variable_paths(self
):
70 """Test dwim-print with variable path expressions."""
72 lldbutil
.run_to_name_breakpoint(self
, "main")
73 exprs
= ("&argc", "*argv", "argv[0]")
75 self
._expect
_cmd
(f
"dwim-print {expr}", "expression")
77 def test_expressions(self
):
78 """Test dwim-print with expressions."""
80 lldbutil
.run_to_name_breakpoint(self
, "main")
81 exprs
= ("argc + 1", "(void)argc", "(int)abs(argc)")
83 self
._expect
_cmd
(f
"dwim-print {expr}", "expression")
85 def test_dummy_target_expressions(self
):
86 """Test dwim-print's ability to evaluate expressions without a target."""
87 self
._expect
_cmd
("dwim-print 1 + 2", "expression")
89 def test_gdb_format(self
):
91 lldbutil
.run_to_name_breakpoint(self
, "main")
92 self
._expect
_cmd
(f
"dwim-print/x argc", "frame variable")
93 self
._expect
_cmd
(f
"dwim-print/x argc + 1", "expression")
95 def test_format_flags(self
):
97 lldbutil
.run_to_name_breakpoint(self
, "main")
98 self
._expect
_cmd
(f
"dwim-print -fx -- argc", "frame variable")
99 self
._expect
_cmd
(f
"dwim-print -fx -- argc + 1", "expression")
101 def test_display_flags(self
):
103 lldbutil
.run_to_name_breakpoint(self
, "main")
104 self
._expect
_cmd
(f
"dwim-print -T -- argc", "frame variable")
105 self
._expect
_cmd
(f
"dwim-print -T -- argc + 1", "expression")
107 def test_expression_language(self
):
108 """Test that the language flag doesn't affect the choice of command."""
110 lldbutil
.run_to_name_breakpoint(self
, "main")
111 self
._expect
_cmd
(f
"dwim-print -l c++ -- argc", "frame variable")
112 self
._expect
_cmd
(f
"dwim-print -l c++ -- argc + 1", "expression")
114 def test_empty_expression(self
):
116 lldbutil
.run_to_name_breakpoint(self
, "main")
117 error_msg
= "error: 'dwim-print' takes a variable or expression"
118 self
.expect(f
"dwim-print", error
=True, startstr
=error_msg
)
119 self
.expect(f
"dwim-print -- ", error
=True, startstr
=error_msg
)
121 def test_nested_values(self
):
122 """Test dwim-print with nested values (structs, etc)."""
124 lldbutil
.run_to_source_breakpoint(
125 self
, "break here", lldb
.SBFileSpec("main.cpp")
127 self
.runCmd("settings set auto-one-line-summaries false")
128 self
._expect
_cmd
(f
"dwim-print s", "frame variable")
129 self
._expect
_cmd
(f
"dwim-print (struct Structure)s", "expression")
131 def test_summary_strings(self
):
132 """Test dwim-print with type summaries."""
134 lldbutil
.run_to_source_breakpoint(
135 self
, "break here", lldb
.SBFileSpec("main.cpp")
137 self
.runCmd("settings set auto-one-line-summaries false")
138 self
.runCmd("type summary add -e -s 'stub summary' Structure")
139 self
._expect
_cmd
(f
"dwim-print s", "frame variable")
140 self
._expect
_cmd
(f
"dwim-print (struct Structure)s", "expression")
141 self
.runCmd("type summary delete Structure")
143 def test_void_result(self
):
144 """Test dwim-print does not surface an error message for void expressions."""
146 lldbutil
.run_to_source_breakpoint(
147 self
, "break here", lldb
.SBFileSpec("main.cpp")
149 self
.expect("dwim-print (void)15", matching
=False, patterns
=["(?i)error"])
151 def test_preserves_persistent_variables(self
):
152 """Test dwim-print does not delete persistent variables."""
154 lldbutil
.run_to_source_breakpoint(
155 self
, "break here", lldb
.SBFileSpec("main.cpp")
157 self
.expect("dwim-print int $i = 15")
158 # Run the same expression twice and verify success. This ensures the
159 # first command does not delete the persistent variable.
161 self
.expect("dwim-print $i", startstr
="(int) 15")
163 def test_missing_type(self
):
164 """The expected output of po opaque is its address (no error)"""
166 lldbutil
.run_to_source_breakpoint(
167 self
, "break here", lldb
.SBFileSpec("main.cpp")
169 self
.expect("dwim-print -O -- opaque", substrs
=["0x"])
171 def test_variable_expression_path(self
):
172 """Test dwim-print supports certain variable expression paths."""
174 lldbutil
.run_to_source_breakpoint(
175 self
, "break here", lldb
.SBFileSpec("main.cpp")
177 self
.runCmd("settings set auto-one-line-summaries false")
178 self
._expect
_cmd
("dwim-print w.s", "frame variable")
179 self
._expect
_cmd
("dwim-print wp->s", "expression")
181 def test_direct_child_access(self
):
182 """Test dwim-print supports accessing members/ivars without qualification."""
184 lldbutil
.run_to_source_breakpoint(
185 self
, "break inside", lldb
.SBFileSpec("main.cpp")
187 self
._expect
_cmd
("dwim-print number", "frame variable")