blob: face35e9a445ec74971fdbb514e1dedcbd19edcc [file] [log] [blame]
Johnny Chen843f6892010-07-07 21:10:55 +00001"""
Johnny Chenb2017362010-12-14 22:26:34 +00002Test that breakpoint by symbol name works correctly with dynamic libs.
Johnny Chen843f6892010-07-07 21:10:55 +00003"""
4
5import os, time
Johnny Chen55e1bdf2010-12-06 21:08:51 +00006import re
Johnny Chen75e28f92010-08-05 23:42:46 +00007import unittest2
Johnny Chen843f6892010-07-07 21:10:55 +00008import lldb
Johnny Chend85dae52010-08-09 23:44:24 +00009from lldbtest import *
Johnny Chen843f6892010-07-07 21:10:55 +000010
Johnny Chen1c42e862010-09-01 19:59:58 +000011class LoadUnloadTestCase(TestBase):
Johnny Chen843f6892010-07-07 21:10:55 +000012
13 mydir = "load_unload"
14
Johnny Chen55e1bdf2010-12-06 21:08:51 +000015 def setUp(self):
16 # Call super's setUp().
17 TestBase.setUp(self)
18 # Find the line number to break for main.cpp.
19 self.line = line_number('main.c',
20 '// Set break point at this line for test_lldb_process_load_and_unload_commands().')
Johnny Chenb2017362010-12-14 22:26:34 +000021 self.line_d_function = line_number('d.c',
22 '// Find this line number within d_dunction().')
23
Johnny Chen9157f5d2011-05-06 23:59:10 +000024 def test_modules_search_paths(self):
25 """Test target modules list after moving libd.dylib, and verifies that it works with 'target modules search-paths add'."""
Johnny Chen4d661352011-02-03 00:30:19 +000026
27 # Invoke the default build rule.
28 self.buildDefault()
29
30 if sys.platform.startswith("darwin"):
31 dylibName = 'libd.dylib'
32
33 # Now let's move the dynamic library to a different directory than $CWD.
34
35 # The directory to relocate the dynamic library to.
36 new_dir = os.path.join(os.getcwd(), "dyld_path")
37
38 # This is the function to remove the dyld_path directory after the test.
39 def remove_dyld_dir():
40 import shutil
41 shutil.rmtree(new_dir)
42
43 old_dylib = os.path.join(os.getcwd(), dylibName)
44 new_dylib = os.path.join(new_dir, dylibName)
45
46 os.mkdir(new_dir)
47 os.rename(old_dylib, new_dylib)
48 self.addTearDownHook(remove_dyld_dir)
49
50 exe = os.path.join(os.getcwd(), "a.out")
51 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
Johnny Chen13f96c32011-05-03 22:32:16 +000052
Johnny Chen9157f5d2011-05-06 23:59:10 +000053 self.expect("target modules list",
Johnny Chen4d661352011-02-03 00:30:19 +000054 substrs = [old_dylib])
Johnny Chen9157f5d2011-05-06 23:59:10 +000055 self.expect("target modules list -t 3",
Johnny Chen2edbaa22011-05-03 18:53:19 +000056 patterns = ["%s-[^-]*-[^-]*" % self.getArchitecture()])
Johnny Chen9157f5d2011-05-06 23:59:10 +000057 self.runCmd("target modules search-paths add %s %s" % (os.getcwd(), new_dir))
58
59 self.expect("target modules search-paths list",
60 substrs = [os.getcwd(), new_dir])
61
Johnny Chen7acdcec2011-02-03 18:03:54 +000062 # Add teardown hook to clear image-search-paths after the test.
Johnny Chen9157f5d2011-05-06 23:59:10 +000063 self.addTearDownHook(lambda: self.runCmd("target modules search-paths clear"))
64 self.expect("target modules list", "LLDB successfully locates the relocated dynamic library",
Johnny Chen4d661352011-02-03 00:30:19 +000065 substrs = [new_dylib])
66
67
Johnny Chenb2017362010-12-14 22:26:34 +000068 def test_dyld_library_path(self):
69 """Test DYLD_LIBRARY_PATH after moving libd.dylib, which defines d_function, somewhere else."""
70
71 # Invoke the default build rule.
72 self.buildDefault()
73
74 if sys.platform.startswith("darwin"):
75 dylibName = 'libd.dylib'
76 dsymName = 'libd.dylib.dSYM'
77 dylibPath = 'DYLD_LIBRARY_PATH'
78
79 # Now let's move the dynamic library to a different directory than $CWD.
80
81 # The directory to relocate the dynamic library and its debugging info.
82 new_dir = os.path.join(os.getcwd(), "dyld_path")
83
84 # This is the function to remove the dyld_path directory after the test.
Johnny Chenec882742010-12-14 23:13:03 +000085 def remove_dyld_dir():
Johnny Chenb2017362010-12-14 22:26:34 +000086 import shutil
87 shutil.rmtree(new_dir)
88
89 old_dylib = os.path.join(os.getcwd(), dylibName)
90 new_dylib = os.path.join(new_dir, dylibName)
91 old_dSYM = os.path.join(os.getcwd(), dsymName)
92 new_dSYM = os.path.join(new_dir, dsymName)
93 #system(["ls", "-lR", "."])
94 os.mkdir(new_dir)
95 os.rename(old_dylib, new_dylib)
96 if dsymName:
97 os.rename(old_dSYM, new_dSYM)
Johnny Chenec882742010-12-14 23:13:03 +000098 self.addTearDownHook(remove_dyld_dir)
Johnny Chenb2017362010-12-14 22:26:34 +000099 #system(["ls", "-lR", "."])
100
101 # With libd.dylib moved, a.out run should fail.
102 exe = os.path.join(os.getcwd(), "a.out")
103 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
104 # Set breakpoint by function name d_function.
105 self.expect("breakpoint set -n d_function", BREAKPOINT_CREATED,
106 substrs = ["Breakpoint created",
107 "name = 'd_function'",
108 "locations = 0 (pending)"])
109 self.runCmd("run")
110 self.expect("process status", "Not expected to hit the d_function breakpoint",
111 matching=False,
112 substrs = ["stop reason = breakpoint"])
113 # Kill the inferior process.
114 self.runCmd("process kill")
115
116 # Try again with the DYLD_LIBRARY_PATH environment variable properly set.
117 os.environ[dylibPath] = new_dir
Johnny Chenec882742010-12-14 23:13:03 +0000118 self.addTearDownHook(lambda: os.environ.pop(dylibPath))
Johnny Chenb2017362010-12-14 22:26:34 +0000119 self.runCmd("run")
120 self.expect("thread backtrace", STOPPED_DUE_TO_BREAKPOINT,
121 patterns = ["frame #0.*d_function.*at d.c:%d" % self.line_d_function])
Johnny Chen55e1bdf2010-12-06 21:08:51 +0000122
123 def test_lldb_process_load_and_unload_commands(self):
124 """Test that lldb process load/unload command work correctly."""
125
126 # Invoke the default build rule.
127 self.buildDefault()
128
129 exe = os.path.join(os.getcwd(), "a.out")
130 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
131
132 # Break at main.c before the call to dlopen().
133 # Use lldb's process load command to load the dylib, instead.
134
135 self.expect("breakpoint set -f main.c -l %d" % self.line,
136 BREAKPOINT_CREATED,
137 startstr = "Breakpoint created: 1: file ='main.c', line = %d" %
138 self.line)
139
140 self.runCmd("run", RUN_SUCCEEDED)
141
142 # Make sure that a_function does not exist at this point.
143 self.expect("image lookup -n a_function", "a_function should not exist yet",
144 error=True, matching=False,
145 patterns = ["1 match found .* %s" % self.mydir])
146
147 # Use lldb 'process load' to load the dylib.
148 self.expect("process load liba.dylib", "liba.dylib loaded correctly",
149 patterns = ['Loading "liba.dylib".*ok',
150 'Image [0-9]+ loaded'])
151
152 # Search for and match the "Image ([0-9]+) loaded" pattern.
153 output = self.res.GetOutput()
154 pattern = re.compile("Image ([0-9]+) loaded")
155 for l in output.split(os.linesep):
156 #print "l:", l
157 match = pattern.search(l)
158 if match:
159 break
160 index = match.group(1)
161
162 # Now we should have an entry for a_function.
163 self.expect("image lookup -n a_function", "a_function should now exist",
164 patterns = ["1 match found .*%s" % self.mydir])
165
166 # Use lldb 'process unload' to unload the dylib.
167 self.expect("process unload %s" % index, "liba.dylib unloaded correctly",
168 patterns = ["Unloading .* with index %s.*ok" % index])
169
170 self.runCmd("process continue")
171
Johnny Chen30974392010-07-27 20:59:06 +0000172 def test_load_unload(self):
Johnny Chen843f6892010-07-07 21:10:55 +0000173 """Test breakpoint by name works correctly with dlopen'ing."""
Johnny Chen821a8c42010-09-03 23:52:15 +0000174
175 # Invoke the default build rule.
176 self.buildDefault()
177
Johnny Chen843f6892010-07-07 21:10:55 +0000178 exe = os.path.join(os.getcwd(), "a.out")
Johnny Chen029acae2010-08-20 21:03:09 +0000179 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
Johnny Chen843f6892010-07-07 21:10:55 +0000180
181 # Break by function name a_function (not yet loaded).
Johnny Chen029acae2010-08-20 21:03:09 +0000182 self.expect("breakpoint set -n a_function", BREAKPOINT_CREATED,
183 startstr = "Breakpoint created: 1: name = 'a_function', locations = 0 (pending)")
Johnny Chen843f6892010-07-07 21:10:55 +0000184
Johnny Chen1bb9f9a2010-08-27 23:47:36 +0000185 self.runCmd("run", RUN_SUCCEEDED)
Johnny Chen843f6892010-07-07 21:10:55 +0000186
187 # The stop reason of the thread should be breakpoint and at a_function.
Johnny Chen029acae2010-08-20 21:03:09 +0000188 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
Greg Claytonabe0fed2011-04-18 08:33:37 +0000189 substrs = ['stopped',
Johnny Chen029acae2010-08-20 21:03:09 +0000190 'a_function',
Johnny Chen029acae2010-08-20 21:03:09 +0000191 'stop reason = breakpoint'])
Johnny Chen843f6892010-07-07 21:10:55 +0000192
193 # The breakpoint should have a hit count of 1.
Caroline Tice41950cc2011-02-04 22:59:41 +0000194 self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
Johnny Chen029acae2010-08-20 21:03:09 +0000195 substrs = [' resolved, hit count = 1'])
Johnny Chen843f6892010-07-07 21:10:55 +0000196
Johnny Chen14df3d42010-10-04 16:58:16 +0000197 # Issue the 'contnue' command. We should stop agaian at a_function.
198 # The stop reason of the thread should be breakpoint and at a_function.
199 self.runCmd("continue")
Johnny Chenc958be42010-10-20 21:56:26 +0000200
201 # rdar://problem/8508987
202 # The a_function breakpoint should be encountered twice.
Johnny Chen14df3d42010-10-04 16:58:16 +0000203 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
Greg Claytonabe0fed2011-04-18 08:33:37 +0000204 substrs = ['stopped',
Johnny Chen14df3d42010-10-04 16:58:16 +0000205 'a_function',
206 'stop reason = breakpoint'])
207
208 # The breakpoint should have a hit count of 2.
Caroline Tice41950cc2011-02-04 22:59:41 +0000209 self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE,
Johnny Chen14df3d42010-10-04 16:58:16 +0000210 substrs = [' resolved, hit count = 2'])
Johnny Chen843f6892010-07-07 21:10:55 +0000211
212
213if __name__ == '__main__':
Johnny Chen88f83042010-08-05 21:23:45 +0000214 import atexit
Johnny Chen843f6892010-07-07 21:10:55 +0000215 lldb.SBDebugger.Initialize()
Johnny Chen88f83042010-08-05 21:23:45 +0000216 atexit.register(lambda: lldb.SBDebugger.Terminate())
Johnny Chen75e28f92010-08-05 23:42:46 +0000217 unittest2.main()