File: TestModuleLoadedNotifys.py

package info (click to toggle)
llvm-toolchain-15 1%3A15.0.6-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,554,644 kB
  • sloc: cpp: 5,922,452; ansic: 1,012,136; asm: 674,362; python: 191,568; objc: 73,855; f90: 42,327; lisp: 31,913; pascal: 11,973; javascript: 10,144; sh: 9,421; perl: 7,447; ml: 5,527; awk: 3,523; makefile: 2,520; xml: 885; cs: 573; fortran: 567
file content (117 lines) | stat: -rw-r--r-- 5,322 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
"""
Test how many times newly loaded binaries are notified;
they should be delivered in batches instead of one-by-one.
"""

from __future__ import print_function


import lldb
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil

class ModuleLoadedNotifysTestCase(TestBase):
    NO_DEBUG_INFO_TESTCASE = True

    # At least DynamicLoaderDarwin and DynamicLoaderPOSIXDYLD should batch up
    # notifications about newly added/removed libraries.  Other DynamicLoaders may
    # not be written this way.
    @skipUnlessPlatform(["linux"]+lldbplatformutil.getDarwinOSTriples())

    def setUp(self):
        # Call super's setUp().
        TestBase.setUp(self)
        # Find the line number to break inside main().
        self.line = line_number('main.cpp', '// breakpoint')

    def test_launch_notifications(self):
        """Test that lldb broadcasts newly loaded libraries in batches."""
        self.build()
        exe = self.getBuildArtifact("a.out")
        self.dbg.SetAsync(False)

        listener = self.dbg.GetListener()
        listener.StartListeningForEventClass(
            self.dbg,
            lldb.SBTarget.GetBroadcasterClassName(),
            lldb.SBTarget.eBroadcastBitModulesLoaded | lldb.SBTarget.eBroadcastBitModulesUnloaded)

        # Create a target by the debugger.
        target = self.dbg.CreateTarget(exe)
        self.assertTrue(target, VALID_TARGET)

        # break on main
        breakpoint = target.BreakpointCreateByName('main', 'a.out')

        event = lldb.SBEvent()
        # CreateTarget() generated modules-loaded events; consume them & toss
        while listener.GetNextEvent(event):
            True

        error = lldb.SBError()
        flags = target.GetLaunchInfo().GetLaunchFlags()
        process = target.Launch(listener,
                                None,      # argv
                                None,      # envp
                                None,      # stdin_path
                                None,      # stdout_path
                                None,      # stderr_path
                                None,      # working directory
                                flags,     # launch flags
                                False,     # Stop at entry
                                error)     # error

        self.assertEqual(
            process.GetState(), lldb.eStateStopped,
            PROCESS_STOPPED)

        total_solibs_added = 0
        total_solibs_removed = 0
        total_modules_added_events = 0
        total_modules_removed_events = 0
        already_loaded_modules = []
        while listener.GetNextEvent(event):
            if lldb.SBTarget.EventIsTargetEvent(event):
                if event.GetType() == lldb.SBTarget.eBroadcastBitModulesLoaded:
                    solib_count = lldb.SBTarget.GetNumModulesFromEvent(event)
                    total_modules_added_events += 1
                    total_solibs_added += solib_count
                    added_files = []
                    for i in range (solib_count):
                        module = lldb.SBTarget.GetModuleAtIndexFromEvent(i, event)
                        # On macOS Ventura and later, dyld and the main binary
                        # will be loaded again when dyld moves itself into the
                        # shared cache.
                        if module.file.fullpath not in ['/usr/lib/dyld', exe]:
                            self.assertTrue(module not in already_loaded_modules, '{} is already loaded'.format(module))
                        already_loaded_modules.append(module)
                        if self.TraceOn():
                            added_files.append(module.GetFileSpec().GetFilename())
                    if self.TraceOn():
                        # print all of the binaries that have been added
                        print("Loaded files: %s" % (', '.join(added_files)))

                if event.GetType() == lldb.SBTarget.eBroadcastBitModulesUnloaded:
                    solib_count = lldb.SBTarget.GetNumModulesFromEvent(event)
                    total_modules_removed_events += 1
                    total_solibs_removed += solib_count
                    if self.TraceOn():
                        # print all of the binaries that have been removed
                        removed_files = []
                        i = 0
                        while i < solib_count:
                            module = lldb.SBTarget.GetModuleAtIndexFromEvent(i, event)
                            removed_files.append(module.GetFileSpec().GetFilename())
                            i = i + 1
                        print("Unloaded files: %s" % (', '.join(removed_files)))


        # This is testing that we get back a small number of events with the loaded
        # binaries in batches.  Check that we got back more than 1 solib per event.
        # In practice on Darwin today, we get back two events for a do-nothing c
        # program: a.out and dyld, and then all the rest of the system libraries.
        # On Linux we get events for ld.so, [vdso], the binary and then all libraries.

        avg_solibs_added_per_event = round(float(total_solibs_added) / float(total_modules_added_events))
        self.assertGreater(avg_solibs_added_per_event, 1)