199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtTest that breakpoint by symbol name works correctly with dynamic libs. 399451b44SJordan Rupprecht""" 499451b44SJordan Rupprecht 599451b44SJordan Rupprechtfrom __future__ import print_function 699451b44SJordan Rupprecht 799451b44SJordan Rupprecht 899451b44SJordan Rupprechtimport os 999451b44SJordan Rupprechtimport re 1099451b44SJordan Rupprechtimport lldb 1199451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 1299451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 1399451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 1499451b44SJordan Rupprecht 1599451b44SJordan Rupprecht 1699451b44SJordan Rupprechtclass LoadUnloadTestCase(TestBase): 1799451b44SJordan Rupprecht 1899451b44SJordan Rupprecht NO_DEBUG_INFO_TESTCASE = True 1999451b44SJordan Rupprecht 2099451b44SJordan Rupprecht def setUp(self): 2199451b44SJordan Rupprecht # Call super's setUp(). 2299451b44SJordan Rupprecht TestBase.setUp(self) 2399451b44SJordan Rupprecht self.setup_test() 2499451b44SJordan Rupprecht # Invoke the default build rule. 2599451b44SJordan Rupprecht self.build() 2699451b44SJordan Rupprecht # Find the line number to break for main.cpp. 2799451b44SJordan Rupprecht self.line = line_number( 2899451b44SJordan Rupprecht 'main.cpp', 2999451b44SJordan Rupprecht '// Set break point at this line for test_lldb_process_load_and_unload_commands().') 3099451b44SJordan Rupprecht self.line_d_function = line_number( 3199451b44SJordan Rupprecht 'd.cpp', '// Find this line number within d_dunction().') 3299451b44SJordan Rupprecht 3399451b44SJordan Rupprecht def setup_test(self): 3499451b44SJordan Rupprecht lldbutil.mkdir_p(self.getBuildArtifact("hidden")) 3599451b44SJordan Rupprecht if lldb.remote_platform: 36e0dbd025SPavel Labath path = lldb.remote_platform.GetWorkingDirectory() 3799451b44SJordan Rupprecht else: 38e0dbd025SPavel Labath path = self.getBuildDir() 39e0dbd025SPavel Labath if self.dylibPath in os.environ: 40e0dbd025SPavel Labath sep = self.platformContext.shlib_path_separator 41e0dbd025SPavel Labath path = os.environ[self.dylibPath] + sep + path 42e0dbd025SPavel Labath self.runCmd("settings append target.env-vars '{}={}'".format(self.dylibPath, path)) 43e0dbd025SPavel Labath self.default_path = path 4499451b44SJordan Rupprecht 4599451b44SJordan Rupprecht def copy_shlibs_to_remote(self, hidden_dir=False): 4699451b44SJordan Rupprecht """ Copies the shared libs required by this test suite to remote. 4799451b44SJordan Rupprecht Does nothing in case of non-remote platforms. 4899451b44SJordan Rupprecht """ 4999451b44SJordan Rupprecht if lldb.remote_platform: 5099451b44SJordan Rupprecht ext = 'so' 5199451b44SJordan Rupprecht if self.platformIsDarwin(): 5299451b44SJordan Rupprecht ext = 'dylib' 5399451b44SJordan Rupprecht 5499451b44SJordan Rupprecht shlibs = ['libloadunload_a.' + ext, 'libloadunload_b.' + ext, 5599451b44SJordan Rupprecht 'libloadunload_c.' + ext, 'libloadunload_d.' + ext] 5699451b44SJordan Rupprecht wd = lldb.remote_platform.GetWorkingDirectory() 5799451b44SJordan Rupprecht cwd = os.getcwd() 5899451b44SJordan Rupprecht for f in shlibs: 5999451b44SJordan Rupprecht err = lldb.remote_platform.Put( 6099451b44SJordan Rupprecht lldb.SBFileSpec(self.getBuildArtifact(f)), 6199451b44SJordan Rupprecht lldb.SBFileSpec(os.path.join(wd, f))) 6299451b44SJordan Rupprecht if err.Fail(): 6399451b44SJordan Rupprecht raise RuntimeError( 6499451b44SJordan Rupprecht "Unable copy '%s' to '%s'.\n>>> %s" % 6599451b44SJordan Rupprecht (f, wd, err.GetCString())) 6699451b44SJordan Rupprecht if hidden_dir: 6799451b44SJordan Rupprecht shlib = 'libloadunload_d.' + ext 6899451b44SJordan Rupprecht hidden_dir = os.path.join(wd, 'hidden') 6999451b44SJordan Rupprecht hidden_file = os.path.join(hidden_dir, shlib) 7099451b44SJordan Rupprecht err = lldb.remote_platform.MakeDirectory(hidden_dir) 7199451b44SJordan Rupprecht if err.Fail(): 7299451b44SJordan Rupprecht raise RuntimeError( 7399451b44SJordan Rupprecht "Unable to create a directory '%s'." % hidden_dir) 7499451b44SJordan Rupprecht err = lldb.remote_platform.Put( 7599451b44SJordan Rupprecht lldb.SBFileSpec(os.path.join('hidden', shlib)), 7699451b44SJordan Rupprecht lldb.SBFileSpec(hidden_file)) 7799451b44SJordan Rupprecht if err.Fail(): 7899451b44SJordan Rupprecht raise RuntimeError( 7999451b44SJordan Rupprecht "Unable copy 'libloadunload_d.so' to '%s'.\n>>> %s" % 8099451b44SJordan Rupprecht (wd, err.GetCString())) 8199451b44SJordan Rupprecht 8299451b44SJordan Rupprecht def setSvr4Support(self, enabled): 8399451b44SJordan Rupprecht self.runCmd( 8499451b44SJordan Rupprecht "settings set plugin.process.gdb-remote.use-libraries-svr4 {enabled}".format( 8599451b44SJordan Rupprecht enabled="true" if enabled else "false" 8699451b44SJordan Rupprecht ) 8799451b44SJordan Rupprecht ) 8899451b44SJordan Rupprecht 8999451b44SJordan Rupprecht # libloadunload_d.so does not appear in the image list because executable 9099451b44SJordan Rupprecht # dependencies are resolved relative to the debuggers PWD. Bug? 912c2eb5e6SMichał Górny @expectedFailureAll(oslist=["freebsd", "linux", "netbsd"]) 9266ae40ebSRaphael Isemann @skipIfRemote 9399451b44SJordan Rupprecht @skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently 9499451b44SJordan Rupprecht def test_modules_search_paths(self): 9599451b44SJordan Rupprecht """Test target modules list after loading a different copy of the library libd.dylib, and verifies that it works with 'target modules search-paths add'.""" 9699451b44SJordan Rupprecht if self.platformIsDarwin(): 9799451b44SJordan Rupprecht dylibName = 'libloadunload_d.dylib' 9899451b44SJordan Rupprecht else: 9999451b44SJordan Rupprecht dylibName = 'libloadunload_d.so' 10099451b44SJordan Rupprecht 10199451b44SJordan Rupprecht # The directory with the dynamic library we did not link to. 10299451b44SJordan Rupprecht new_dir = os.path.join(self.getBuildDir(), "hidden") 10399451b44SJordan Rupprecht 10499451b44SJordan Rupprecht old_dylib = os.path.join(self.getBuildDir(), dylibName) 10599451b44SJordan Rupprecht new_dylib = os.path.join(new_dir, dylibName) 10699451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 10799451b44SJordan Rupprecht self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 10899451b44SJordan Rupprecht 10999451b44SJordan Rupprecht self.expect("target modules list", 11099451b44SJordan Rupprecht substrs=[old_dylib]) 11199451b44SJordan Rupprecht # self.expect("target modules list -t 3", 11299451b44SJordan Rupprecht # patterns = ["%s-[^-]*-[^-]*" % self.getArchitecture()]) 11399451b44SJordan Rupprecht # Add an image search path substitution pair. 11499451b44SJordan Rupprecht self.runCmd( 11599451b44SJordan Rupprecht "target modules search-paths add %s %s" % 11699451b44SJordan Rupprecht (self.getBuildDir(), new_dir)) 11799451b44SJordan Rupprecht 11899451b44SJordan Rupprecht self.expect("target modules search-paths list", 11999451b44SJordan Rupprecht substrs=[self.getBuildDir(), new_dir]) 12099451b44SJordan Rupprecht 12199451b44SJordan Rupprecht self.expect( 12299451b44SJordan Rupprecht "target modules search-paths query %s" % 12399451b44SJordan Rupprecht self.getBuildDir(), 12499451b44SJordan Rupprecht "Image search path successfully transformed", 12599451b44SJordan Rupprecht substrs=[new_dir]) 12699451b44SJordan Rupprecht 12799451b44SJordan Rupprecht # Obliterate traces of libd from the old location. 12899451b44SJordan Rupprecht os.remove(old_dylib) 12999451b44SJordan Rupprecht # Inform (DY)LD_LIBRARY_PATH of the new path, too. 130e0dbd025SPavel Labath env_cmd_string = "settings replace target.env-vars " + self.dylibPath + "=" + new_dir 13199451b44SJordan Rupprecht if self.TraceOn(): 13299451b44SJordan Rupprecht print("Set environment to: ", env_cmd_string) 13399451b44SJordan Rupprecht self.runCmd(env_cmd_string) 13499451b44SJordan Rupprecht self.runCmd("settings show target.env-vars") 13599451b44SJordan Rupprecht 13699451b44SJordan Rupprecht self.runCmd("run") 13799451b44SJordan Rupprecht 13899451b44SJordan Rupprecht self.expect( 13999451b44SJordan Rupprecht "target modules list", 14099451b44SJordan Rupprecht "LLDB successfully locates the relocated dynamic library", 14199451b44SJordan Rupprecht substrs=[new_dylib]) 14299451b44SJordan Rupprecht 14399451b44SJordan Rupprecht # libloadunload_d.so does not appear in the image list because executable 14499451b44SJordan Rupprecht # dependencies are resolved relative to the debuggers PWD. Bug? 1452c2eb5e6SMichał Górny @expectedFailureAll(oslist=["freebsd", "linux", "netbsd"]) 14699451b44SJordan Rupprecht @expectedFailureAndroid # wrong source file shows up for hidden library 14799451b44SJordan Rupprecht @skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently 14899451b44SJordan Rupprecht @skipIfDarwinEmbedded 14999451b44SJordan Rupprecht def test_dyld_library_path(self): 15099451b44SJordan Rupprecht """Test (DY)LD_LIBRARY_PATH after moving libd.dylib, which defines d_function, somewhere else.""" 15199451b44SJordan Rupprecht self.copy_shlibs_to_remote(hidden_dir=True) 15299451b44SJordan Rupprecht 15399451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 15499451b44SJordan Rupprecht self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 15599451b44SJordan Rupprecht 15699451b44SJordan Rupprecht # Shut off ANSI color usage so we don't get ANSI escape sequences 15799451b44SJordan Rupprecht # mixed in with stop locations. 15899451b44SJordan Rupprecht self.dbg.SetUseColor(False) 15999451b44SJordan Rupprecht 16099451b44SJordan Rupprecht if self.platformIsDarwin(): 16199451b44SJordan Rupprecht dylibName = 'libloadunload_d.dylib' 16299451b44SJordan Rupprecht dsymName = 'libloadunload_d.dylib.dSYM' 16399451b44SJordan Rupprecht else: 16499451b44SJordan Rupprecht dylibName = 'libloadunload_d.so' 16599451b44SJordan Rupprecht 16699451b44SJordan Rupprecht # The directory to relocate the dynamic library and its debugging info. 16799451b44SJordan Rupprecht special_dir = "hidden" 16899451b44SJordan Rupprecht if lldb.remote_platform: 16999451b44SJordan Rupprecht wd = lldb.remote_platform.GetWorkingDirectory() 17099451b44SJordan Rupprecht else: 17199451b44SJordan Rupprecht wd = self.getBuildDir() 17299451b44SJordan Rupprecht 17399451b44SJordan Rupprecht old_dir = wd 17499451b44SJordan Rupprecht new_dir = os.path.join(wd, special_dir) 17599451b44SJordan Rupprecht old_dylib = os.path.join(old_dir, dylibName) 17699451b44SJordan Rupprecht 17799451b44SJordan Rupprecht # For now we don't track (DY)LD_LIBRARY_PATH, so the old 17899451b44SJordan Rupprecht # library will be in the modules list. 17999451b44SJordan Rupprecht self.expect("target modules list", 18099451b44SJordan Rupprecht substrs=[os.path.basename(old_dylib)], 18199451b44SJordan Rupprecht matching=True) 18299451b44SJordan Rupprecht 18399451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 18499451b44SJordan Rupprecht self, "d.cpp", self.line_d_function, num_expected_locations=1) 18599451b44SJordan Rupprecht # After run, make sure the non-hidden library is picked up. 18699451b44SJordan Rupprecht self.expect("run", substrs=["return", "700"]) 18799451b44SJordan Rupprecht 18899451b44SJordan Rupprecht self.runCmd("continue") 18999451b44SJordan Rupprecht 19099451b44SJordan Rupprecht # Add the hidden directory first in the search path. 191e0dbd025SPavel Labath env_cmd_string = ("settings set target.env-vars %s=%s%s%s" % 192e0dbd025SPavel Labath (self.dylibPath, new_dir, 193e0dbd025SPavel Labath self.platformContext.shlib_path_separator, self.default_path)) 19499451b44SJordan Rupprecht self.runCmd(env_cmd_string) 19599451b44SJordan Rupprecht 19699451b44SJordan Rupprecht # This time, the hidden library should be picked up. 19799451b44SJordan Rupprecht self.expect("run", substrs=["return", "12345"]) 19899451b44SJordan Rupprecht 19999451b44SJordan Rupprecht @expectedFailureAll( 20099451b44SJordan Rupprecht bugnumber="llvm.org/pr25805", 20199451b44SJordan Rupprecht hostoslist=["windows"], 20299451b44SJordan Rupprecht triple='.*-android') 203e0dbd025SPavel Labath @expectedFailureAll(oslist=["windows"]) # process load not implemented 20499451b44SJordan Rupprecht def test_lldb_process_load_and_unload_commands(self): 20599451b44SJordan Rupprecht self.setSvr4Support(False) 20699451b44SJordan Rupprecht self.run_lldb_process_load_and_unload_commands() 20799451b44SJordan Rupprecht 20899451b44SJordan Rupprecht @expectedFailureAll( 20999451b44SJordan Rupprecht bugnumber="llvm.org/pr25805", 21099451b44SJordan Rupprecht hostoslist=["windows"], 21199451b44SJordan Rupprecht triple='.*-android') 212e0dbd025SPavel Labath @expectedFailureAll(oslist=["windows"]) # process load not implemented 21399451b44SJordan Rupprecht def test_lldb_process_load_and_unload_commands_with_svr4(self): 21499451b44SJordan Rupprecht self.setSvr4Support(True) 21599451b44SJordan Rupprecht self.run_lldb_process_load_and_unload_commands() 21699451b44SJordan Rupprecht 21799451b44SJordan Rupprecht def run_lldb_process_load_and_unload_commands(self): 21899451b44SJordan Rupprecht """Test that lldb process load/unload command work correctly.""" 21999451b44SJordan Rupprecht self.copy_shlibs_to_remote() 22099451b44SJordan Rupprecht 22199451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 22299451b44SJordan Rupprecht self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 22399451b44SJordan Rupprecht 22499451b44SJordan Rupprecht # Break at main.cpp before the call to dlopen(). 22599451b44SJordan Rupprecht # Use lldb's process load command to load the dylib, instead. 22699451b44SJordan Rupprecht 22799451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 22899451b44SJordan Rupprecht self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) 22999451b44SJordan Rupprecht 23099451b44SJordan Rupprecht self.runCmd("run", RUN_SUCCEEDED) 23199451b44SJordan Rupprecht 23299451b44SJordan Rupprecht ctx = self.platformContext 23399451b44SJordan Rupprecht dylibName = ctx.shlib_prefix + 'loadunload_a.' + ctx.shlib_extension 23499451b44SJordan Rupprecht localDylibPath = self.getBuildArtifact(dylibName) 23599451b44SJordan Rupprecht if lldb.remote_platform: 23699451b44SJordan Rupprecht wd = lldb.remote_platform.GetWorkingDirectory() 23799451b44SJordan Rupprecht remoteDylibPath = lldbutil.join_remote_paths(wd, dylibName) 23899451b44SJordan Rupprecht else: 23999451b44SJordan Rupprecht remoteDylibPath = localDylibPath 24099451b44SJordan Rupprecht 241f7588597SJim Ingham # First make sure that we get some kind of error if process load fails. 242f7588597SJim Ingham # We print some error even if the load fails, which isn't formalized. 243f7588597SJim Ingham # The only plugin at present (Posix) that supports this says "unknown reasons". 244f7588597SJim Ingham # If another plugin shows up, let's require it uses "unknown error" as well. 245f7588597SJim Ingham non_existant_shlib = "/NoSuchDir/NoSuchSubdir/ReallyNo/NotAFile" 246f7588597SJim Ingham self.expect("process load %s"%(non_existant_shlib), error=True, matching=False, 247f7588597SJim Ingham patterns=["unknown reasons"]) 248f7588597SJim Ingham 249f7588597SJim Ingham 25099451b44SJordan Rupprecht # Make sure that a_function does not exist at this point. 25199451b44SJordan Rupprecht self.expect( 25299451b44SJordan Rupprecht "image lookup -n a_function", 25399451b44SJordan Rupprecht "a_function should not exist yet", 25499451b44SJordan Rupprecht error=True, 25599451b44SJordan Rupprecht matching=False, 25699451b44SJordan Rupprecht patterns=["1 match found"]) 25799451b44SJordan Rupprecht 25899451b44SJordan Rupprecht # Use lldb 'process load' to load the dylib. 25999451b44SJordan Rupprecht self.expect( 26099451b44SJordan Rupprecht "process load %s --install=%s" % (localDylibPath, remoteDylibPath), 26199451b44SJordan Rupprecht "%s loaded correctly" % dylibName, 26299451b44SJordan Rupprecht patterns=[ 26399451b44SJordan Rupprecht 'Loading "%s".*ok' % re.escape(localDylibPath), 26499451b44SJordan Rupprecht 'Image [0-9]+ loaded']) 26599451b44SJordan Rupprecht 26699451b44SJordan Rupprecht # Search for and match the "Image ([0-9]+) loaded" pattern. 26799451b44SJordan Rupprecht output = self.res.GetOutput() 26899451b44SJordan Rupprecht pattern = re.compile("Image ([0-9]+) loaded") 26999451b44SJordan Rupprecht for l in output.split(os.linesep): 270b321b429SJonas Devlieghere self.trace("l:", l) 27199451b44SJordan Rupprecht match = pattern.search(l) 27299451b44SJordan Rupprecht if match: 27399451b44SJordan Rupprecht break 27499451b44SJordan Rupprecht index = match.group(1) 27599451b44SJordan Rupprecht 27699451b44SJordan Rupprecht # Now we should have an entry for a_function. 27799451b44SJordan Rupprecht self.expect( 27899451b44SJordan Rupprecht "image lookup -n a_function", 27999451b44SJordan Rupprecht "a_function should now exist", 28099451b44SJordan Rupprecht patterns=[ 28199451b44SJordan Rupprecht "1 match found .*%s" % 28299451b44SJordan Rupprecht dylibName]) 28399451b44SJordan Rupprecht 28499451b44SJordan Rupprecht # Use lldb 'process unload' to unload the dylib. 28599451b44SJordan Rupprecht self.expect( 28699451b44SJordan Rupprecht "process unload %s" % 28799451b44SJordan Rupprecht index, 28899451b44SJordan Rupprecht "%s unloaded correctly" % 28999451b44SJordan Rupprecht dylibName, 29099451b44SJordan Rupprecht patterns=[ 29199451b44SJordan Rupprecht "Unloading .* with index %s.*ok" % 29299451b44SJordan Rupprecht index]) 29399451b44SJordan Rupprecht 29499451b44SJordan Rupprecht self.runCmd("process continue") 29599451b44SJordan Rupprecht 296e0dbd025SPavel Labath @expectedFailureAll(oslist=["windows"]) # breakpoint not hit 29799451b44SJordan Rupprecht def test_load_unload(self): 29899451b44SJordan Rupprecht self.setSvr4Support(False) 29999451b44SJordan Rupprecht self.run_load_unload() 30099451b44SJordan Rupprecht 301e0dbd025SPavel Labath @expectedFailureAll(oslist=["windows"]) # breakpoint not hit 30299451b44SJordan Rupprecht def test_load_unload_with_svr4(self): 30399451b44SJordan Rupprecht self.setSvr4Support(True) 30499451b44SJordan Rupprecht self.run_load_unload() 30599451b44SJordan Rupprecht 30699451b44SJordan Rupprecht def run_load_unload(self): 30799451b44SJordan Rupprecht """Test breakpoint by name works correctly with dlopen'ing.""" 30899451b44SJordan Rupprecht self.copy_shlibs_to_remote() 30999451b44SJordan Rupprecht 31099451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 31199451b44SJordan Rupprecht self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 31299451b44SJordan Rupprecht 31399451b44SJordan Rupprecht # Break by function name a_function (not yet loaded). 31499451b44SJordan Rupprecht lldbutil.run_break_set_by_symbol( 31599451b44SJordan Rupprecht self, "a_function", num_expected_locations=0) 31699451b44SJordan Rupprecht 31799451b44SJordan Rupprecht self.runCmd("run", RUN_SUCCEEDED) 31899451b44SJordan Rupprecht 31999451b44SJordan Rupprecht # The stop reason of the thread should be breakpoint and at a_function. 32099451b44SJordan Rupprecht self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 32199451b44SJordan Rupprecht substrs=['stopped', 32299451b44SJordan Rupprecht 'a_function', 32399451b44SJordan Rupprecht 'stop reason = breakpoint']) 32499451b44SJordan Rupprecht 32599451b44SJordan Rupprecht # The breakpoint should have a hit count of 1. 3269f0b5f9aSSYNOPSYS\georgiev lldbutil.check_breakpoint(self, bpno = 1, expected_hit_count = 1) 32799451b44SJordan Rupprecht 328e9264b74SKazuaki Ishizaki # Issue the 'continue' command. We should stop agaian at a_function. 32999451b44SJordan Rupprecht # The stop reason of the thread should be breakpoint and at a_function. 33099451b44SJordan Rupprecht self.runCmd("continue") 33199451b44SJordan Rupprecht 33299451b44SJordan Rupprecht # rdar://problem/8508987 33399451b44SJordan Rupprecht # The a_function breakpoint should be encountered twice. 33499451b44SJordan Rupprecht self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 33599451b44SJordan Rupprecht substrs=['stopped', 33699451b44SJordan Rupprecht 'a_function', 33799451b44SJordan Rupprecht 'stop reason = breakpoint']) 33899451b44SJordan Rupprecht 33999451b44SJordan Rupprecht # The breakpoint should have a hit count of 2. 3409f0b5f9aSSYNOPSYS\georgiev lldbutil.check_breakpoint(self, bpno = 1, expected_hit_count = 2) 34199451b44SJordan Rupprecht 34299451b44SJordan Rupprecht def test_step_over_load(self): 34399451b44SJordan Rupprecht self.setSvr4Support(False) 34499451b44SJordan Rupprecht self.run_step_over_load() 34599451b44SJordan Rupprecht 34699451b44SJordan Rupprecht def test_step_over_load_with_svr4(self): 34799451b44SJordan Rupprecht self.setSvr4Support(True) 34899451b44SJordan Rupprecht self.run_step_over_load() 34999451b44SJordan Rupprecht 35099451b44SJordan Rupprecht def run_step_over_load(self): 35199451b44SJordan Rupprecht """Test stepping over code that loads a shared library works correctly.""" 35299451b44SJordan Rupprecht self.copy_shlibs_to_remote() 35399451b44SJordan Rupprecht 35499451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 35599451b44SJordan Rupprecht self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 35699451b44SJordan Rupprecht 35799451b44SJordan Rupprecht # Break by function name a_function (not yet loaded). 35899451b44SJordan Rupprecht lldbutil.run_break_set_by_file_and_line( 35999451b44SJordan Rupprecht self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True) 36099451b44SJordan Rupprecht 36199451b44SJordan Rupprecht self.runCmd("run", RUN_SUCCEEDED) 36299451b44SJordan Rupprecht 36399451b44SJordan Rupprecht # The stop reason of the thread should be breakpoint and at a_function. 36499451b44SJordan Rupprecht self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 36599451b44SJordan Rupprecht substrs=['stopped', 36699451b44SJordan Rupprecht 'stop reason = breakpoint']) 36799451b44SJordan Rupprecht 36899451b44SJordan Rupprecht self.runCmd( 36999451b44SJordan Rupprecht "thread step-over", 37099451b44SJordan Rupprecht "Stepping over function that loads library") 37199451b44SJordan Rupprecht 37299451b44SJordan Rupprecht # The stop reason should be step end. 37399451b44SJordan Rupprecht self.expect("thread list", "step over succeeded.", 37499451b44SJordan Rupprecht substrs=['stopped', 37599451b44SJordan Rupprecht 'stop reason = step over']) 37699451b44SJordan Rupprecht 37799451b44SJordan Rupprecht # We can't find a breakpoint location for d_init before launching because 37899451b44SJordan Rupprecht # executable dependencies are resolved relative to the debuggers PWD. Bug? 3792c2eb5e6SMichał Górny @expectedFailureAll(oslist=["freebsd", "linux", "netbsd"], triple=no_match('aarch64-.*-android')) 380*b82b0187SMuhammad Omair Javaid @expectedFailureAll(oslist=["windows"], archs=["aarch64"]) 38199451b44SJordan Rupprecht def test_static_init_during_load(self): 38299451b44SJordan Rupprecht """Test that we can set breakpoints correctly in static initializers""" 38399451b44SJordan Rupprecht self.copy_shlibs_to_remote() 38499451b44SJordan Rupprecht 38599451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 38699451b44SJordan Rupprecht self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET) 38799451b44SJordan Rupprecht 38899451b44SJordan Rupprecht a_init_bp_num = lldbutil.run_break_set_by_symbol( 38999451b44SJordan Rupprecht self, "a_init", num_expected_locations=0) 39099451b44SJordan Rupprecht b_init_bp_num = lldbutil.run_break_set_by_symbol( 39199451b44SJordan Rupprecht self, "b_init", num_expected_locations=0) 39299451b44SJordan Rupprecht d_init_bp_num = lldbutil.run_break_set_by_symbol( 39399451b44SJordan Rupprecht self, "d_init", num_expected_locations=1) 39499451b44SJordan Rupprecht 39599451b44SJordan Rupprecht self.runCmd("run", RUN_SUCCEEDED) 39699451b44SJordan Rupprecht 39799451b44SJordan Rupprecht self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 39899451b44SJordan Rupprecht substrs=['stopped', 39999451b44SJordan Rupprecht 'd_init', 40099451b44SJordan Rupprecht 'stop reason = breakpoint %d' % d_init_bp_num]) 40199451b44SJordan Rupprecht 40299451b44SJordan Rupprecht self.runCmd("continue") 40399451b44SJordan Rupprecht self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 40499451b44SJordan Rupprecht substrs=['stopped', 40599451b44SJordan Rupprecht 'b_init', 40699451b44SJordan Rupprecht 'stop reason = breakpoint %d' % b_init_bp_num]) 40799451b44SJordan Rupprecht self.expect("thread backtrace", 40899451b44SJordan Rupprecht substrs=['b_init', 409e0dbd025SPavel Labath 'dylib_open', 41099451b44SJordan Rupprecht 'main']) 41199451b44SJordan Rupprecht 41299451b44SJordan Rupprecht self.runCmd("continue") 41399451b44SJordan Rupprecht self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 41499451b44SJordan Rupprecht substrs=['stopped', 41599451b44SJordan Rupprecht 'a_init', 41699451b44SJordan Rupprecht 'stop reason = breakpoint %d' % a_init_bp_num]) 41799451b44SJordan Rupprecht self.expect("thread backtrace", 41899451b44SJordan Rupprecht substrs=['a_init', 419e0dbd025SPavel Labath 'dylib_open', 42099451b44SJordan Rupprecht 'main']) 421