199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest that breakpoint by symbol name works correctly with dynamic libs.
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprecht
599451b44SJordan Rupprechtfrom __future__ import print_function
699451b44SJordan Rupprecht
799451b44SJordan Rupprecht
899451b44SJordan Rupprechtimport os
999451b44SJordan Rupprechtimport re
1099451b44SJordan Rupprechtimport lldb
1199451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
1299451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
1399451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil
1499451b44SJordan Rupprecht
1599451b44SJordan Rupprecht
1699451b44SJordan Rupprechtclass LoadUnloadTestCase(TestBase):
1799451b44SJordan Rupprecht
1899451b44SJordan Rupprecht    NO_DEBUG_INFO_TESTCASE = True
1999451b44SJordan Rupprecht
2099451b44SJordan Rupprecht    def setUp(self):
2199451b44SJordan Rupprecht        # Call super's setUp().
2299451b44SJordan Rupprecht        TestBase.setUp(self)
2399451b44SJordan Rupprecht        self.setup_test()
2499451b44SJordan Rupprecht        # Invoke the default build rule.
2599451b44SJordan Rupprecht        self.build()
2699451b44SJordan Rupprecht        # Find the line number to break for main.cpp.
2799451b44SJordan Rupprecht        self.line = line_number(
2899451b44SJordan Rupprecht            'main.cpp',
2999451b44SJordan Rupprecht            '// Set break point at this line for test_lldb_process_load_and_unload_commands().')
3099451b44SJordan Rupprecht        self.line_d_function = line_number(
3199451b44SJordan Rupprecht            'd.cpp', '// Find this line number within d_dunction().')
3299451b44SJordan Rupprecht
3399451b44SJordan Rupprecht    def setup_test(self):
3499451b44SJordan Rupprecht        lldbutil.mkdir_p(self.getBuildArtifact("hidden"))
3599451b44SJordan Rupprecht        if lldb.remote_platform:
36e0dbd025SPavel Labath            path = lldb.remote_platform.GetWorkingDirectory()
3799451b44SJordan Rupprecht        else:
38e0dbd025SPavel Labath            path = self.getBuildDir()
39e0dbd025SPavel Labath            if self.dylibPath in os.environ:
40e0dbd025SPavel Labath                sep = self.platformContext.shlib_path_separator
41e0dbd025SPavel Labath                path = os.environ[self.dylibPath] + sep + path
42e0dbd025SPavel Labath        self.runCmd("settings append target.env-vars '{}={}'".format(self.dylibPath, path))
43e0dbd025SPavel Labath        self.default_path = path
4499451b44SJordan Rupprecht
4599451b44SJordan Rupprecht    def copy_shlibs_to_remote(self, hidden_dir=False):
4699451b44SJordan Rupprecht        """ Copies the shared libs required by this test suite to remote.
4799451b44SJordan Rupprecht        Does nothing in case of non-remote platforms.
4899451b44SJordan Rupprecht        """
4999451b44SJordan Rupprecht        if lldb.remote_platform:
5099451b44SJordan Rupprecht            ext = 'so'
5199451b44SJordan Rupprecht            if self.platformIsDarwin():
5299451b44SJordan Rupprecht                ext = 'dylib'
5399451b44SJordan Rupprecht
5499451b44SJordan Rupprecht            shlibs = ['libloadunload_a.' + ext, 'libloadunload_b.' + ext,
5599451b44SJordan Rupprecht                      'libloadunload_c.' + ext, 'libloadunload_d.' + ext]
5699451b44SJordan Rupprecht            wd = lldb.remote_platform.GetWorkingDirectory()
5799451b44SJordan Rupprecht            cwd = os.getcwd()
5899451b44SJordan Rupprecht            for f in shlibs:
5999451b44SJordan Rupprecht                err = lldb.remote_platform.Put(
6099451b44SJordan Rupprecht                    lldb.SBFileSpec(self.getBuildArtifact(f)),
6199451b44SJordan Rupprecht                    lldb.SBFileSpec(os.path.join(wd, f)))
6299451b44SJordan Rupprecht                if err.Fail():
6399451b44SJordan Rupprecht                    raise RuntimeError(
6499451b44SJordan Rupprecht                        "Unable copy '%s' to '%s'.\n>>> %s" %
6599451b44SJordan Rupprecht                        (f, wd, err.GetCString()))
6699451b44SJordan Rupprecht            if hidden_dir:
6799451b44SJordan Rupprecht                shlib = 'libloadunload_d.' + ext
6899451b44SJordan Rupprecht                hidden_dir = os.path.join(wd, 'hidden')
6999451b44SJordan Rupprecht                hidden_file = os.path.join(hidden_dir, shlib)
7099451b44SJordan Rupprecht                err = lldb.remote_platform.MakeDirectory(hidden_dir)
7199451b44SJordan Rupprecht                if err.Fail():
7299451b44SJordan Rupprecht                    raise RuntimeError(
7399451b44SJordan Rupprecht                        "Unable to create a directory '%s'." % hidden_dir)
7499451b44SJordan Rupprecht                err = lldb.remote_platform.Put(
7599451b44SJordan Rupprecht                    lldb.SBFileSpec(os.path.join('hidden', shlib)),
7699451b44SJordan Rupprecht                    lldb.SBFileSpec(hidden_file))
7799451b44SJordan Rupprecht                if err.Fail():
7899451b44SJordan Rupprecht                    raise RuntimeError(
7999451b44SJordan Rupprecht                        "Unable copy 'libloadunload_d.so' to '%s'.\n>>> %s" %
8099451b44SJordan Rupprecht                        (wd, err.GetCString()))
8199451b44SJordan Rupprecht
8299451b44SJordan Rupprecht    def setSvr4Support(self, enabled):
8399451b44SJordan Rupprecht        self.runCmd(
8499451b44SJordan Rupprecht            "settings set plugin.process.gdb-remote.use-libraries-svr4 {enabled}".format(
8599451b44SJordan Rupprecht                enabled="true" if enabled else "false"
8699451b44SJordan Rupprecht            )
8799451b44SJordan Rupprecht        )
8899451b44SJordan Rupprecht
8999451b44SJordan Rupprecht    # libloadunload_d.so does not appear in the image list because executable
9099451b44SJordan Rupprecht    # dependencies are resolved relative to the debuggers PWD. Bug?
912c2eb5e6SMichał Górny    @expectedFailureAll(oslist=["freebsd", "linux", "netbsd"])
9266ae40ebSRaphael Isemann    @skipIfRemote
9399451b44SJordan Rupprecht    @skipIfWindows  # Windows doesn't have dlopen and friends, dynamic libraries work differently
9499451b44SJordan Rupprecht    def test_modules_search_paths(self):
9599451b44SJordan Rupprecht        """Test target modules list after loading a different copy of the library libd.dylib, and verifies that it works with 'target modules search-paths add'."""
9699451b44SJordan Rupprecht        if self.platformIsDarwin():
9799451b44SJordan Rupprecht            dylibName = 'libloadunload_d.dylib'
9899451b44SJordan Rupprecht        else:
9999451b44SJordan Rupprecht            dylibName = 'libloadunload_d.so'
10099451b44SJordan Rupprecht
10199451b44SJordan Rupprecht        # The directory with the dynamic library we did not link to.
10299451b44SJordan Rupprecht        new_dir = os.path.join(self.getBuildDir(), "hidden")
10399451b44SJordan Rupprecht
10499451b44SJordan Rupprecht        old_dylib = os.path.join(self.getBuildDir(), dylibName)
10599451b44SJordan Rupprecht        new_dylib = os.path.join(new_dir, dylibName)
10699451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
10799451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
10899451b44SJordan Rupprecht
10999451b44SJordan Rupprecht        self.expect("target modules list",
11099451b44SJordan Rupprecht                    substrs=[old_dylib])
11199451b44SJordan Rupprecht        # self.expect("target modules list -t 3",
11299451b44SJordan Rupprecht        #    patterns = ["%s-[^-]*-[^-]*" % self.getArchitecture()])
11399451b44SJordan Rupprecht        # Add an image search path substitution pair.
11499451b44SJordan Rupprecht        self.runCmd(
11599451b44SJordan Rupprecht            "target modules search-paths add %s %s" %
11699451b44SJordan Rupprecht            (self.getBuildDir(), new_dir))
11799451b44SJordan Rupprecht
11899451b44SJordan Rupprecht        self.expect("target modules search-paths list",
11999451b44SJordan Rupprecht                    substrs=[self.getBuildDir(), new_dir])
12099451b44SJordan Rupprecht
12199451b44SJordan Rupprecht        self.expect(
12299451b44SJordan Rupprecht            "target modules search-paths query %s" %
12399451b44SJordan Rupprecht            self.getBuildDir(),
12499451b44SJordan Rupprecht            "Image search path successfully transformed",
12599451b44SJordan Rupprecht            substrs=[new_dir])
12699451b44SJordan Rupprecht
12799451b44SJordan Rupprecht        # Obliterate traces of libd from the old location.
12899451b44SJordan Rupprecht        os.remove(old_dylib)
12999451b44SJordan Rupprecht        # Inform (DY)LD_LIBRARY_PATH of the new path, too.
130e0dbd025SPavel Labath        env_cmd_string = "settings replace target.env-vars " + self.dylibPath + "=" + new_dir
13199451b44SJordan Rupprecht        if self.TraceOn():
13299451b44SJordan Rupprecht            print("Set environment to: ", env_cmd_string)
13399451b44SJordan Rupprecht        self.runCmd(env_cmd_string)
13499451b44SJordan Rupprecht        self.runCmd("settings show target.env-vars")
13599451b44SJordan Rupprecht
13699451b44SJordan Rupprecht        self.runCmd("run")
13799451b44SJordan Rupprecht
13899451b44SJordan Rupprecht        self.expect(
13999451b44SJordan Rupprecht            "target modules list",
14099451b44SJordan Rupprecht            "LLDB successfully locates the relocated dynamic library",
14199451b44SJordan Rupprecht            substrs=[new_dylib])
14299451b44SJordan Rupprecht
14399451b44SJordan Rupprecht    # libloadunload_d.so does not appear in the image list because executable
14499451b44SJordan Rupprecht    # dependencies are resolved relative to the debuggers PWD. Bug?
1452c2eb5e6SMichał Górny    @expectedFailureAll(oslist=["freebsd", "linux", "netbsd"])
14699451b44SJordan Rupprecht    @expectedFailureAndroid  # wrong source file shows up for hidden library
14799451b44SJordan Rupprecht    @skipIfWindows  # Windows doesn't have dlopen and friends, dynamic libraries work differently
14899451b44SJordan Rupprecht    @skipIfDarwinEmbedded
14999451b44SJordan Rupprecht    def test_dyld_library_path(self):
15099451b44SJordan Rupprecht        """Test (DY)LD_LIBRARY_PATH after moving libd.dylib, which defines d_function, somewhere else."""
15199451b44SJordan Rupprecht        self.copy_shlibs_to_remote(hidden_dir=True)
15299451b44SJordan Rupprecht
15399451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
15499451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
15599451b44SJordan Rupprecht
15699451b44SJordan Rupprecht        # Shut off ANSI color usage so we don't get ANSI escape sequences
15799451b44SJordan Rupprecht        # mixed in with stop locations.
15899451b44SJordan Rupprecht        self.dbg.SetUseColor(False)
15999451b44SJordan Rupprecht
16099451b44SJordan Rupprecht        if self.platformIsDarwin():
16199451b44SJordan Rupprecht            dylibName = 'libloadunload_d.dylib'
16299451b44SJordan Rupprecht            dsymName = 'libloadunload_d.dylib.dSYM'
16399451b44SJordan Rupprecht        else:
16499451b44SJordan Rupprecht            dylibName = 'libloadunload_d.so'
16599451b44SJordan Rupprecht
16699451b44SJordan Rupprecht        # The directory to relocate the dynamic library and its debugging info.
16799451b44SJordan Rupprecht        special_dir = "hidden"
16899451b44SJordan Rupprecht        if lldb.remote_platform:
16999451b44SJordan Rupprecht            wd = lldb.remote_platform.GetWorkingDirectory()
17099451b44SJordan Rupprecht        else:
17199451b44SJordan Rupprecht            wd = self.getBuildDir()
17299451b44SJordan Rupprecht
17399451b44SJordan Rupprecht        old_dir = wd
17499451b44SJordan Rupprecht        new_dir = os.path.join(wd, special_dir)
17599451b44SJordan Rupprecht        old_dylib = os.path.join(old_dir, dylibName)
17699451b44SJordan Rupprecht
17799451b44SJordan Rupprecht        # For now we don't track (DY)LD_LIBRARY_PATH, so the old
17899451b44SJordan Rupprecht        # library will be in the modules list.
17999451b44SJordan Rupprecht        self.expect("target modules list",
18099451b44SJordan Rupprecht                    substrs=[os.path.basename(old_dylib)],
18199451b44SJordan Rupprecht                    matching=True)
18299451b44SJordan Rupprecht
18399451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
18499451b44SJordan Rupprecht            self, "d.cpp", self.line_d_function, num_expected_locations=1)
18599451b44SJordan Rupprecht        # After run, make sure the non-hidden library is picked up.
18699451b44SJordan Rupprecht        self.expect("run", substrs=["return", "700"])
18799451b44SJordan Rupprecht
18899451b44SJordan Rupprecht        self.runCmd("continue")
18999451b44SJordan Rupprecht
19099451b44SJordan Rupprecht        # Add the hidden directory first in the search path.
191e0dbd025SPavel Labath        env_cmd_string = ("settings set target.env-vars %s=%s%s%s" %
192e0dbd025SPavel Labath                          (self.dylibPath, new_dir,
193e0dbd025SPavel Labath                              self.platformContext.shlib_path_separator, self.default_path))
19499451b44SJordan Rupprecht        self.runCmd(env_cmd_string)
19599451b44SJordan Rupprecht
19699451b44SJordan Rupprecht        # This time, the hidden library should be picked up.
19799451b44SJordan Rupprecht        self.expect("run", substrs=["return", "12345"])
19899451b44SJordan Rupprecht
19999451b44SJordan Rupprecht    @expectedFailureAll(
20099451b44SJordan Rupprecht        bugnumber="llvm.org/pr25805",
20199451b44SJordan Rupprecht        hostoslist=["windows"],
20299451b44SJordan Rupprecht        triple='.*-android')
203e0dbd025SPavel Labath    @expectedFailureAll(oslist=["windows"]) # process load not implemented
20499451b44SJordan Rupprecht    def test_lldb_process_load_and_unload_commands(self):
20599451b44SJordan Rupprecht        self.setSvr4Support(False)
20699451b44SJordan Rupprecht        self.run_lldb_process_load_and_unload_commands()
20799451b44SJordan Rupprecht
20899451b44SJordan Rupprecht    @expectedFailureAll(
20999451b44SJordan Rupprecht        bugnumber="llvm.org/pr25805",
21099451b44SJordan Rupprecht        hostoslist=["windows"],
21199451b44SJordan Rupprecht        triple='.*-android')
212e0dbd025SPavel Labath    @expectedFailureAll(oslist=["windows"]) # process load not implemented
21399451b44SJordan Rupprecht    def test_lldb_process_load_and_unload_commands_with_svr4(self):
21499451b44SJordan Rupprecht        self.setSvr4Support(True)
21599451b44SJordan Rupprecht        self.run_lldb_process_load_and_unload_commands()
21699451b44SJordan Rupprecht
21799451b44SJordan Rupprecht    def run_lldb_process_load_and_unload_commands(self):
21899451b44SJordan Rupprecht        """Test that lldb process load/unload command work correctly."""
21999451b44SJordan Rupprecht        self.copy_shlibs_to_remote()
22099451b44SJordan Rupprecht
22199451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
22299451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
22399451b44SJordan Rupprecht
22499451b44SJordan Rupprecht        # Break at main.cpp before the call to dlopen().
22599451b44SJordan Rupprecht        # Use lldb's process load command to load the dylib, instead.
22699451b44SJordan Rupprecht
22799451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
22899451b44SJordan Rupprecht            self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
22999451b44SJordan Rupprecht
23099451b44SJordan Rupprecht        self.runCmd("run", RUN_SUCCEEDED)
23199451b44SJordan Rupprecht
23299451b44SJordan Rupprecht        ctx = self.platformContext
23399451b44SJordan Rupprecht        dylibName = ctx.shlib_prefix + 'loadunload_a.' + ctx.shlib_extension
23499451b44SJordan Rupprecht        localDylibPath = self.getBuildArtifact(dylibName)
23599451b44SJordan Rupprecht        if lldb.remote_platform:
23699451b44SJordan Rupprecht            wd = lldb.remote_platform.GetWorkingDirectory()
23799451b44SJordan Rupprecht            remoteDylibPath = lldbutil.join_remote_paths(wd, dylibName)
23899451b44SJordan Rupprecht        else:
23999451b44SJordan Rupprecht            remoteDylibPath = localDylibPath
24099451b44SJordan Rupprecht
241f7588597SJim Ingham        # First make sure that we get some kind of error if process load fails.
242f7588597SJim Ingham        # We print some error even if the load fails, which isn't formalized.
243f7588597SJim Ingham        # The only plugin at present (Posix) that supports this says "unknown reasons".
244f7588597SJim Ingham        # If another plugin shows up, let's require it uses "unknown error" as well.
245f7588597SJim Ingham        non_existant_shlib = "/NoSuchDir/NoSuchSubdir/ReallyNo/NotAFile"
246f7588597SJim Ingham        self.expect("process load %s"%(non_existant_shlib), error=True, matching=False,
247f7588597SJim Ingham                    patterns=["unknown reasons"])
248f7588597SJim Ingham
249f7588597SJim Ingham
25099451b44SJordan Rupprecht        # Make sure that a_function does not exist at this point.
25199451b44SJordan Rupprecht        self.expect(
25299451b44SJordan Rupprecht            "image lookup -n a_function",
25399451b44SJordan Rupprecht            "a_function should not exist yet",
25499451b44SJordan Rupprecht            error=True,
25599451b44SJordan Rupprecht            matching=False,
25699451b44SJordan Rupprecht            patterns=["1 match found"])
25799451b44SJordan Rupprecht
25899451b44SJordan Rupprecht        # Use lldb 'process load' to load the dylib.
25999451b44SJordan Rupprecht        self.expect(
26099451b44SJordan Rupprecht            "process load %s --install=%s" % (localDylibPath, remoteDylibPath),
26199451b44SJordan Rupprecht            "%s loaded correctly" % dylibName,
26299451b44SJordan Rupprecht            patterns=[
26399451b44SJordan Rupprecht                'Loading "%s".*ok' % re.escape(localDylibPath),
26499451b44SJordan Rupprecht                'Image [0-9]+ loaded'])
26599451b44SJordan Rupprecht
26699451b44SJordan Rupprecht        # Search for and match the "Image ([0-9]+) loaded" pattern.
26799451b44SJordan Rupprecht        output = self.res.GetOutput()
26899451b44SJordan Rupprecht        pattern = re.compile("Image ([0-9]+) loaded")
26999451b44SJordan Rupprecht        for l in output.split(os.linesep):
270b321b429SJonas Devlieghere            self.trace("l:", l)
27199451b44SJordan Rupprecht            match = pattern.search(l)
27299451b44SJordan Rupprecht            if match:
27399451b44SJordan Rupprecht                break
27499451b44SJordan Rupprecht        index = match.group(1)
27599451b44SJordan Rupprecht
27699451b44SJordan Rupprecht        # Now we should have an entry for a_function.
27799451b44SJordan Rupprecht        self.expect(
27899451b44SJordan Rupprecht            "image lookup -n a_function",
27999451b44SJordan Rupprecht            "a_function should now exist",
28099451b44SJordan Rupprecht            patterns=[
28199451b44SJordan Rupprecht                "1 match found .*%s" %
28299451b44SJordan Rupprecht                dylibName])
28399451b44SJordan Rupprecht
28499451b44SJordan Rupprecht        # Use lldb 'process unload' to unload the dylib.
28599451b44SJordan Rupprecht        self.expect(
28699451b44SJordan Rupprecht            "process unload %s" %
28799451b44SJordan Rupprecht            index,
28899451b44SJordan Rupprecht            "%s unloaded correctly" %
28999451b44SJordan Rupprecht            dylibName,
29099451b44SJordan Rupprecht            patterns=[
29199451b44SJordan Rupprecht                "Unloading .* with index %s.*ok" %
29299451b44SJordan Rupprecht                index])
29399451b44SJordan Rupprecht
29499451b44SJordan Rupprecht        self.runCmd("process continue")
29599451b44SJordan Rupprecht
296e0dbd025SPavel Labath    @expectedFailureAll(oslist=["windows"]) # breakpoint not hit
29799451b44SJordan Rupprecht    def test_load_unload(self):
29899451b44SJordan Rupprecht        self.setSvr4Support(False)
29999451b44SJordan Rupprecht        self.run_load_unload()
30099451b44SJordan Rupprecht
301e0dbd025SPavel Labath    @expectedFailureAll(oslist=["windows"]) # breakpoint not hit
30299451b44SJordan Rupprecht    def test_load_unload_with_svr4(self):
30399451b44SJordan Rupprecht        self.setSvr4Support(True)
30499451b44SJordan Rupprecht        self.run_load_unload()
30599451b44SJordan Rupprecht
30699451b44SJordan Rupprecht    def run_load_unload(self):
30799451b44SJordan Rupprecht        """Test breakpoint by name works correctly with dlopen'ing."""
30899451b44SJordan Rupprecht        self.copy_shlibs_to_remote()
30999451b44SJordan Rupprecht
31099451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
31199451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
31299451b44SJordan Rupprecht
31399451b44SJordan Rupprecht        # Break by function name a_function (not yet loaded).
31499451b44SJordan Rupprecht        lldbutil.run_break_set_by_symbol(
31599451b44SJordan Rupprecht            self, "a_function", num_expected_locations=0)
31699451b44SJordan Rupprecht
31799451b44SJordan Rupprecht        self.runCmd("run", RUN_SUCCEEDED)
31899451b44SJordan Rupprecht
31999451b44SJordan Rupprecht        # The stop reason of the thread should be breakpoint and at a_function.
32099451b44SJordan Rupprecht        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
32199451b44SJordan Rupprecht                    substrs=['stopped',
32299451b44SJordan Rupprecht                             'a_function',
32399451b44SJordan Rupprecht                             'stop reason = breakpoint'])
32499451b44SJordan Rupprecht
32599451b44SJordan Rupprecht        # The breakpoint should have a hit count of 1.
3269f0b5f9aSSYNOPSYS\georgiev        lldbutil.check_breakpoint(self, bpno = 1, expected_hit_count = 1)
32799451b44SJordan Rupprecht
328e9264b74SKazuaki Ishizaki        # Issue the 'continue' command.  We should stop agaian at a_function.
32999451b44SJordan Rupprecht        # The stop reason of the thread should be breakpoint and at a_function.
33099451b44SJordan Rupprecht        self.runCmd("continue")
33199451b44SJordan Rupprecht
33299451b44SJordan Rupprecht        # rdar://problem/8508987
33399451b44SJordan Rupprecht        # The a_function breakpoint should be encountered twice.
33499451b44SJordan Rupprecht        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
33599451b44SJordan Rupprecht                    substrs=['stopped',
33699451b44SJordan Rupprecht                             'a_function',
33799451b44SJordan Rupprecht                             'stop reason = breakpoint'])
33899451b44SJordan Rupprecht
33999451b44SJordan Rupprecht        # The breakpoint should have a hit count of 2.
3409f0b5f9aSSYNOPSYS\georgiev        lldbutil.check_breakpoint(self, bpno = 1, expected_hit_count = 2)
34199451b44SJordan Rupprecht
34299451b44SJordan Rupprecht    def test_step_over_load(self):
34399451b44SJordan Rupprecht        self.setSvr4Support(False)
34499451b44SJordan Rupprecht        self.run_step_over_load()
34599451b44SJordan Rupprecht
34699451b44SJordan Rupprecht    def test_step_over_load_with_svr4(self):
34799451b44SJordan Rupprecht        self.setSvr4Support(True)
34899451b44SJordan Rupprecht        self.run_step_over_load()
34999451b44SJordan Rupprecht
35099451b44SJordan Rupprecht    def run_step_over_load(self):
35199451b44SJordan Rupprecht        """Test stepping over code that loads a shared library works correctly."""
35299451b44SJordan Rupprecht        self.copy_shlibs_to_remote()
35399451b44SJordan Rupprecht
35499451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
35599451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
35699451b44SJordan Rupprecht
35799451b44SJordan Rupprecht        # Break by function name a_function (not yet loaded).
35899451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
35999451b44SJordan Rupprecht            self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
36099451b44SJordan Rupprecht
36199451b44SJordan Rupprecht        self.runCmd("run", RUN_SUCCEEDED)
36299451b44SJordan Rupprecht
36399451b44SJordan Rupprecht        # The stop reason of the thread should be breakpoint and at a_function.
36499451b44SJordan Rupprecht        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
36599451b44SJordan Rupprecht                    substrs=['stopped',
36699451b44SJordan Rupprecht                             'stop reason = breakpoint'])
36799451b44SJordan Rupprecht
36899451b44SJordan Rupprecht        self.runCmd(
36999451b44SJordan Rupprecht            "thread step-over",
37099451b44SJordan Rupprecht            "Stepping over function that loads library")
37199451b44SJordan Rupprecht
37299451b44SJordan Rupprecht        # The stop reason should be step end.
37399451b44SJordan Rupprecht        self.expect("thread list", "step over succeeded.",
37499451b44SJordan Rupprecht                    substrs=['stopped',
37599451b44SJordan Rupprecht                             'stop reason = step over'])
37699451b44SJordan Rupprecht
37799451b44SJordan Rupprecht    # We can't find a breakpoint location for d_init before launching because
37899451b44SJordan Rupprecht    # executable dependencies are resolved relative to the debuggers PWD. Bug?
3792c2eb5e6SMichał Górny    @expectedFailureAll(oslist=["freebsd", "linux", "netbsd"], triple=no_match('aarch64-.*-android'))
380*b82b0187SMuhammad Omair Javaid    @expectedFailureAll(oslist=["windows"], archs=["aarch64"])
38199451b44SJordan Rupprecht    def test_static_init_during_load(self):
38299451b44SJordan Rupprecht        """Test that we can set breakpoints correctly in static initializers"""
38399451b44SJordan Rupprecht        self.copy_shlibs_to_remote()
38499451b44SJordan Rupprecht
38599451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
38699451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
38799451b44SJordan Rupprecht
38899451b44SJordan Rupprecht        a_init_bp_num = lldbutil.run_break_set_by_symbol(
38999451b44SJordan Rupprecht            self, "a_init", num_expected_locations=0)
39099451b44SJordan Rupprecht        b_init_bp_num = lldbutil.run_break_set_by_symbol(
39199451b44SJordan Rupprecht            self, "b_init", num_expected_locations=0)
39299451b44SJordan Rupprecht        d_init_bp_num = lldbutil.run_break_set_by_symbol(
39399451b44SJordan Rupprecht            self, "d_init", num_expected_locations=1)
39499451b44SJordan Rupprecht
39599451b44SJordan Rupprecht        self.runCmd("run", RUN_SUCCEEDED)
39699451b44SJordan Rupprecht
39799451b44SJordan Rupprecht        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
39899451b44SJordan Rupprecht                    substrs=['stopped',
39999451b44SJordan Rupprecht                             'd_init',
40099451b44SJordan Rupprecht                             'stop reason = breakpoint %d' % d_init_bp_num])
40199451b44SJordan Rupprecht
40299451b44SJordan Rupprecht        self.runCmd("continue")
40399451b44SJordan Rupprecht        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
40499451b44SJordan Rupprecht                    substrs=['stopped',
40599451b44SJordan Rupprecht                             'b_init',
40699451b44SJordan Rupprecht                             'stop reason = breakpoint %d' % b_init_bp_num])
40799451b44SJordan Rupprecht        self.expect("thread backtrace",
40899451b44SJordan Rupprecht                    substrs=['b_init',
409e0dbd025SPavel Labath                             'dylib_open',
41099451b44SJordan Rupprecht                             'main'])
41199451b44SJordan Rupprecht
41299451b44SJordan Rupprecht        self.runCmd("continue")
41399451b44SJordan Rupprecht        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
41499451b44SJordan Rupprecht                    substrs=['stopped',
41599451b44SJordan Rupprecht                             'a_init',
41699451b44SJordan Rupprecht                             'stop reason = breakpoint %d' % a_init_bp_num])
41799451b44SJordan Rupprecht        self.expect("thread backtrace",
41899451b44SJordan Rupprecht                    substrs=['a_init',
419e0dbd025SPavel Labath                             'dylib_open',
42099451b44SJordan Rupprecht                             'main'])
421