1""" 2Test that we can compile expressions referring to 3absent weak symbols from a dylib. 4""" 5 6 7import os 8import lldb 9from lldbsuite.test.decorators import * 10import lldbsuite.test.lldbutil as lldbutil 11from lldbsuite.test.lldbtest import * 12 13 14class TestWeakSymbolsInExpressions(TestBase): 15 NO_DEBUG_INFO_TESTCASE = True 16 17 @skipUnlessDarwin 18 @skipIf(compiler="clang", compiler_version=["<", "7.0"]) 19 def test_weak_symbol_in_expr(self): 20 """Tests that we can refer to weak symbols in expressions.""" 21 self.build() 22 self.main_source_file = lldb.SBFileSpec("main.c") 23 self.do_test() 24 25 def run_weak_var_check(self, weak_varname, present): 26 # The expression will modify present_weak_int to signify which branch 27 # was taken. Set it to so we don't get confused by a previous run. 28 value = self.target.FindFirstGlobalVariable("present_weak_int") 29 value.SetValueFromCString("0") 30 if present: 31 correct_value = 10 32 else: 33 correct_value = 20 34 35 # Note, I'm adding the "; 10" at the end of the expression to work around 36 # the bug that expressions with no result currently return False for Success()... 37 expr = ( 38 "if (&" 39 + weak_varname 40 + " != NULL) { present_weak_int = 10; } else { present_weak_int = 20;}; 10" 41 ) 42 result = self.frame.EvaluateExpression(expr) 43 self.assertSuccess(result.GetError(), "absent_weak_int expr failed") 44 self.assertEqual( 45 value.GetValueAsSigned(), 46 correct_value, 47 "Didn't change present_weak_int correctly.", 48 ) 49 50 def do_test(self): 51 hidden_dir = os.path.join(self.getBuildDir(), "hidden") 52 hidden_dylib = os.path.join(hidden_dir, "libdylib.dylib") 53 54 launch_info = lldb.SBLaunchInfo(None) 55 launch_info.SetWorkingDirectory(self.getBuildDir()) 56 launch_info.SetLaunchFlags(lldb.eLaunchFlagInheritTCCFromParent) 57 58 (self.target, _, thread, _) = lldbutil.run_to_source_breakpoint( 59 self, 60 "Set a breakpoint here", 61 self.main_source_file, 62 launch_info=launch_info, 63 extra_images=[hidden_dylib], 64 ) 65 # First we have to import the Dylib module so we get the type info 66 # for the weak symbol. We need to add the source dir to the module 67 # search paths, and then run @import to introduce it into the expression 68 # context: 69 self.dbg.HandleCommand( 70 "settings set target.clang-module-search-paths " + self.getSourceDir() 71 ) 72 73 self.frame = thread.frames[0] 74 self.assertTrue(self.frame.IsValid(), "Got a good frame") 75 options = lldb.SBExpressionOptions() 76 options.SetLanguage(lldb.eLanguageTypeObjC) 77 result = self.frame.EvaluateExpression("@import Dylib", options) 78 79 # Now run an expression that references an absent weak symbol: 80 self.run_weak_var_check("absent_weak_int", False) 81 self.run_weak_var_check("absent_weak_function", False) 82 83 # Make sure we can do the same thing with present weak symbols 84 self.run_weak_var_check("present_weak_int", True) 85 self.run_weak_var_check("present_weak_function", True) 86