1"""
2Test some target commands: create, list, select, variable.
3"""
4
5import unittest2
6import lldb
7import sys
8from lldbtest import *
9import lldbutil
10
11class targetCommandTestCase(TestBase):
12
13    mydir = os.path.join("functionalities", "target_command")
14
15    def setUp(self):
16        # Call super's setUp().
17        TestBase.setUp(self)
18        # Find the line numbers for our breakpoints.
19        self.line_b = line_number('b.c', '// Set break point at this line.')
20        self.line_c = line_number('c.c', '// Set break point at this line.')
21
22    @dwarf_test
23    def test_target_command_with_dwarf(self):
24        """Test some target commands: create, list, select."""
25        da = {'C_SOURCES': 'a.c', 'EXE': 'a.out'}
26        self.buildDwarf(dictionary=da)
27        self.addTearDownCleanup(dictionary=da)
28
29        db = {'C_SOURCES': 'b.c', 'EXE': 'b.out'}
30        self.buildDwarf(dictionary=db)
31        self.addTearDownCleanup(dictionary=db)
32
33        dc = {'C_SOURCES': 'c.c', 'EXE': 'c.out'}
34        self.buildDwarf(dictionary=dc)
35        self.addTearDownCleanup(dictionary=dc)
36
37        self.do_target_command()
38
39    # rdar://problem/9763907
40    # 'target variable' command fails if the target program has been run
41    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
42    @dsym_test
43    def test_target_variable_command_with_dsym(self):
44        """Test 'target variable' command before and after starting the inferior."""
45        d = {'C_SOURCES': 'globals.c', 'EXE': 'globals'}
46        self.buildDsym(dictionary=d)
47        self.addTearDownCleanup(dictionary=d)
48
49        self.do_target_variable_command('globals')
50
51    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
52    @dsym_test
53    def test_target_variable_command_with_dsym_no_fail(self):
54        """Test 'target variable' command before and after starting the inferior."""
55        d = {'C_SOURCES': 'globals.c', 'EXE': 'globals'}
56        self.buildDsym(dictionary=d)
57        self.addTearDownCleanup(dictionary=d)
58
59        self.do_target_variable_command_no_fail('globals')
60
61    def do_target_command(self):
62        """Exercise 'target create', 'target list', 'target select' commands."""
63        exe_a = os.path.join(os.getcwd(), "a.out")
64        exe_b = os.path.join(os.getcwd(), "b.out")
65        exe_c = os.path.join(os.getcwd(), "c.out")
66
67        self.runCmd("target list")
68        output = self.res.GetOutput()
69        if output.startswith("No targets"):
70            # We start from index 0.
71            base = 0
72        else:
73            # Find the largest index of the existing list.
74            import re
75            pattern = re.compile("target #(\d+):")
76            for line in reversed(output.split(os.linesep)):
77                match = pattern.search(line)
78                if match:
79                    # We will start from (index + 1) ....
80                    base = int(match.group(1), 10) + 1
81                    #print "base is:", base
82                    break;
83
84        self.runCmd("target create " + exe_a, CURRENT_EXECUTABLE_SET)
85        self.runCmd("run", RUN_SUCCEEDED)
86
87        self.runCmd("target create " + exe_b, CURRENT_EXECUTABLE_SET)
88        lldbutil.run_break_set_by_file_and_line (self, 'b.c', self.line_b, num_expected_locations=1, loc_exact=True)
89        self.runCmd("run", RUN_SUCCEEDED)
90
91        self.runCmd("target create " + exe_c, CURRENT_EXECUTABLE_SET)
92        lldbutil.run_break_set_by_file_and_line (self, 'c.c', self.line_c, num_expected_locations=1, loc_exact=True)
93        self.runCmd("run", RUN_SUCCEEDED)
94
95        self.runCmd("target list")
96
97        self.runCmd("target select %d" % base)
98        self.runCmd("thread backtrace")
99
100        self.runCmd("target select %d" % (base + 2))
101        self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
102            substrs = ['c.c:%d' % self.line_c,
103                       'stop reason = breakpoint'])
104
105        self.runCmd("target select %d" % (base + 1))
106        self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
107            substrs = ['b.c:%d' % self.line_b,
108                       'stop reason = breakpoint'])
109
110        self.runCmd("target list")
111
112    def do_target_variable_command(self, exe_name):
113        """Exercise 'target variable' command before and after starting the inferior."""
114        self.runCmd("file " + exe_name, CURRENT_EXECUTABLE_SET)
115
116        self.expect("target variable my_global_char", VARIABLES_DISPLAYED_CORRECTLY,
117            substrs = ["my_global_char", "'X'"])
118        self.expect("target variable my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
119            substrs = ['my_global_str', '"abc"'])
120        self.expect("target variable my_static_int", VARIABLES_DISPLAYED_CORRECTLY,
121            substrs = ['my_static_int', '228'])
122        self.expect("target variable my_global_str_ptr", matching=False,
123                    substrs = ['"abc"'])
124        self.expect("target variable *my_global_str_ptr", matching=True,
125                    substrs = ['"abc"'])
126        self.expect("target variable *my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
127                    substrs = ['a'])
128
129        self.runCmd("b main")
130        self.runCmd("run")
131
132        self.expect("target variable my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
133                    substrs = ['my_global_str', '"abc"'])
134        self.expect("target variable my_static_int", VARIABLES_DISPLAYED_CORRECTLY,
135                    substrs = ['my_static_int', '228'])
136        self.expect("target variable my_global_str_ptr", matching=False,
137                    substrs = ['"abc"'])
138        self.expect("target variable *my_global_str_ptr", matching=True,
139                    substrs = ['"abc"'])
140        self.expect("target variable *my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
141                    substrs = ['a'])
142        self.expect("target variable my_global_char", VARIABLES_DISPLAYED_CORRECTLY,
143                    substrs = ["my_global_char", "'X'"])
144
145        self.runCmd("c")
146
147        # rdar://problem/9763907
148        # 'target variable' command fails if the target program has been run
149        self.expect("target variable my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
150            substrs = ['my_global_str', '"abc"'])
151        self.expect("target variable my_static_int", VARIABLES_DISPLAYED_CORRECTLY,
152            substrs = ['my_static_int', '228'])
153        self.expect("target variable my_global_str_ptr", matching=False,
154                    substrs = ['"abc"'])
155        self.expect("target variable *my_global_str_ptr", matching=True,
156                    substrs = ['"abc"'])
157        self.expect("target variable *my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
158                    substrs = ['a'])
159        self.expect("target variable my_global_char", VARIABLES_DISPLAYED_CORRECTLY,
160                    substrs = ["my_global_char", "'X'"])
161
162    def do_target_variable_command_no_fail(self, exe_name):
163        """Exercise 'target variable' command before and after starting the inferior."""
164        self.runCmd("file " + exe_name, CURRENT_EXECUTABLE_SET)
165
166        self.expect("target variable my_global_char", VARIABLES_DISPLAYED_CORRECTLY,
167            substrs = ["my_global_char", "'X'"])
168        self.expect("target variable my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
169            substrs = ['my_global_str', '"abc"'])
170        self.expect("target variable my_static_int", VARIABLES_DISPLAYED_CORRECTLY,
171            substrs = ['my_static_int', '228'])
172        self.expect("target variable my_global_str_ptr", matching=False,
173                    substrs = ['"abc"'])
174        self.expect("target variable *my_global_str_ptr", matching=True,
175                    substrs = ['"abc"'])
176        self.expect("target variable *my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
177                    substrs = ['a'])
178
179        self.runCmd("b main")
180        self.runCmd("run")
181
182        # New feature: you don't need to specify the variable(s) to 'target vaiable'.
183        # It will find all the global and static variables in the current compile unit.
184        self.expect("target variable",
185            substrs = ['my_global_char',
186                       'my_global_str',
187                       'my_global_str_ptr',
188                       'my_static_int'])
189
190        self.expect("target variable my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
191                    substrs = ['my_global_str', '"abc"'])
192        self.expect("target variable my_static_int", VARIABLES_DISPLAYED_CORRECTLY,
193                    substrs = ['my_static_int', '228'])
194        self.expect("target variable my_global_str_ptr", matching=False,
195                    substrs = ['"abc"'])
196        self.expect("target variable *my_global_str_ptr", matching=True,
197                    substrs = ['"abc"'])
198        self.expect("target variable *my_global_str", VARIABLES_DISPLAYED_CORRECTLY,
199                    substrs = ['a'])
200        self.expect("target variable my_global_char", VARIABLES_DISPLAYED_CORRECTLY,
201                    substrs = ["my_global_char", "'X'"])
202
203if __name__ == '__main__':
204    import atexit
205    lldb.SBDebugger.Initialize()
206    atexit.register(lambda: lldb.SBDebugger.Terminate())
207    unittest2.main()
208