1*99451b44SJordan Rupprecht""" 2*99451b44SJordan RupprechtTest that SBProcess.LoadImageUsingPaths works correctly. 3*99451b44SJordan Rupprecht""" 4*99451b44SJordan Rupprecht 5*99451b44SJordan Rupprecht 6*99451b44SJordan Rupprecht 7*99451b44SJordan Rupprechtimport os 8*99451b44SJordan Rupprechtimport lldb 9*99451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 10*99451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 11*99451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 12*99451b44SJordan Rupprecht 13*99451b44SJordan Rupprecht 14*99451b44SJordan Rupprecht@skipIfWindows # The Windows platform doesn't implement DoLoadImage. 15*99451b44SJordan Rupprechtclass LoadUsingPathsTestCase(TestBase): 16*99451b44SJordan Rupprecht 17*99451b44SJordan Rupprecht mydir = TestBase.compute_mydir(__file__) 18*99451b44SJordan Rupprecht 19*99451b44SJordan Rupprecht NO_DEBUG_INFO_TESTCASE = True 20*99451b44SJordan Rupprecht 21*99451b44SJordan Rupprecht def setUp(self): 22*99451b44SJordan Rupprecht # Call super's setUp(). 23*99451b44SJordan Rupprecht TestBase.setUp(self) 24*99451b44SJordan Rupprecht # Make the hidden directory in the build hierarchy: 25*99451b44SJordan Rupprecht lldbutil.mkdir_p(self.getBuildArtifact("hidden")) 26*99451b44SJordan Rupprecht 27*99451b44SJordan Rupprecht # Invoke the default build rule. 28*99451b44SJordan Rupprecht self.build() 29*99451b44SJordan Rupprecht 30*99451b44SJordan Rupprecht ext = 'so' 31*99451b44SJordan Rupprecht if self.platformIsDarwin(): 32*99451b44SJordan Rupprecht ext = 'dylib' 33*99451b44SJordan Rupprecht self.lib_name = 'libloadunload.' + ext 34*99451b44SJordan Rupprecht 35*99451b44SJordan Rupprecht self.wd = os.path.realpath(self.getBuildDir()) 36*99451b44SJordan Rupprecht self.hidden_dir = os.path.join(self.wd, 'hidden') 37*99451b44SJordan Rupprecht self.hidden_lib = os.path.join(self.hidden_dir, self.lib_name) 38*99451b44SJordan Rupprecht 39*99451b44SJordan Rupprecht @skipIfFreeBSD # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support 40*99451b44SJordan Rupprecht @not_remote_testsuite_ready 41*99451b44SJordan Rupprecht @skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently 42*99451b44SJordan Rupprecht @expectedFlakeyNetBSD 43*99451b44SJordan Rupprecht def test_load_using_paths(self): 44*99451b44SJordan Rupprecht """Test that we can load a module by providing a set of search paths.""" 45*99451b44SJordan Rupprecht if self.platformIsDarwin(): 46*99451b44SJordan Rupprecht dylibName = 'libloadunload_d.dylib' 47*99451b44SJordan Rupprecht else: 48*99451b44SJordan Rupprecht dylibName = 'libloadunload_d.so' 49*99451b44SJordan Rupprecht 50*99451b44SJordan Rupprecht # The directory with the dynamic library we did not link to. 51*99451b44SJordan Rupprecht path_dir = os.path.join(self.getBuildDir(), "hidden") 52*99451b44SJordan Rupprecht 53*99451b44SJordan Rupprecht (target, process, thread, 54*99451b44SJordan Rupprecht _) = lldbutil.run_to_source_breakpoint(self, 55*99451b44SJordan Rupprecht "Break here to do the load using paths", 56*99451b44SJordan Rupprecht lldb.SBFileSpec("main.cpp")) 57*99451b44SJordan Rupprecht error = lldb.SBError() 58*99451b44SJordan Rupprecht lib_spec = lldb.SBFileSpec(self.lib_name) 59*99451b44SJordan Rupprecht paths = lldb.SBStringList() 60*99451b44SJordan Rupprecht paths.AppendString(self.wd) 61*99451b44SJordan Rupprecht paths.AppendString(os.path.join(self.wd, "no_such_dir")) 62*99451b44SJordan Rupprecht 63*99451b44SJordan Rupprecht out_spec = lldb.SBFileSpec() 64*99451b44SJordan Rupprecht 65*99451b44SJordan Rupprecht # First try with no correct directories on the path, and make sure that doesn't blow up: 66*99451b44SJordan Rupprecht token = process.LoadImageUsingPaths(lib_spec, paths, out_spec, error) 67*99451b44SJordan Rupprecht self.assertEqual(token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Only looked on the provided path.") 68*99451b44SJordan Rupprecht 69*99451b44SJordan Rupprecht # Now add the correct dir to the paths list and try again: 70*99451b44SJordan Rupprecht paths.AppendString(self.hidden_dir) 71*99451b44SJordan Rupprecht token = process.LoadImageUsingPaths(lib_spec, paths, out_spec, error) 72*99451b44SJordan Rupprecht 73*99451b44SJordan Rupprecht self.assertNotEqual(token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Got a valid token") 74*99451b44SJordan Rupprecht self.assertEqual(out_spec, lldb.SBFileSpec(self.hidden_lib), "Found the expected library") 75*99451b44SJordan Rupprecht 76*99451b44SJordan Rupprecht # Make sure this really is in the image list: 77*99451b44SJordan Rupprecht loaded_module = target.FindModule(out_spec) 78*99451b44SJordan Rupprecht 79*99451b44SJordan Rupprecht self.assertTrue(loaded_module.IsValid(), "The loaded module is in the image list.") 80*99451b44SJordan Rupprecht 81*99451b44SJordan Rupprecht # Now see that we can call a function in the loaded module. 82*99451b44SJordan Rupprecht value = thread.frames[0].EvaluateExpression("d_function()", lldb.SBExpressionOptions()) 83*99451b44SJordan Rupprecht self.assertTrue(value.GetError().Success(), "Got a value from the expression") 84*99451b44SJordan Rupprecht ret_val = value.GetValueAsSigned() 85*99451b44SJordan Rupprecht self.assertEqual(ret_val, 12345, "Got the right value") 86*99451b44SJordan Rupprecht 87*99451b44SJordan Rupprecht # Make sure the token works to unload it: 88*99451b44SJordan Rupprecht process.UnloadImage(token) 89*99451b44SJordan Rupprecht 90*99451b44SJordan Rupprecht # Make sure this really is no longer in the image list: 91*99451b44SJordan Rupprecht loaded_module = target.FindModule(out_spec) 92*99451b44SJordan Rupprecht 93*99451b44SJordan Rupprecht self.assertFalse(loaded_module.IsValid(), "The unloaded module is no longer in the image list.") 94*99451b44SJordan Rupprecht 95*99451b44SJordan Rupprecht # Make sure a relative path also works: 96*99451b44SJordan Rupprecht paths.Clear() 97*99451b44SJordan Rupprecht paths.AppendString(os.path.join(self.wd, "no_such_dir")) 98*99451b44SJordan Rupprecht paths.AppendString(self.wd) 99*99451b44SJordan Rupprecht relative_spec = lldb.SBFileSpec(os.path.join("hidden", self.lib_name)) 100*99451b44SJordan Rupprecht 101*99451b44SJordan Rupprecht out_spec = lldb.SBFileSpec() 102*99451b44SJordan Rupprecht token = process.LoadImageUsingPaths(relative_spec, paths, out_spec, error) 103*99451b44SJordan Rupprecht 104*99451b44SJordan Rupprecht self.assertNotEqual(token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Got a valid token with relative path") 105*99451b44SJordan Rupprecht self.assertEqual(out_spec, lldb.SBFileSpec(self.hidden_lib), "Found the expected library with relative path") 106*99451b44SJordan Rupprecht 107*99451b44SJordan Rupprecht process.UnloadImage(token) 108*99451b44SJordan Rupprecht 109*99451b44SJordan Rupprecht # Make sure the presence of an empty path doesn't mess anything up: 110*99451b44SJordan Rupprecht paths.Clear() 111*99451b44SJordan Rupprecht paths.AppendString("") 112*99451b44SJordan Rupprecht paths.AppendString(os.path.join(self.wd, "no_such_dir")) 113*99451b44SJordan Rupprecht paths.AppendString(self.wd) 114*99451b44SJordan Rupprecht relative_spec = lldb.SBFileSpec(os.path.join("hidden", self.lib_name)) 115*99451b44SJordan Rupprecht 116*99451b44SJordan Rupprecht out_spec = lldb.SBFileSpec() 117*99451b44SJordan Rupprecht token = process.LoadImageUsingPaths(relative_spec, paths, out_spec, error) 118*99451b44SJordan Rupprecht 119*99451b44SJordan Rupprecht self.assertNotEqual(token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Got a valid token with included empty path") 120*99451b44SJordan Rupprecht self.assertEqual(out_spec, lldb.SBFileSpec(self.hidden_lib), "Found the expected library with included empty path") 121*99451b44SJordan Rupprecht 122*99451b44SJordan Rupprecht process.UnloadImage(token) 123*99451b44SJordan Rupprecht 124*99451b44SJordan Rupprecht 125*99451b44SJordan Rupprecht 126*99451b44SJordan Rupprecht # Finally, passing in an absolute path should work like the basename: 127*99451b44SJordan Rupprecht # This should NOT work because we've taken hidden_dir off the paths: 128*99451b44SJordan Rupprecht abs_spec = lldb.SBFileSpec(os.path.join(self.hidden_dir, self.lib_name)) 129*99451b44SJordan Rupprecht 130*99451b44SJordan Rupprecht token = process.LoadImageUsingPaths(lib_spec, paths, out_spec, error) 131*99451b44SJordan Rupprecht self.assertEqual(token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Only looked on the provided path.") 132*99451b44SJordan Rupprecht 133*99451b44SJordan Rupprecht # But it should work when we add the dir: 134*99451b44SJordan Rupprecht # Now add the correct dir to the paths list and try again: 135*99451b44SJordan Rupprecht paths.AppendString(self.hidden_dir) 136*99451b44SJordan Rupprecht token = process.LoadImageUsingPaths(lib_spec, paths, out_spec, error) 137*99451b44SJordan Rupprecht 138*99451b44SJordan Rupprecht self.assertNotEqual(token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Got a valid token") 139*99451b44SJordan Rupprecht self.assertEqual(out_spec, lldb.SBFileSpec(self.hidden_lib), "Found the expected library") 140*99451b44SJordan Rupprecht 141*99451b44SJordan Rupprecht 142