2 Set breakpoints on objective-c class and instance methods in foundation.
3 Also lookup objective-c data types and evaluate expressions.
9 from lldbsuite
.test
.decorators
import *
10 from lldbsuite
.test
.lldbtest
import *
11 from lldbsuite
.test
import lldbutil
16 class FoundationTestCase(TestBase
):
18 # Call super's setUp().
20 # Find the line number to break inside main().
21 self
.main_source
= "main.m"
22 self
.line
= line_number(self
.main_source
, "// Set break point at this line.")
25 """Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'."""
27 exe
= self
.getBuildArtifact("a.out")
28 self
.runCmd("file " + exe
, CURRENT_EXECUTABLE_SET
)
30 # Stop at +[NSString stringWithFormat:].
31 break_results
= lldbutil
.run_break_set_command(
32 self
, "_regexp-break +[NSString stringWithFormat:]"
34 lldbutil
.check_breakpoint_result(
37 symbol_name
="+[NSString stringWithFormat:]",
41 # Stop at -[MyString initWithNSString:].
42 lldbutil
.run_break_set_by_symbol(
44 "-[MyString initWithNSString:]",
45 num_expected_locations
=1,
49 # Stop at the "description" selector.
50 lldbutil
.run_break_set_by_selector(
51 self
, "description", num_expected_locations
=1, module_name
="a.out"
54 # Stop at -[NSAutoreleasePool release].
55 break_results
= lldbutil
.run_break_set_command(
56 self
, "_regexp-break -[NSAutoreleasePool release]"
58 lldbutil
.check_breakpoint_result(
61 symbol_name
="-[NSAutoreleasePool release]",
65 self
.runCmd("run", RUN_SUCCEEDED
)
67 # First stop is +[NSString stringWithFormat:].
70 "Stop at +[NSString stringWithFormat:]",
71 substrs
=["Foundation`+[NSString stringWithFormat:]"],
74 self
.runCmd("process continue")
76 # Second stop is still +[NSString stringWithFormat:].
79 "Stop at +[NSString stringWithFormat:]",
80 substrs
=["Foundation`+[NSString stringWithFormat:]"],
83 self
.runCmd("process continue")
85 # Followed by a.out`-[MyString initWithNSString:].
88 "Stop at a.out`-[MyString initWithNSString:]",
89 substrs
=["a.out`-[MyString initWithNSString:]"],
92 self
.runCmd("process continue")
94 # Followed by -[MyString description].
97 "Stop at -[MyString description]",
98 substrs
=["a.out`-[MyString description]"],
101 self
.runCmd("process continue")
103 # Followed by the same -[MyString description].
106 "Stop at -[MyString description]",
107 substrs
=["a.out`-[MyString description]"],
110 self
.runCmd("process continue")
112 # Followed by -[NSAutoreleasePool release].
115 "Stop at -[NSAutoreleasePool release]",
116 substrs
=["Foundation`-[NSAutoreleasePool release]"],
119 # rdar://problem/8542091
120 # rdar://problem/8492646
121 def test_data_type_and_expr(self
):
122 """Lookup objective-c data types and evaluate expressions."""
124 exe
= self
.getBuildArtifact("a.out")
125 self
.runCmd("file " + exe
, CURRENT_EXECUTABLE_SET
)
127 # Stop at -[MyString description].
128 lldbutil
.run_break_set_by_symbol(
129 self
, "-[MyString description]", num_expected_locations
=1, sym_exact
=True
131 # self.expect("breakpoint set -n '-[MyString description]", BREAKPOINT_CREATED,
132 # startstr = "Breakpoint created: 1: name = '-[MyString description]',
135 self
.runCmd("run", RUN_SUCCEEDED
)
137 self
.runCmd("settings set target.prefer-dynamic-value no-dynamic-values")
139 # The backtrace should show we stop at -[MyString description].
142 "Stop at -[MyString description]",
143 substrs
=["a.out`-[MyString description]"],
146 # Lookup objc data type MyString and evaluate some expressions.
149 "image lookup -t NSString",
150 DATA_TYPES_DISPLAYED_CORRECTLY
,
151 substrs
=['name = "NSString"', 'compiler_type = "@interface NSString'],
155 "image lookup -t MyString",
156 DATA_TYPES_DISPLAYED_CORRECTLY
,
159 'compiler_type = "@interface MyString',
166 "frame variable --show-types --scope",
167 VARIABLES_DISPLAYED_CORRECTLY
,
168 substrs
=["ARG: (MyString *) self"],
169 patterns
=["ARG: \(.*\) _cmd", "(objc_selector *)|(SEL)"],
172 # rdar://problem/8651752
173 # don't crash trying to ask clang how many children an empty record has
174 self
.runCmd("frame variable *_cmd")
176 # rdar://problem/8492646
177 # test/foundation fails after updating to tot r115023
178 # self->str displays nothing as output
180 "frame variable --show-types self->str",
181 VARIABLES_DISPLAYED_CORRECTLY
,
182 startstr
="(NSString *) self->str",
185 # rdar://problem/8447030
186 # 'frame variable self->date' displays the wrong data member
188 "frame variable --show-types self->date",
189 VARIABLES_DISPLAYED_CORRECTLY
,
190 startstr
="(NSDate *) self->date",
193 # This should display the str and date member fields as well.
195 "frame variable --show-types *self",
196 VARIABLES_DISPLAYED_CORRECTLY
,
197 substrs
=["(MyString) *self", "(NSString *) str", "(NSDate *) date"],
200 # isa should be accessible.
202 "expression self->isa", VARIABLES_DISPLAYED_CORRECTLY
, substrs
=["Class)"]
205 # This should fail expectedly.
207 "expression self->non_existent_member",
208 COMMAND_FAILED_AS_EXPECTED
,
212 "'MyString' does not have a member named 'non_existent_member'",
216 # Use expression parser.
217 self
.runCmd("expression self->str")
218 self
.runCmd("expression self->date")
220 # (lldb) expression self->str
221 # error: instance variable 'str' is protected
222 # error: 1 errors parsing expression
224 # (lldb) expression self->date
225 # error: instance variable 'date' is protected
226 # error: 1 errors parsing expression
229 self
.runCmd("breakpoint delete 1")
230 lldbutil
.run_break_set_by_file_and_line(
231 self
, "main.m", self
.line
, num_expected_locations
=1, loc_exact
=True
234 self
.runCmd("process continue")
236 # rdar://problem/8542091
237 # test/foundation: expr -o -- my not working?
239 # Test new feature with r115115:
240 # Add "-o" option to "expression" which prints the object description
243 "expression --object-description -- my",
244 "Object description displayed correctly",
245 patterns
=["Hello from.*a.out.*with timestamp: "],
248 @add_test_categories(["pyapi"])
249 def test_print_ivars_correctly(self
):
251 # See: <rdar://problem/8717050> lldb needs to use the ObjC runtime symbols for ivar offsets
252 # Only fails for the ObjC 2.0 runtime.
253 exe
= self
.getBuildArtifact("a.out")
255 target
= self
.dbg
.CreateTarget(exe
)
256 self
.assertTrue(target
, VALID_TARGET
)
258 break1
= target
.BreakpointCreateByLocation(self
.main_source
, self
.line
)
259 self
.assertTrue(break1
, VALID_BREAKPOINT
)
261 # Now launch the process, and do not stop at entry point.
262 process
= target
.LaunchSimple(None, None, self
.get_process_working_directory())
264 self
.assertTrue(process
, PROCESS_IS_VALID
)
266 # The stop reason of the thread should be breakpoint.
267 thread
= process
.GetThreadAtIndex(0)
268 if thread
.GetStopReason() != lldb
.eStopReasonBreakpoint
:
269 from lldbsuite
.test
.lldbutil
import stop_reason_to_str
272 STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS
273 % stop_reason_to_str(thread
.GetStopReason())
276 # Make sure we stopped at the first breakpoint.
278 cur_frame
= thread
.GetFrameAtIndex(0)
280 line_number
= cur_frame
.GetLineEntry().GetLine()
281 self
.assertEqual(line_number
, self
.line
, "Hit the first breakpoint.")
283 my_var
= cur_frame
.FindVariable("my")
284 self
.assertTrue(my_var
, "Made a variable object for my")
286 str_var
= cur_frame
.FindVariable("str")
287 self
.assertTrue(str_var
, "Made a variable object for str")
289 # Now make sure that the my->str == str:
291 my_str_var
= my_var
.GetChildMemberWithName("str")
292 self
.assertTrue(my_str_var
, "Found a str ivar in my")
294 str_value
= int(str_var
.GetValue(), 0)
296 my_str_value
= int(my_str_var
.GetValue(), 0)
298 self
.assertEqual(str_value
, my_str_value
, "Got the correct value for my->str")
300 def test_expression_lookups_objc(self
):
301 """Test running an expression detect spurious debug info lookups (DWARF)."""
303 exe
= self
.getBuildArtifact("a.out")
304 self
.runCmd("file " + exe
, CURRENT_EXECUTABLE_SET
)
306 # Stop at -[MyString initWithNSString:].
307 lldbutil
.run_break_set_by_symbol(
309 "-[MyString initWithNSString:]",
310 num_expected_locations
=1,
314 self
.runCmd("run", RUN_SUCCEEDED
)
317 # Log any DWARF lookups
319 logfile
= os
.path
.join(
321 "dwarf-lookups-" + self
.getArchitecture() + "-" + str(file_index
) + ".txt",
323 self
.runCmd("log enable -f %s dwarf lookups" % (logfile
))
324 self
.runCmd("expr self")
325 self
.runCmd("log disable dwarf lookups")
328 if os
.path
.exists(logfile
):
331 self
.addTearDownHook(cleanup
)
333 if os
.path
.exists(logfile
):
335 lines
= f
.readlines()
338 if "$__lldb" in line
:
341 "error: found spurious name lookups when evaluating an expression:"
345 self
.assertEqual(num_errors
, 0, "Spurious lookups detected")