-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[LTO] Avoid assert fail on failed pass plugin load #96691
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
Without this patch, passing -load-pass-plugin=nonexistent.so to llvm-lto2 produces a backtrace because LTOBackend.cpp does not handle the error correctly: ``` Failed to load passes from 'nonexistant.so'. Request ignored. Expected<T> must be checked before access or destruction. Unchecked Expected<T> contained error: Could not load library 'nonexistant.so': nonexistant.so: cannot open shared object file: No such file or directoryPLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace. ``` Any tool using `lto::Config::PassPlugins` should suffer similarly. Based on the message "Request ignored" and the continue statement in the implementation, this patch assumes the intention was not to cause the program to fail.
@llvm/pr-subscribers-lto Author: Joel E. Denny (jdenny-ornl) ChangesWithout this patch, passing -load-pass-plugin=nonexistent.so to llvm-lto2 produces a backtrace because LTOBackend.cpp does not handle the error correctly:
Any tool using Based on the message "Request ignored" and the continue statement in the implementation, this patch assumes the intention was not to cause the program to fail. Full diff: https://github.com/llvm/llvm-project/pull/96691.diff 2 Files Affected:
diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp
index 84a69d9ff1a1f..7931108c0ec99 100644
--- a/llvm/lib/LTO/LTOBackend.cpp
+++ b/llvm/lib/LTO/LTOBackend.cpp
@@ -192,8 +192,9 @@ static void RegisterPassPlugins(ArrayRef<std::string> PassPlugins,
for (auto &PluginFN : PassPlugins) {
auto PassPlugin = PassPlugin::Load(PluginFN);
if (!PassPlugin) {
- errs() << "Failed to load passes from '" << PluginFN
- << "'. Request ignored.\n";
+ errs() << "Failed to load passes from plugin '" << PluginFN
+ << "' (request ignored): " << toString(PassPlugin.takeError())
+ << "\n";
continue;
}
diff --git a/llvm/test/Feature/load_plugin_error.ll b/llvm/test/Feature/load_plugin_error.ll
index 24a7cce5d8d39..2b860a901ee41 100644
--- a/llvm/test/Feature/load_plugin_error.ll
+++ b/llvm/test/Feature/load_plugin_error.ll
@@ -1,5 +1,18 @@
-; REQUIRES: plugins, examples
+; REQUIRES: plugins
; UNSUPPORTED: target={{.*windows.*}}
-; RUN: not opt < %s -load-pass-plugin=%t/nonexistant.so -disable-output 2>&1 | FileCheck %s
-; CHECK: Could not load library {{.*}}nonexistant.so
+; RUN: not opt < %s -load-pass-plugin=%t/nonexistent.so -disable-output 2>&1 | FileCheck %s
+
+; RUN: opt %s -o %t.o
+; RUN: llvm-lto2 run -load-pass-plugin=%t/nonexistent.so %t.o -o %t \
+; RUN: -r %t.o,test 2>&1 | \
+; RUN: FileCheck %s
+
+; CHECK: Could not load library {{.*}}nonexistent.so
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @test() {
+ ret void
+}
|
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.
Good catch, we definitely need to consume the error in the failure state for proper behavior.
I wonder if we could make a lint for this in the LLVM codebase.
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'm not 100% sure we shouldn't stop the whole pipeline when the module fails to load. The difference in behavior between opt and llvm-lto2 is probably not a good thing :-/
I'm happy to change it to be like opt. After all, stopping on failure to load a plugin is what lto already does without this patch (but it's a crash). |
Yeah, crashing on an unhandled error is definitely incorrect, whether or not it should be ignored is a different issue but I can see the rationale. I think |
I just mean to point out that apparently no one has been too dependent on its ability to continue given that it currently crashes. |
Based on the message "Request ignored" and the continue statement, the intention was apparently to continue on failure to load a plugin. However, no one appears to rely on that behavior now given that it crashes instead, and terminating is consistent with opt.
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 now, thanks!
Thanks for the reviews. |
LGTM. Ideally LTOBackend.cpp should have a better error reporting mechanism than we do not need so many |
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/620 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/744 Here is the relevant piece of the build log for the reference:
|
This one blamed only me, but it looks irrelevant, and it passed on the next build. |
I pushed a commit to hopefully fix that and other bot fails. |
Without this patch, passing -load-pass-plugin=nonexistent.so to llvm-lto2 produces a backtrace because LTOBackend.cpp does not handle the error correctly: ``` Failed to load passes from 'nonexistant.so'. Request ignored. Expected<T> must be checked before access or destruction. Unchecked Expected<T> contained error: Could not load library 'nonexistant.so': nonexistant.so: cannot open shared object file: No such file or directoryPLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace. ``` Any tool using `lto::Config::PassPlugins` should suffer similarly. Based on the message "Request ignored" and the continue statement, the intention was apparently to continue on failure to load a plugin. However, no one appears to rely on that behavior now given that it crashes instead, and terminating is consistent with opt.
Without this patch, passing -load-pass-plugin=nonexistent.so to llvm-lto2 produces a backtrace because LTOBackend.cpp does not handle the error correctly: ``` Failed to load passes from 'nonexistant.so'. Request ignored. Expected<T> must be checked before access or destruction. Unchecked Expected<T> contained error: Could not load library 'nonexistant.so': nonexistant.so: cannot open shared object file: No such file or directoryPLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace. ``` Any tool using `lto::Config::PassPlugins` should suffer similarly. Based on the message "Request ignored" and the continue statement, the intention was apparently to continue on failure to load a plugin. However, no one appears to rely on that behavior now given that it crashes instead, and terminating is consistent with opt.
The original version was introduced here in 2476cd3.
Without this patch, passing -load-pass-plugin=nonexistent.so to llvm-lto2 produces a backtrace because LTOBackend.cpp does not handle the error correctly:
Any tool using
lto::Config::PassPlugins
should suffer similarly.Based on the message "Request ignored" and the continue statement, the intention was apparently to continue on failure to load a plugin. However, no one appears to rely on that behavior now given that it crashes instead, and terminating is consistent with opt.