-
Couldn't load subscription status.
- Fork 15k
[ORC] Add automatic shared library resolver for unresolved symbols. #148410
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
Conversation
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
|
@SahilPatidar, what is still required for this PR to make it ready for review? |
|
Done. We'll improve it based on the review. I had added async locally before, but it would be better if lhames reviews it so we can get a better idea of how to improve it. |
0288f91 to
e0366e0
Compare
| return *this; | ||
| } | ||
|
|
||
| BloomFilter build(const std::vector<std::string> &symbols) const { |
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.
Can we avoid the std::string copies? Is there something smarter we can do here?
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.
can try StringRef or Range?
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.
Assuming the allocation is done already in the opened file then we could reuse that memory instead of allocating more.
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.
Looks like all of the Cling/ROOT-related bits are in place. Can we work on adding a set of tests?
Perhaps @alexander-penev could also take a look as he was one of the originators of this work.
| while (it != end) { | ||
| const auto &lib = it->second; | ||
| if (lib->getState() == state && lib->getKind() == kind) | ||
| break; | ||
| ++it; | ||
| } |
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.
Probably could be written as a for loop.
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.
Like this :
for (; it != end; ++it)
if (it->second->getState() == state && it->second->getKind() == kind)
break;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.
For example.
| for (const auto &sym : symbols) { | ||
| filter.add(sym); | ||
| } |
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.
| for (const auto &sym : symbols) { | |
| filter.add(sym); | |
| } | |
| for (const auto &sym : symbols) | |
| filter.add(sym); |
|
This is being tested by the original downstream client and overall looks good. For this PR to move forward we will need a good amount of test cases. |
| for (const auto &sym : Symbols) { | ||
| filter.add(sym); | ||
| } |
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.
| for (const auto &sym : Symbols) { | |
| filter.add(sym); | |
| } | |
| for (const auto &sym : Symbols) | |
| filter.add(sym); |
llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/LibraryResolver.h
Outdated
Show resolved
Hide resolved
| Iterator begin_, end_; | ||
| State state_; | ||
| PathType kind_; |
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.
I'd move this before the class definition. @lhames, are you aware if the training underscore is acceptable as a coding convention?
| } | ||
|
|
||
| private: | ||
| Iterator begin_, end_; |
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.
| Iterator begin_, end_; | |
| Iterator begin_; | |
| Iterator end_; |
| if (it != m_readlinkCache.end()) { | ||
| return it->second; | ||
| } |
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.
| if (it != m_readlinkCache.end()) { | |
| return it->second; | |
| } | |
| if (it != m_readlinkCache.end()) | |
| return it->second; |
| if (it != m_lstatCache.end()) { | ||
| return it->second; | ||
| } |
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.
| if (it != m_lstatCache.end()) { | |
| return it->second; | |
| } | |
| if (it != m_lstatCache.end()) | |
| return it->second; |
|
|
||
| private: | ||
| // mutable std::shared_mutex m_mutex; | ||
| std::shared_ptr<LibraryPathCache> m_cache; |
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.
Move that section up.
| if (input.starts_with(ph)) { | ||
| return (Twine(value) + input.drop_front(ph.size())).str(); | ||
| } |
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.
| if (input.starts_with(ph)) { | |
| return (Twine(value) + input.drop_front(ph.size())).str(); | |
| } | |
| if (input.starts_with(ph)) | |
| return (Twine(value) + input.drop_front(ph.size())).str(); |
| } | ||
|
|
||
| private: | ||
| StringMap<std::string> placeholders_; |
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.
Likewise.
|
@vgvassilev I also think that everything from Cling/ROOT (as well as the subsequent rework) seems to be implemented. The improvements made are also reasonable. As @vgvassilev says, it is good to add some of the tests and some new ones. The recommended improvements are also appropriate. |
|
Thanks for the review! Folder structure: The test reads each YAML and creates a I’m figuring out how to make the YAML files portable across platforms. If I don’t find a simple way, then I need to create separate YAML files for each platform. |
|
Maybe some of the tests I wrote before can be found and adapted from here... https://github.com/compiler-research/CppInterOp/pull/308/files |
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.
Why not a flat structure, eg. Inputs/{A,B,C}.yaml?
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.
To test, check if dylib-resolver can find the dependency via @rpath and handle different search path directories.
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.
Ah, yes, good point. We should also test things like RUNPATH and similar code. Can you run codecoverage locally and list all of the untested branches? I really want good testing coverage for this feature.
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.
since we currently only support Mach-O.
So I added @rpath and @loader_path handling, plus extra path searching (with and without extensions like A.dylib or just A when searching for a library).
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.
We have a lot of tests that intent to capture real-world setups here: https://github.com/root-project/cling/tree/master/test/DynamicLibraryManager
Can you take a look and see what's missing from the current tests we have in this PR?
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.
Thank you for this piece of work and your patience! LGTM!
| /** | ||
| * @brief A read-only view of libraries filtered by state and kind. | ||
| * | ||
| * Lets you loop over only the libraries in a map that match a given State | ||
| * and PathType. | ||
| */ |
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.
| /** | |
| * @brief A read-only view of libraries filtered by state and kind. | |
| * | |
| * Lets you loop over only the libraries in a map that match a given State | |
| * and PathType. | |
| */ | |
| /** | |
| /// A read-only view of libraries filtered by state and kind. | |
| /// | |
| /// Lets you loop over only the libraries in a map that match a given State | |
| /// and PathType. |
|
One more task I need to complete is moving the code from Orc/TargetProcess to Orc/Shared, so that it can be used on the Root side as an API. Also, before merging, can we make sure the unit tests are running correctly? Right now, they only work for Mach-O binaries. I created a fat binary (x86_64 + arm64 + arm64e) YAML, where the x86_64 and arm64e parts were cross-compiled, and I generated the YAML file. However, I’ve only tested it on arm64, not on x86_64. |
Probably that’s a question for @lhames. I am fine with that change considering the fact that we will rework that part when the new orc runtime shapes up.
I can take this PR and run the test suite on Unix 64bit platform. Is that enough? |
The YAML file we have is a fat YAML containing slices for three architectures supported only on macOS. I’m not sure whether a Unix x86_64 system would support this format. |
Are there any other tests in the codebase that follow the same approach? |
| static constexpr uint32_t bitsPerEntry = 64; | ||
|
|
||
| bool initialized = false; | ||
| uint32_t symbolCount_ = 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.
Trailing underscore for member names isn't idiomatic in LLVM. I think it'd make more sense to put that on the constructor parameter.
| @@ -0,0 +1,173 @@ | |||
| //===--- SymbolFilter.h - Utils for Symbol Filter ---*- C++ -*-===// | |||
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.
Header comment should be 80-cols wide.
| //===- LibraryResolver.h - Automatic Dynamic Library Symbol Resolution -*- C++ | ||
| //-*-===// |
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.
Header comment should be 80 cols wide.
| #ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_DYNAMICLOADER_H | ||
| #define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_DYNAMICLOADER_H |
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.
Include guard name should match file name.
| std::string getFullPath() const { return filePath; } | ||
|
|
||
| bool setFilter(BloomFilter F) { | ||
| std::lock_guard<std::shared_mutex> lock(mutex); |
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.
Note: I think that std::scoped_lock is preferred to std::lock_guard these days. They're equivalent for your purposes though -- if you want to land as is we can replace later in-tree.
| BloomFilter(uint32_t symbolCount, float falsePositiveRate, HashFunc hashFn) | ||
| : hashFunc(std::move(hashFn)) { | ||
| initialize(symbolCount, falsePositiveRate); | ||
| } |
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.
LLVM variable names should start with an upper-case letter (https://llvm.org/docs/CodingStandards.html#name-types-functions-variables-and-enumerators-properly)
| //===- LibraryScanner.h - Scanner for Shared Libraries -*- C++ | ||
| //-*-===// |
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.
Include comment should be 80-cols.
| //===----- LibraryScanner.cpp - Provide Library Scaning implementation | ||
| //-----===// |
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.
Header comment should be 80-cols.
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.
ping.
| } | ||
|
|
||
| private: | ||
| Iterator begin_; |
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.
Can we fix convention here: begin_ and friends?
| @@ -0,0 +1,475 @@ | |||
| //===- LibraryScanner.h - Scanner for Shared Libraries -*- C++ | |||
| //-*-===// | |||
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.
Can you fix these indentation/alignment?
| //===----- LibraryScanner.cpp - Provide Library Scaning implementation | ||
| //-----===// |
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.
ping.
|
Okay, I’ll fix all the comments. |
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.
LGTM, with minor comments.
Thank you very much for your patience with the review process, and all the hard work that you have put into this patch. I'm excited to see this getting upstreamed!
| auto enumerateSymbolsIfNeeded = [&]() { | ||
| if (hasEnumerated) | ||
| return; | ||
|
|
||
| hasEnumerated = true; | ||
|
|
||
| LLVM_DEBUG(dbgs() << "Enumerating symbols in library: " << Lib.getFullPath() | ||
| << "\n";); | ||
| SymbolEnumerator::enumerateSymbols( | ||
| Lib.getFullPath(), | ||
| [&](StringRef sym) { | ||
| discoveredSymbols.insert(sym); | ||
| return EnumerateResult::Continue; | ||
| }, | ||
| Opts); | ||
| }; |
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.
It looks like this is only called once below -- could the body of this lambda just be moved down to the call-point?
| StringSet<> discoveredSymbols; | ||
| bool hasEnumerated = false; |
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.
Symbol names should be upper-case, but these cosmetic issues can be fixed up in-tree at this point.
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/10/builds/15619 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/190/builds/29226 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/203/builds/26516 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/205/builds/25305 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/204/builds/25328 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/140/builds/32587 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/206/builds/7651 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/80/builds/16779 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/160/builds/26763 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/180/builds/26903 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/218/builds/281 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/27/builds/17648 Here is the relevant piece of the build log for the reference |
…resolved symbols." (#163943) Reverts llvm/llvm-project#148410 Reverting this change due to a few buildbot/test failures. Will investigate and reapply once the issues are resolved.
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/145/builds/10315 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/151/builds/7044 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/97/builds/8899 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/118/builds/8554 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/23/builds/14754 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/76/builds/13215 Here is the relevant piece of the build log for the reference |
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/130/builds/15738 Here is the relevant piece of the build log for the reference |
…olved symbols. llvm#148410 (llvm#164551)" This reverts commit 4f53413.
…mbols. llvm#148410 (llvm#164551) This PR reapplies the changes previously introduced in llvm#148410. It introduces a redesigned and rebuilt Cling-based auto-loading workaround that enables scanning libraries and resolving unresolved symbols within those libraries.
…olved symbols. llvm#148410" (llvm#165069) Reverting llvm#164551 due to persistent build bot failure caused by a path difference issue.
This PR introduces a redesigned and rebuilt Cling-based auto-loading workaround, which enables scanning libraries and searching for unresolved symbols within the scanned libraries.