xref: /llvm-project/lldb/test/API/commands/expression/weak_symbols/TestWeakSymbols.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest that we can compile expressions referring to
399451b44SJordan Rupprechtabsent weak symbols from a dylib.
499451b44SJordan Rupprecht"""
599451b44SJordan Rupprecht
699451b44SJordan Rupprecht
799451b44SJordan Rupprechtimport os
899451b44SJordan Rupprechtimport lldb
9db5b960eSAdrian Prantlfrom lldbsuite.test.decorators import *
1099451b44SJordan Rupprechtimport lldbsuite.test.lldbutil as lldbutil
1199451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
1299451b44SJordan Rupprecht
1399451b44SJordan Rupprecht
1499451b44SJordan Rupprechtclass TestWeakSymbolsInExpressions(TestBase):
1599451b44SJordan Rupprecht    NO_DEBUG_INFO_TESTCASE = True
1699451b44SJordan Rupprecht
17db5b960eSAdrian Prantl    @skipUnlessDarwin
18*2238dcc3SJonas Devlieghere    @skipIf(compiler="clang", compiler_version=["<", "7.0"])
1999451b44SJordan Rupprecht    def test_weak_symbol_in_expr(self):
2099451b44SJordan Rupprecht        """Tests that we can refer to weak symbols in expressions."""
2199451b44SJordan Rupprecht        self.build()
2299451b44SJordan Rupprecht        self.main_source_file = lldb.SBFileSpec("main.c")
2399451b44SJordan Rupprecht        self.do_test()
2499451b44SJordan Rupprecht
2599451b44SJordan Rupprecht    def run_weak_var_check(self, weak_varname, present):
2699451b44SJordan Rupprecht        # The expression will modify present_weak_int to signify which branch
2799451b44SJordan Rupprecht        # was taken.  Set it to so we don't get confused by a previous run.
2899451b44SJordan Rupprecht        value = self.target.FindFirstGlobalVariable("present_weak_int")
2999451b44SJordan Rupprecht        value.SetValueFromCString("0")
3099451b44SJordan Rupprecht        if present:
3199451b44SJordan Rupprecht            correct_value = 10
3299451b44SJordan Rupprecht        else:
3399451b44SJordan Rupprecht            correct_value = 20
3499451b44SJordan Rupprecht
3599451b44SJordan Rupprecht        # Note, I'm adding the "; 10" at the end of the expression to work around
3699451b44SJordan Rupprecht        # the bug that expressions with no result currently return False for Success()...
37*2238dcc3SJonas Devlieghere        expr = (
38*2238dcc3SJonas Devlieghere            "if (&"
39*2238dcc3SJonas Devlieghere            + weak_varname
40*2238dcc3SJonas Devlieghere            + " != NULL) { present_weak_int = 10; } else { present_weak_int = 20;}; 10"
41*2238dcc3SJonas Devlieghere        )
4299451b44SJordan Rupprecht        result = self.frame.EvaluateExpression(expr)
4335674976SPavel Labath        self.assertSuccess(result.GetError(), "absent_weak_int expr failed")
44*2238dcc3SJonas Devlieghere        self.assertEqual(
45*2238dcc3SJonas Devlieghere            value.GetValueAsSigned(),
46*2238dcc3SJonas Devlieghere            correct_value,
47*2238dcc3SJonas Devlieghere            "Didn't change present_weak_int correctly.",
48*2238dcc3SJonas Devlieghere        )
4999451b44SJordan Rupprecht
5099451b44SJordan Rupprecht    def do_test(self):
5199451b44SJordan Rupprecht        hidden_dir = os.path.join(self.getBuildDir(), "hidden")
5299451b44SJordan Rupprecht        hidden_dylib = os.path.join(hidden_dir, "libdylib.dylib")
5399451b44SJordan Rupprecht
5499451b44SJordan Rupprecht        launch_info = lldb.SBLaunchInfo(None)
5599451b44SJordan Rupprecht        launch_info.SetWorkingDirectory(self.getBuildDir())
56254e0abfSJonas Devlieghere        launch_info.SetLaunchFlags(lldb.eLaunchFlagInheritTCCFromParent)
5799451b44SJordan Rupprecht
5899451b44SJordan Rupprecht        (self.target, _, thread, _) = lldbutil.run_to_source_breakpoint(
59*2238dcc3SJonas Devlieghere            self,
60*2238dcc3SJonas Devlieghere            "Set a breakpoint here",
6199451b44SJordan Rupprecht            self.main_source_file,
6299451b44SJordan Rupprecht            launch_info=launch_info,
63*2238dcc3SJonas Devlieghere            extra_images=[hidden_dylib],
64*2238dcc3SJonas Devlieghere        )
6599451b44SJordan Rupprecht        # First we have to import the Dylib module so we get the type info
6699451b44SJordan Rupprecht        # for the weak symbol.  We need to add the source dir to the module
6799451b44SJordan Rupprecht        # search paths, and then run @import to introduce it into the expression
6899451b44SJordan Rupprecht        # context:
69*2238dcc3SJonas Devlieghere        self.dbg.HandleCommand(
70*2238dcc3SJonas Devlieghere            "settings set target.clang-module-search-paths " + self.getSourceDir()
71*2238dcc3SJonas Devlieghere        )
7299451b44SJordan Rupprecht
7399451b44SJordan Rupprecht        self.frame = thread.frames[0]
7499451b44SJordan Rupprecht        self.assertTrue(self.frame.IsValid(), "Got a good frame")
7599451b44SJordan Rupprecht        options = lldb.SBExpressionOptions()
7699451b44SJordan Rupprecht        options.SetLanguage(lldb.eLanguageTypeObjC)
7799451b44SJordan Rupprecht        result = self.frame.EvaluateExpression("@import Dylib", options)
7899451b44SJordan Rupprecht
7999451b44SJordan Rupprecht        # Now run an expression that references an absent weak symbol:
8099451b44SJordan Rupprecht        self.run_weak_var_check("absent_weak_int", False)
8199451b44SJordan Rupprecht        self.run_weak_var_check("absent_weak_function", False)
8299451b44SJordan Rupprecht
8399451b44SJordan Rupprecht        # Make sure we can do the same thing with present weak symbols
8499451b44SJordan Rupprecht        self.run_weak_var_check("present_weak_int", True)
8599451b44SJordan Rupprecht        self.run_weak_var_check("present_weak_function", True)
86