Skip to content

[LLDB] Deterministic module order in Target::SetExecutableModule #10746

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

Open
wants to merge 1 commit into
base: stable/20240723
Choose a base branch
from

Conversation

DmT021
Copy link

@DmT021 DmT021 commented May 24, 2025

This change separates module loading from symbol preloading to ensure a deterministic module loading order. Parallel module loading was causing non-deterministic behavior, but we only need to load symbols in parallel as that's the heavy part of the process.

Discussion https://discourse.llvm.org/t/non-deterministic-module-order-in-lldb/86446

This change separates module loading from symbol preloading to ensure a
deterministic module loading order. Parallel module loading was causing
non-deterministic behavior, but we only need to load symbols in parallel
as that's the heavy part of the process.
@DmT021
Copy link
Author

DmT021 commented May 24, 2025

@swift-ci Please test

@DmT021 DmT021 marked this pull request as ready for review May 25, 2025 16:45
@DmT021 DmT021 requested a review from a team as a code owner May 25, 2025 16:45
/// will likely be provided.
lldb::ModuleSP GetOrCreateModule(
const ModuleSpec &module_spec, bool notify,
llvm::function_ref<void(std::function<void()>)> scheduleSymbolsPreload,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a separate overload for this or could we use a default value of nullptr for scheduleSymbolsPreload? It looks like llvm::function_ref has a suitable operator bool() defined.

I suppose it might require updating more callsites that currently pass the Status output pointer.

@@ -0,0 +1,26 @@
C_SOURCES := main.c
LD_EXTRAS := -L. -la -lb -lc -ld -le
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran into a few problems when running this test on linux.

  1. The -lc was confusing the locally build libc.so with the "real" libc and causing linking errors.
  2. The linked shared libraries did not use a full path so only the basename is stored in the DT_NEEDED section. This does not resolve to a unique file location so it they are skipped by the load dependent code.

I worked around the first problem by not linking libc.so into a.out. But then when running the test with trace enabled I see the following output.

First run module list: ['a.out']
Run 2 module list: ['a.out']
...

Obviously this is not going to detect a non-deterministic module order for linux. But if we change it to link to the full path of the shared objects

--- a/lldb/test/API/functionalities/deterministic_module_order/Makefile
+++ b/lldb/test/API/functionalities/deterministic_module_order/Makefile
@@ -1,9 +1,12 @@
 C_SOURCES := main.c
-LD_EXTRAS := -L. -la -lb -lc -ld -le
+include Makefile.rules
+
+# Use full path to shared libraries to make test effective on linux.
+LD_EXTRAS := $(BUILDDIR)/liba.so $(BUILDDIR)/libb.so $(BUILDDIR)/libc.so $(BUILDDIR)/libd.so $(BUILDDIR)/libe.so

 a.out: liba libb libc libd libe

-include Makefile.rules
+

Then the test looks like it would work

First run module list: ['a.out', 'liba.so', 'libb.so', 'libc.so', 'libd.so', 'libe.so']
Run 2 module list: ['a.out', 'liba.so', 'libb.so', 'libc.so', 'libd.so', 'libe.so']
...

ModuleSpec module_spec(platform_dependent_file_spec, m_arch.GetSpec());
auto image_module_sp = GetOrCreateModule(
module_spec, false /* notify */,
[&](auto preloadSymbols) { task_group.async(preloadSymbols); });
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good to gate the parallel loading of modules here based on the with the target.parallel-module-load setting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants