1*9c95617cSMichael Buch""" 299451b44SJordan RupprechtTest that SBProcess.LoadImageUsingPaths works correctly. 399451b44SJordan Rupprecht""" 499451b44SJordan Rupprecht 599451b44SJordan Rupprecht 699451b44SJordan Rupprechtimport os 799451b44SJordan Rupprechtimport lldb 899451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 999451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 1099451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 1199451b44SJordan Rupprecht 1299451b44SJordan Rupprecht 1399451b44SJordan Rupprecht@skipIfWindows # The Windows platform doesn't implement DoLoadImage. 1499451b44SJordan Rupprechtclass LoadUsingPathsTestCase(TestBase): 1599451b44SJordan Rupprecht NO_DEBUG_INFO_TESTCASE = True 1699451b44SJordan Rupprecht 1799451b44SJordan Rupprecht def setUp(self): 1899451b44SJordan Rupprecht # Call super's setUp(). 1999451b44SJordan Rupprecht TestBase.setUp(self) 2099451b44SJordan Rupprecht # Make the hidden directory in the build hierarchy: 2199451b44SJordan Rupprecht lldbutil.mkdir_p(self.getBuildArtifact("hidden")) 2299451b44SJordan Rupprecht 2399451b44SJordan Rupprecht # Invoke the default build rule. 2499451b44SJordan Rupprecht self.build() 2599451b44SJordan Rupprecht 262238dcc3SJonas Devlieghere ext = "so" 2799451b44SJordan Rupprecht if self.platformIsDarwin(): 282238dcc3SJonas Devlieghere ext = "dylib" 292238dcc3SJonas Devlieghere self.lib_name = "libloadunload." + ext 3099451b44SJordan Rupprecht 3199451b44SJordan Rupprecht self.wd = os.path.realpath(self.getBuildDir()) 322238dcc3SJonas Devlieghere self.hidden_dir = os.path.join(self.wd, "hidden") 3399451b44SJordan Rupprecht self.hidden_lib = os.path.join(self.hidden_dir, self.lib_name) 3499451b44SJordan Rupprecht 3566ae40ebSRaphael Isemann @skipIfRemote 3699451b44SJordan Rupprecht @skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently 3799451b44SJordan Rupprecht @expectedFlakeyNetBSD 382238dcc3SJonas Devlieghere @expectedFailureAll(oslist=["linux"], archs=["arm"], bugnumber="llvm.org/pr45894") 3999451b44SJordan Rupprecht def test_load_using_paths(self): 4099451b44SJordan Rupprecht """Test that we can load a module by providing a set of search paths.""" 4199451b44SJordan Rupprecht if self.platformIsDarwin(): 422238dcc3SJonas Devlieghere dylibName = "libloadunload_d.dylib" 4399451b44SJordan Rupprecht else: 442238dcc3SJonas Devlieghere dylibName = "libloadunload_d.so" 4599451b44SJordan Rupprecht 4699451b44SJordan Rupprecht # The directory with the dynamic library we did not link to. 4799451b44SJordan Rupprecht path_dir = os.path.join(self.getBuildDir(), "hidden") 4899451b44SJordan Rupprecht 492238dcc3SJonas Devlieghere (target, process, thread, _) = lldbutil.run_to_source_breakpoint( 502238dcc3SJonas Devlieghere self, "Break here to do the load using paths", lldb.SBFileSpec("main.cpp") 512238dcc3SJonas Devlieghere ) 5299451b44SJordan Rupprecht error = lldb.SBError() 5399451b44SJordan Rupprecht lib_spec = lldb.SBFileSpec(self.lib_name) 5499451b44SJordan Rupprecht paths = lldb.SBStringList() 5599451b44SJordan Rupprecht paths.AppendString(self.wd) 5699451b44SJordan Rupprecht paths.AppendString(os.path.join(self.wd, "no_such_dir")) 5799451b44SJordan Rupprecht 5899451b44SJordan Rupprecht out_spec = lldb.SBFileSpec() 5999451b44SJordan Rupprecht 6099451b44SJordan Rupprecht # First try with no correct directories on the path, and make sure that doesn't blow up: 6199451b44SJordan Rupprecht token = process.LoadImageUsingPaths(lib_spec, paths, out_spec, error) 622238dcc3SJonas Devlieghere self.assertEqual( 632238dcc3SJonas Devlieghere token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Only looked on the provided path." 642238dcc3SJonas Devlieghere ) 65f7588597SJim Ingham # Make sure we got some error back in this case. Since we don't actually know what 66f7588597SJim Ingham # the error will look like, let's look for the absence of "unknown reasons". 67f7588597SJim Ingham error_str = error.description 68f7588597SJim Ingham self.assertNotEqual(len(error_str), 0, "Got an empty error string") 692238dcc3SJonas Devlieghere self.assertNotIn( 702238dcc3SJonas Devlieghere "unknown reasons", error_str, "Error string had unknown reasons" 712238dcc3SJonas Devlieghere ) 7299451b44SJordan Rupprecht 7399451b44SJordan Rupprecht # Now add the correct dir to the paths list and try again: 7499451b44SJordan Rupprecht paths.AppendString(self.hidden_dir) 7599451b44SJordan Rupprecht token = process.LoadImageUsingPaths(lib_spec, paths, out_spec, error) 7699451b44SJordan Rupprecht 7799451b44SJordan Rupprecht self.assertNotEqual(token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Got a valid token") 782238dcc3SJonas Devlieghere self.assertEqual( 792238dcc3SJonas Devlieghere out_spec, lldb.SBFileSpec(self.hidden_lib), "Found the expected library" 802238dcc3SJonas Devlieghere ) 8199451b44SJordan Rupprecht 8299451b44SJordan Rupprecht # Make sure this really is in the image list: 8399451b44SJordan Rupprecht loaded_module = target.FindModule(out_spec) 8499451b44SJordan Rupprecht 852238dcc3SJonas Devlieghere self.assertTrue( 862238dcc3SJonas Devlieghere loaded_module.IsValid(), "The loaded module is in the image list." 872238dcc3SJonas Devlieghere ) 8899451b44SJordan Rupprecht 8999451b44SJordan Rupprecht # Now see that we can call a function in the loaded module. 902238dcc3SJonas Devlieghere value = thread.frames[0].EvaluateExpression( 912238dcc3SJonas Devlieghere "d_function()", lldb.SBExpressionOptions() 922238dcc3SJonas Devlieghere ) 93779bbbf2SDave Lee self.assertSuccess(value.GetError(), "Got a value from the expression") 9499451b44SJordan Rupprecht ret_val = value.GetValueAsSigned() 9599451b44SJordan Rupprecht self.assertEqual(ret_val, 12345, "Got the right value") 9699451b44SJordan Rupprecht 9799451b44SJordan Rupprecht # Make sure the token works to unload it: 9899451b44SJordan Rupprecht process.UnloadImage(token) 9999451b44SJordan Rupprecht 10099451b44SJordan Rupprecht # Make sure this really is no longer in the image list: 10199451b44SJordan Rupprecht loaded_module = target.FindModule(out_spec) 10299451b44SJordan Rupprecht 1032238dcc3SJonas Devlieghere self.assertFalse( 1042238dcc3SJonas Devlieghere loaded_module.IsValid(), 1052238dcc3SJonas Devlieghere "The unloaded module is no longer in the image list.", 1062238dcc3SJonas Devlieghere ) 10799451b44SJordan Rupprecht 10899451b44SJordan Rupprecht # Make sure a relative path also works: 10999451b44SJordan Rupprecht paths.Clear() 11099451b44SJordan Rupprecht paths.AppendString(os.path.join(self.wd, "no_such_dir")) 11199451b44SJordan Rupprecht paths.AppendString(self.wd) 11299451b44SJordan Rupprecht relative_spec = lldb.SBFileSpec(os.path.join("hidden", self.lib_name)) 11399451b44SJordan Rupprecht 11499451b44SJordan Rupprecht out_spec = lldb.SBFileSpec() 11599451b44SJordan Rupprecht token = process.LoadImageUsingPaths(relative_spec, paths, out_spec, error) 11699451b44SJordan Rupprecht 1172238dcc3SJonas Devlieghere self.assertNotEqual( 1182238dcc3SJonas Devlieghere token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Got a valid token with relative path" 1192238dcc3SJonas Devlieghere ) 1202238dcc3SJonas Devlieghere self.assertEqual( 1212238dcc3SJonas Devlieghere out_spec, 1222238dcc3SJonas Devlieghere lldb.SBFileSpec(self.hidden_lib), 1232238dcc3SJonas Devlieghere "Found the expected library with relative path", 1242238dcc3SJonas Devlieghere ) 12599451b44SJordan Rupprecht 12699451b44SJordan Rupprecht process.UnloadImage(token) 12799451b44SJordan Rupprecht 12899451b44SJordan Rupprecht # Make sure the presence of an empty path doesn't mess anything up: 12999451b44SJordan Rupprecht paths.Clear() 13099451b44SJordan Rupprecht paths.AppendString("") 13199451b44SJordan Rupprecht paths.AppendString(os.path.join(self.wd, "no_such_dir")) 13299451b44SJordan Rupprecht paths.AppendString(self.wd) 13399451b44SJordan Rupprecht relative_spec = lldb.SBFileSpec(os.path.join("hidden", self.lib_name)) 13499451b44SJordan Rupprecht 13599451b44SJordan Rupprecht out_spec = lldb.SBFileSpec() 13699451b44SJordan Rupprecht token = process.LoadImageUsingPaths(relative_spec, paths, out_spec, error) 13799451b44SJordan Rupprecht 1382238dcc3SJonas Devlieghere self.assertNotEqual( 1392238dcc3SJonas Devlieghere token, 1402238dcc3SJonas Devlieghere lldb.LLDB_INVALID_IMAGE_TOKEN, 1412238dcc3SJonas Devlieghere "Got a valid token with included empty path", 1422238dcc3SJonas Devlieghere ) 1432238dcc3SJonas Devlieghere self.assertEqual( 1442238dcc3SJonas Devlieghere out_spec, 1452238dcc3SJonas Devlieghere lldb.SBFileSpec(self.hidden_lib), 1462238dcc3SJonas Devlieghere "Found the expected library with included empty path", 1472238dcc3SJonas Devlieghere ) 14899451b44SJordan Rupprecht 14999451b44SJordan Rupprecht process.UnloadImage(token) 15099451b44SJordan Rupprecht 15199451b44SJordan Rupprecht # Finally, passing in an absolute path should work like the basename: 15299451b44SJordan Rupprecht # This should NOT work because we've taken hidden_dir off the paths: 15399451b44SJordan Rupprecht abs_spec = lldb.SBFileSpec(os.path.join(self.hidden_dir, self.lib_name)) 15499451b44SJordan Rupprecht 15599451b44SJordan Rupprecht token = process.LoadImageUsingPaths(lib_spec, paths, out_spec, error) 1562238dcc3SJonas Devlieghere self.assertEqual( 1572238dcc3SJonas Devlieghere token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Only looked on the provided path." 1582238dcc3SJonas Devlieghere ) 15999451b44SJordan Rupprecht 16099451b44SJordan Rupprecht # But it should work when we add the dir: 16199451b44SJordan Rupprecht # Now add the correct dir to the paths list and try again: 16299451b44SJordan Rupprecht paths.AppendString(self.hidden_dir) 16399451b44SJordan Rupprecht token = process.LoadImageUsingPaths(lib_spec, paths, out_spec, error) 16499451b44SJordan Rupprecht 16599451b44SJordan Rupprecht self.assertNotEqual(token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Got a valid token") 1662238dcc3SJonas Devlieghere self.assertEqual( 1672238dcc3SJonas Devlieghere out_spec, lldb.SBFileSpec(self.hidden_lib), "Found the expected library" 1682238dcc3SJonas Devlieghere ) 169