169 lines · python
1"""2Test that SBProcess.LoadImageUsingPaths works correctly.3"""4 5 6import os7import lldb8from lldbsuite.test.decorators import *9from lldbsuite.test.lldbtest import *10from lldbsuite.test import lldbutil11 12 13@skipIfWindows # The Windows platform doesn't implement DoLoadImage.14class LoadUsingPathsTestCase(TestBase):15 NO_DEBUG_INFO_TESTCASE = True16 17 def setUp(self):18 # Call super's setUp().19 TestBase.setUp(self)20 # Make the hidden directory in the build hierarchy:21 lldbutil.mkdir_p(self.getBuildArtifact("hidden"))22 23 # Invoke the default build rule.24 self.build()25 26 ext = "so"27 if self.platformIsDarwin():28 ext = "dylib"29 self.lib_name = "libloadunload." + ext30 31 self.wd = os.path.realpath(self.getBuildDir())32 self.hidden_dir = os.path.join(self.wd, "hidden")33 self.hidden_lib = os.path.join(self.hidden_dir, self.lib_name)34 35 @skipIfRemote36 @skipIfWindows # Windows doesn't have dlopen and friends, dynamic libraries work differently37 @expectedFlakeyNetBSD38 @expectedFailureAll(oslist=["linux"], archs=["arm$"], bugnumber="llvm.org/pr45894")39 def test_load_using_paths(self):40 """Test that we can load a module by providing a set of search paths."""41 if self.platformIsDarwin():42 dylibName = "libloadunload_d.dylib"43 else:44 dylibName = "libloadunload_d.so"45 46 # The directory with the dynamic library we did not link to.47 path_dir = os.path.join(self.getBuildDir(), "hidden")48 49 (target, process, thread, _) = lldbutil.run_to_source_breakpoint(50 self, "Break here to do the load using paths", lldb.SBFileSpec("main.cpp")51 )52 error = lldb.SBError()53 lib_spec = lldb.SBFileSpec(self.lib_name)54 paths = lldb.SBStringList()55 paths.AppendString(self.wd)56 paths.AppendString(os.path.join(self.wd, "no_such_dir"))57 58 out_spec = lldb.SBFileSpec()59 60 # First try with no correct directories on the path, and make sure that doesn't blow up:61 token = process.LoadImageUsingPaths(lib_spec, paths, out_spec, error)62 self.assertEqual(63 token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Only looked on the provided path."64 )65 # Make sure we got some error back in this case. Since we don't actually know what66 # the error will look like, let's look for the absence of "unknown reasons".67 error_str = error.description68 self.assertNotEqual(len(error_str), 0, "Got an empty error string")69 self.assertNotIn(70 "unknown reasons", error_str, "Error string had unknown reasons"71 )72 73 # Now add the correct dir to the paths list and try again:74 paths.AppendString(self.hidden_dir)75 token = process.LoadImageUsingPaths(lib_spec, paths, out_spec, error)76 77 self.assertNotEqual(token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Got a valid token")78 self.assertEqual(79 out_spec, lldb.SBFileSpec(self.hidden_lib), "Found the expected library"80 )81 82 # Make sure this really is in the image list:83 loaded_module = target.FindModule(out_spec)84 85 self.assertTrue(86 loaded_module.IsValid(), "The loaded module is in the image list."87 )88 89 # Now see that we can call a function in the loaded module.90 value = thread.frames[0].EvaluateExpression(91 "d_function()", lldb.SBExpressionOptions()92 )93 self.assertSuccess(value.GetError(), "Got a value from the expression")94 ret_val = value.GetValueAsSigned()95 self.assertEqual(ret_val, 12345, "Got the right value")96 97 # Make sure the token works to unload it:98 process.UnloadImage(token)99 100 # Make sure this really is no longer in the image list:101 loaded_module = target.FindModule(out_spec)102 103 self.assertFalse(104 loaded_module.IsValid(),105 "The unloaded module is no longer in the image list.",106 )107 108 # Make sure a relative path also works:109 paths.Clear()110 paths.AppendString(os.path.join(self.wd, "no_such_dir"))111 paths.AppendString(self.wd)112 relative_spec = lldb.SBFileSpec(os.path.join("hidden", self.lib_name))113 114 out_spec = lldb.SBFileSpec()115 token = process.LoadImageUsingPaths(relative_spec, paths, out_spec, error)116 117 self.assertNotEqual(118 token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Got a valid token with relative path"119 )120 self.assertEqual(121 out_spec,122 lldb.SBFileSpec(self.hidden_lib),123 "Found the expected library with relative path",124 )125 126 process.UnloadImage(token)127 128 # Make sure the presence of an empty path doesn't mess anything up:129 paths.Clear()130 paths.AppendString("")131 paths.AppendString(os.path.join(self.wd, "no_such_dir"))132 paths.AppendString(self.wd)133 relative_spec = lldb.SBFileSpec(os.path.join("hidden", self.lib_name))134 135 out_spec = lldb.SBFileSpec()136 token = process.LoadImageUsingPaths(relative_spec, paths, out_spec, error)137 138 self.assertNotEqual(139 token,140 lldb.LLDB_INVALID_IMAGE_TOKEN,141 "Got a valid token with included empty path",142 )143 self.assertEqual(144 out_spec,145 lldb.SBFileSpec(self.hidden_lib),146 "Found the expected library with included empty path",147 )148 149 process.UnloadImage(token)150 151 # Finally, passing in an absolute path should work like the basename:152 # This should NOT work because we've taken hidden_dir off the paths:153 abs_spec = lldb.SBFileSpec(os.path.join(self.hidden_dir, self.lib_name))154 155 token = process.LoadImageUsingPaths(lib_spec, paths, out_spec, error)156 self.assertEqual(157 token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Only looked on the provided path."158 )159 160 # But it should work when we add the dir:161 # Now add the correct dir to the paths list and try again:162 paths.AppendString(self.hidden_dir)163 token = process.LoadImageUsingPaths(lib_spec, paths, out_spec, error)164 165 self.assertNotEqual(token, lldb.LLDB_INVALID_IMAGE_TOKEN, "Got a valid token")166 self.assertEqual(167 out_spec, lldb.SBFileSpec(self.hidden_lib), "Found the expected library"168 )169