-
Notifications
You must be signed in to change notification settings - Fork 15.9k
[lldb] Fix TestModuleLoadedNotifys API test to work correctly on most of Linux targets #94672
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,23 @@ | ||
| CXX_SOURCES := main.cpp | ||
|
|
||
| include Makefile.rules | ||
| CXX_SOURCES := main.cpp | ||
| LD_EXTRAS := -L. -lloadunload_d -lloadunload_c -lloadunload_a -lloadunload_b | ||
|
|
||
| a.out: lib_b lib_a lib_c lib_d | ||
|
|
||
| include Makefile.rules | ||
|
|
||
| lib_a: lib_b | ||
| $(MAKE) -f $(MAKEFILE_RULES) \ | ||
| DYLIB_ONLY=YES DYLIB_CXX_SOURCES=a.cpp DYLIB_NAME=loadunload_a \ | ||
| LD_EXTRAS="-L. -lloadunload_b" | ||
|
|
||
| lib_b: | ||
| $(MAKE) -f $(MAKEFILE_RULES) \ | ||
| DYLIB_ONLY=YES DYLIB_CXX_SOURCES=b.cpp DYLIB_NAME=loadunload_b | ||
|
|
||
| lib_c: | ||
| $(MAKE) -f $(MAKEFILE_RULES) \ | ||
| DYLIB_ONLY=YES DYLIB_CXX_SOURCES=c.cpp DYLIB_NAME=loadunload_c | ||
|
|
||
| lib_d: | ||
| $(MAKE) -f $(MAKEFILE_RULES) \ | ||
| DYLIB_ONLY=YES DYLIB_CXX_SOURCES=d.cpp DYLIB_NAME=loadunload_d | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,22 +9,51 @@ | |
| from lldbsuite.test import lldbutil | ||
|
|
||
|
|
||
| @skipUnlessPlatform(["linux"] + lldbplatformutil.getDarwinOSTriples()) | ||
| 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 setup_test(self, solibs): | ||
| if lldb.remote_platform: | ||
| path = lldb.remote_platform.GetWorkingDirectory() | ||
| for f in solibs: | ||
| lldbutil.install_to_target(self, self.getBuildArtifact(f)) | ||
| else: | ||
| path = self.getBuildDir() | ||
| if self.dylibPath in os.environ: | ||
| sep = self.platformContext.shlib_path_separator | ||
| path = os.environ[self.dylibPath] + sep + path | ||
| self.runCmd( | ||
| "settings append target.env-vars '{}={}'".format(self.dylibPath, path) | ||
| ) | ||
| self.default_path = path | ||
|
|
||
| def test_launch_notifications(self): | ||
| """Test that lldb broadcasts newly loaded libraries in batches.""" | ||
|
|
||
| ext = "so" | ||
| if self.platformIsDarwin(): | ||
| ext = "dylib" | ||
|
||
|
|
||
| expected_solibs = [ | ||
| "libloadunload_a." + ext, | ||
| "libloadunload_b." + ext, | ||
| "libloadunload_c." + ext, | ||
| "libloadunload_d." + ext, | ||
| ] | ||
|
|
||
| self.build() | ||
| self.setup_test(expected_solibs) | ||
|
|
||
| exe = self.getBuildArtifact("a.out") | ||
| self.dbg.SetAsync(False) | ||
|
|
||
|
|
@@ -70,6 +99,8 @@ def test_launch_notifications(self): | |
| total_modules_added_events = 0 | ||
| total_modules_removed_events = 0 | ||
| already_loaded_modules = [] | ||
| max_solibs_per_event = 0 | ||
| max_solib_chunk_per_event = [] | ||
| while listener.GetNextEvent(event): | ||
| if lldb.SBTarget.EventIsTargetEvent(event): | ||
| if event.GetType() == lldb.SBTarget.eBroadcastBitModulesLoaded: | ||
|
|
@@ -91,12 +122,17 @@ def test_launch_notifications(self): | |
| "{} is already loaded".format(module), | ||
| ) | ||
| already_loaded_modules.append(module) | ||
| if self.TraceOn(): | ||
| added_files.append(module.GetFileSpec().GetFilename()) | ||
| 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))) | ||
|
|
||
| # We will check the latest biggest chunk of loaded solibs. | ||
| # We expect all of our solibs in the last chunk of loaded modules. | ||
| if solib_count >= max_solibs_per_event: | ||
| max_solib_chunk_per_event = added_files.copy() | ||
| max_solibs_per_event = solib_count | ||
|
|
||
| if event.GetType() == lldb.SBTarget.eBroadcastBitModulesUnloaded: | ||
| solib_count = lldb.SBTarget.GetNumModulesFromEvent(event) | ||
| total_modules_removed_events += 1 | ||
|
|
@@ -115,9 +151,10 @@ def test_launch_notifications(self): | |
| # 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) | ||
| # On Linux we get events for ld.so, [vdso], the binary and then all libraries, | ||
| # but the different configurations could load a different number of .so modules | ||
| # per event. | ||
| self.assertGreaterEqual( | ||
| len(set(max_solib_chunk_per_event).intersection(expected_solibs)), | ||
| len(expected_solibs), | ||
|
||
| ) | ||
| self.assertGreater(avg_solibs_added_per_event, 1) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| extern "C" int b_function(); | ||
|
|
||
| int a_init() { return 234; } | ||
|
|
||
| int a_global = a_init(); | ||
|
||
|
|
||
| extern "C" int a_function() { return b_function(); } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| int b_init() { return 345; } | ||
|
|
||
| int b_global = b_init(); | ||
|
|
||
| extern "C" int b_function() { return 500; } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| extern "C" int c_function() { return 600; } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| int d_init() { return 123; } | ||
|
|
||
| int d_global = d_init(); | ||
|
|
||
| extern "C" int d_function() { return 700; } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,16 @@ | ||
| #include <stdio.h> | ||
| int main () | ||
| { | ||
| puts("running"); // breakpoint here | ||
| return 0; | ||
| } | ||
| #include <stdio.h> | ||
|
|
||
| extern "C" int a_function(); | ||
| extern "C" int c_function(); | ||
| extern "C" int b_function(); | ||
| extern "C" int d_function(); | ||
|
|
||
| int main() { | ||
| a_function(); | ||
| b_function(); | ||
| c_function(); | ||
| d_function(); | ||
|
|
||
| puts("running"); // breakpoint here | ||
| return 0; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please rename the modules to something else (even a simple
libais probably fine).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.