blob: a12370cf274a604fa0e87148a8e5d42cea620cbd [file] [log] [blame]
Johnny Chenb3307862010-09-17 22:28:51 +00001"""
2Set breakpoints on objective-c class and instance methods in foundation.
3Also lookup objective-c data types and evaluate expressions.
4"""
Johnny Chen6c17c082010-09-16 20:54:06 +00005
6import os, time
7import unittest2
8import lldb
9from lldbtest import *
10
11@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
12class FoundationTestCase(TestBase):
13
14 mydir = "foundation"
15
Johnny Chenb219d282010-09-17 21:14:02 +000016 def test_break_with_dsym(self):
Greg Clayton8b82f082011-04-12 05:54:46 +000017 """Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'."""
Johnny Chen6c17c082010-09-16 20:54:06 +000018 self.buildDsym()
19 self.break_on_objc_methods()
20
Johnny Chenb219d282010-09-17 21:14:02 +000021 def test_break_with_dwarf(self):
Greg Clayton8b82f082011-04-12 05:54:46 +000022 """Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'."""
Johnny Chen6c17c082010-09-16 20:54:06 +000023 self.buildDwarf()
24 self.break_on_objc_methods()
25
Johnny Chen2769a422010-10-15 23:35:32 +000026 #@unittest2.expectedFailure
Johnny Chenf8afe892010-10-12 21:20:11 +000027 # rdar://problem/8542091
Johnny Chen8eb38502010-09-29 17:58:12 +000028 # rdar://problem/8492646
Johnny Chenb3307862010-09-17 22:28:51 +000029 def test_data_type_and_expr_with_dsym(self):
30 """Lookup objective-c data types and evaluate expressions."""
31 self.buildDsym()
32 self.data_type_and_expr_objc()
33
Johnny Chen2769a422010-10-15 23:35:32 +000034 #@unittest2.expectedFailure
Johnny Chenf8afe892010-10-12 21:20:11 +000035 # rdar://problem/8542091
Johnny Chen8eb38502010-09-29 17:58:12 +000036 # rdar://problem/8492646
Johnny Chenb3307862010-09-17 22:28:51 +000037 def test_data_type_and_expr_with_dwarf(self):
38 """Lookup objective-c data types and evaluate expressions."""
39 self.buildDwarf()
40 self.data_type_and_expr_objc()
41
Jim Ingham5949cfe2010-12-15 20:47:34 +000042 @python_api_test
43 def test_print_ivars_correctly_with_dsym (self):
44 self.buildDsym()
45 self.print_ivars_correctly()
46
47 @python_api_test
48 def test_print_ivars_correctly_with_dwarf (self):
49 self.buildDwarf()
50 self.print_ivars_correctly()
51
Johnny Chen6c17c082010-09-16 20:54:06 +000052 def break_on_objc_methods(self):
Greg Clayton8b82f082011-04-12 05:54:46 +000053 """Test setting objc breakpoints using '_regexp-break' and 'breakpoint set'."""
Johnny Chen6c17c082010-09-16 20:54:06 +000054 exe = os.path.join(os.getcwd(), "a.out")
55 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
56
57 # Stop at +[NSString stringWithFormat:].
Greg Clayton8b82f082011-04-12 05:54:46 +000058 self.expect("_regexp-break +[NSString stringWithFormat:]", BREAKPOINT_CREATED,
Johnny Chenf062c2f2010-10-12 19:29:49 +000059 substrs = ["Breakpoint created: 1: name = '+[NSString stringWithFormat:]', locations = 1"])
Johnny Chen6c17c082010-09-16 20:54:06 +000060
Johnny Chen2756d602010-09-16 23:57:33 +000061 # Stop at -[MyString initWithNSString:].
62 self.expect("breakpoint set -n '-[MyString initWithNSString:]'", BREAKPOINT_CREATED,
63 startstr = "Breakpoint created: 2: name = '-[MyString initWithNSString:]', locations = 1")
64
65 # Stop at the "description" selector.
66 self.expect("breakpoint set -S description", BREAKPOINT_CREATED,
67 startstr = "Breakpoint created: 3: name = 'description', locations = 1")
68
Johnny Chen6c17c082010-09-16 20:54:06 +000069 # Stop at -[NSAutoreleasePool release].
Greg Clayton8b82f082011-04-12 05:54:46 +000070 self.expect("_regexp-break -[NSAutoreleasePool release]", BREAKPOINT_CREATED,
Johnny Chenf062c2f2010-10-12 19:29:49 +000071 substrs = ["Breakpoint created: 4: name = '-[NSAutoreleasePool release]', locations = 1"])
Johnny Chen6c17c082010-09-16 20:54:06 +000072
73 self.runCmd("run", RUN_SUCCEEDED)
74
75 # First stop is +[NSString stringWithFormat:].
76 self.expect("thread backtrace", "Stop at +[NSString stringWithFormat:]",
77 substrs = ["Foundation`+[NSString stringWithFormat:]"])
78
79 self.runCmd("process continue")
80
Johnny Chen73b7b932010-12-06 22:09:04 +000081 # Second stop is still +[NSString stringWithFormat:].
82 self.expect("thread backtrace", "Stop at +[NSString stringWithFormat:]",
83 substrs = ["Foundation`+[NSString stringWithFormat:]"])
84
85 self.runCmd("process continue")
86
Johnny Chen2756d602010-09-16 23:57:33 +000087 # Followed by a.out`-[MyString initWithNSString:].
88 self.expect("thread backtrace", "Stop at a.out`-[MyString initWithNSString:]",
89 substrs = ["a.out`-[MyString initWithNSString:]"])
90
91 self.runCmd("process continue")
92
93 # Followed by -[MyString description].
94 self.expect("thread backtrace", "Stop at -[MyString description]",
95 substrs = ["a.out`-[MyString description]"])
96
97 self.runCmd("process continue")
98
Johnny Chen73b7b932010-12-06 22:09:04 +000099 # Followed by the same -[MyString description].
100 self.expect("thread backtrace", "Stop at -[MyString description]",
101 substrs = ["a.out`-[MyString description]"])
102
103 self.runCmd("process continue")
104
Johnny Chen6c17c082010-09-16 20:54:06 +0000105 # Followed by -[NSAutoreleasePool release].
106 self.expect("thread backtrace", "Stop at -[NSAutoreleasePool release]",
107 substrs = ["Foundation`-[NSAutoreleasePool release]"])
108
Johnny Chenf8afe892010-10-12 21:20:11 +0000109 def setUp(self):
Johnny Chenaadcef52010-10-14 17:31:24 +0000110 # Call super's setUp().
111 TestBase.setUp(self)
Johnny Chenf8afe892010-10-12 21:20:11 +0000112 # Find the line number to break inside main().
Jim Ingham5949cfe2010-12-15 20:47:34 +0000113 self.main_source = "main.m"
114 self.line = line_number(self.main_source, '// Set break point at this line.')
Johnny Chenf8afe892010-10-12 21:20:11 +0000115
Johnny Chenb3307862010-09-17 22:28:51 +0000116 def data_type_and_expr_objc(self):
117 """Lookup objective-c data types and evaluate expressions."""
118 exe = os.path.join(os.getcwd(), "a.out")
119 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
120
121 # Stop at -[MyString description].
122 self.expect("breakpoint set -n '-[MyString description]", BREAKPOINT_CREATED,
123 startstr = "Breakpoint created: 1: name = '-[MyString description]', locations = 1")
124
125 self.runCmd("run", RUN_SUCCEEDED)
126
127 # The backtrace should show we stop at -[MyString description].
128 self.expect("thread backtrace", "Stop at -[MyString description]",
129 substrs = ["a.out`-[MyString description]"])
130
131 # Lookup objc data type MyString and evaluate some expressions.
132
133 self.expect("image lookup -t NSString", DATA_TYPES_DISPLAYED_CORRECTLY,
Johnny Chen620f9d12010-09-29 17:50:35 +0000134 substrs = ['name = "NSString"',
Johnny Chenf8afe892010-10-12 21:20:11 +0000135 'clang_type = "@interface NSString'])
Johnny Chenb3307862010-09-17 22:28:51 +0000136
137 self.expect("image lookup -t MyString", DATA_TYPES_DISPLAYED_CORRECTLY,
Johnny Chen620f9d12010-09-29 17:50:35 +0000138 substrs = ['name = "MyString"',
Johnny Chenf8afe892010-10-12 21:20:11 +0000139 'clang_type = "@interface MyString',
140 'NSString * str;',
141 'NSDate * date;'])
Johnny Chenb3307862010-09-17 22:28:51 +0000142
Jim Ingham2837b762011-05-04 03:43:18 +0000143 self.expect("frame variable -T -s", VARIABLES_DISPLAYED_CORRECTLY,
Johnny Chen7fce8772010-10-01 23:34:28 +0000144 substrs = ["ARG: (MyString *) self"],
145 patterns = ["ARG: \(.*\) _cmd",
146 "(struct objc_selector *)|(SEL)"])
Johnny Chenb3307862010-09-17 22:28:51 +0000147
Johnny Chen07f06c42010-11-11 19:15:04 +0000148 # rdar://problem/8651752
149 # don't crash trying to ask clang how many children an empty record has
150 self.runCmd("frame variable *_cmd")
151
Johnny Chen8eb38502010-09-29 17:58:12 +0000152 # rdar://problem/8492646
153 # test/foundation fails after updating to tot r115023
154 # self->str displays nothing as output
Jim Ingham2837b762011-05-04 03:43:18 +0000155 self.expect("frame variable -T self->str", VARIABLES_DISPLAYED_CORRECTLY,
Johnny Chenb3307862010-09-17 22:28:51 +0000156 startstr = "(NSString *) self->str")
157
158 # rdar://problem/8447030
159 # 'frame variable self->date' displays the wrong data member
Jim Ingham2837b762011-05-04 03:43:18 +0000160 self.expect("frame variable -T self->date", VARIABLES_DISPLAYED_CORRECTLY,
Johnny Chenb3307862010-09-17 22:28:51 +0000161 startstr = "(NSDate *) self->date")
162
Johnny Chenf8afe892010-10-12 21:20:11 +0000163 # This should display the str and date member fields as well.
Jim Ingham2837b762011-05-04 03:43:18 +0000164 self.expect("frame variable -T *self", VARIABLES_DISPLAYED_CORRECTLY,
Johnny Chen8e744162010-12-15 22:50:54 +0000165 substrs = ["(MyString) *self",
Johnny Chenf8afe892010-10-12 21:20:11 +0000166 "(NSString *) str",
167 "(NSDate *) date"])
168
169 # This should fail expectedly.
Johnny Chena8807f92010-10-19 00:52:07 +0000170 self.expect("expression self->non_existent_member",
171 COMMAND_FAILED_AS_EXPECTED, error=True,
Johnny Chenf8afe892010-10-12 21:20:11 +0000172 startstr = "error: 'MyString' does not have a member named 'non_existent_member'")
173
Johnny Chenf8afe892010-10-12 21:20:11 +0000174 # Use expression parser.
Johnny Chen99ff4892010-11-12 00:55:31 +0000175 self.runCmd("expression self->str")
176 self.runCmd("expression self->date")
Johnny Chen2e566e02010-09-29 18:05:03 +0000177
Johnny Chena8807f92010-10-19 00:52:07 +0000178 # (lldb) expression self->str
Johnny Chenf8afe892010-10-12 21:20:11 +0000179 # error: instance variable 'str' is protected
Johnny Chenb3307862010-09-17 22:28:51 +0000180 # error: 1 errors parsing expression
Johnny Chenf8afe892010-10-12 21:20:11 +0000181 #
Johnny Chena8807f92010-10-19 00:52:07 +0000182 # (lldb) expression self->date
Johnny Chenf8afe892010-10-12 21:20:11 +0000183 # error: instance variable 'date' is protected
Johnny Chenb3307862010-09-17 22:28:51 +0000184 # error: 1 errors parsing expression
Johnny Chenf8afe892010-10-12 21:20:11 +0000185 #
186
Johnny Chen7987c612010-10-15 19:29:15 +0000187 self.runCmd("breakpoint delete 1")
Johnny Chenf8afe892010-10-12 21:20:11 +0000188 self.expect("breakpoint set -f main.m -l %d" % self.line,
189 BREAKPOINT_CREATED,
190 startstr = "Breakpoint created: 2: file ='main.m', line = %d, locations = 1" %
191 self.line)
192 self.runCmd("process continue")
193
Johnny Chenf8afe892010-10-12 21:20:11 +0000194 # rdar://problem/8542091
195 # test/foundation: expr -o -- my not working?
196 #
197 # Test new feature with r115115:
198 # Add "-o" option to "expression" which prints the object description if available.
Johnny Chena8807f92010-10-19 00:52:07 +0000199 self.expect("expression -o -- my", "Object description displayed correctly",
Johnny Chen2769a422010-10-15 23:35:32 +0000200 patterns = ["Hello from.*a.out.*with timestamp: "])
Johnny Chenb3307862010-09-17 22:28:51 +0000201
Jim Ingham5949cfe2010-12-15 20:47:34 +0000202 @unittest2.expectedFailure
203 # See: <rdar://problem/8717050> lldb needs to use the ObjC runtime symbols for ivar offsets
204 # Only fails for the ObjC 2.0 runtime.
205 def print_ivars_correctly(self) :
206 exe = os.path.join(os.getcwd(), "a.out")
Johnny Chen6c17c082010-09-16 20:54:06 +0000207
Jim Ingham5949cfe2010-12-15 20:47:34 +0000208 target = self.dbg.CreateTarget(exe)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000209 self.assertTrue(target, VALID_TARGET)
Jim Ingham5949cfe2010-12-15 20:47:34 +0000210
211 break1 = target.BreakpointCreateByLocation(self.main_source, self.line)
Johnny Chen4ebd0192011-05-24 18:22:45 +0000212 self.assertTrue(break1, VALID_BREAKPOINT)
Jim Ingham5949cfe2010-12-15 20:47:34 +0000213
214 # Now launch the process, and do not stop at entry point.
Greg Clayton6f907e62011-01-23 17:46:22 +0000215 error = lldb.SBError()
Johnny Chend762ff12011-02-03 23:15:53 +0000216 self.process = target.Launch (self.dbg.GetListener(), None, None, os.ctermid(), os.ctermid(), os.ctermid(), None, 0, False, error)
Jim Ingham5949cfe2010-12-15 20:47:34 +0000217
Johnny Chen4ebd0192011-05-24 18:22:45 +0000218 self.assertTrue(self.process, PROCESS_IS_VALID)
Jim Ingham5949cfe2010-12-15 20:47:34 +0000219
220 # The stop reason of the thread should be breakpoint.
221 thread = self.process.GetThreadAtIndex(0)
222 if thread.GetStopReason() != lldb.eStopReasonBreakpoint:
Johnny Chende90f1d2011-04-27 17:43:07 +0000223 from lldbutil import stop_reason_to_str
Jim Ingham5949cfe2010-12-15 20:47:34 +0000224 self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS %
Johnny Chende90f1d2011-04-27 17:43:07 +0000225 stop_reason_to_str(thread.GetStopReason()))
Jim Ingham5949cfe2010-12-15 20:47:34 +0000226
227 # Make sure we stopped at the first breakpoint.
228
229 cur_frame = thread.GetFrameAtIndex(0)
230
231 line_number = cur_frame.GetLineEntry().GetLine()
232 self.assertTrue (line_number == self.line, "Hit the first breakpoint.")
233
234 my_var = cur_frame.FindVariable("my")
Johnny Chen4ebd0192011-05-24 18:22:45 +0000235 self.assertTrue(my_var, "Made a variable object for my")
Jim Ingham5949cfe2010-12-15 20:47:34 +0000236
237 str_var = cur_frame.FindVariable("str")
Johnny Chen4ebd0192011-05-24 18:22:45 +0000238 self.assertTrue(str_var, "Made a variable object for str")
Jim Ingham5949cfe2010-12-15 20:47:34 +0000239
240 # Now make sure that the my->str == str:
241
242 my_str_var = my_var.GetChildMemberWithName("str")
Johnny Chen4ebd0192011-05-24 18:22:45 +0000243 self.assertTrue(my_str_var, "Found a str ivar in my")
Jim Ingham5949cfe2010-12-15 20:47:34 +0000244
245 str_value = int(str_var.GetValue(cur_frame), 0)
246
247 my_str_value = int(my_str_var.GetValue(cur_frame), 0)
248
249 self.assertTrue(str_value == my_str_value, "Got the correct value for my->str")
250
Johnny Chen6c17c082010-09-16 20:54:06 +0000251if __name__ == '__main__':
252 import atexit
253 lldb.SBDebugger.Initialize()
254 atexit.register(lambda: lldb.SBDebugger.Terminate())
255 unittest2.main()