llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.06k stars 11.98k forks source link

Clang-17 gets an internal error while building OpenSSH-9.5-P1 due to -fzero-call-used-regs #69794

Open debohman opened 1 year ago

debohman commented 1 year ago
0.  Program arguments: cc -g -O2 -pipe -Wunknown-warning-option -Qunused-arguments -Wall -Wpointer-arith -Wuninitialized -Wsign-compare -Wformat-security -Wsizeof-pointer-memaccess -Wno-pointer-sign -Wno-unused-result -Wmisleading-indentation -Wbitwise-instead-of-logical -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -ftrapv -fzero-call-used-regs=all -ftrivial-auto-var-init=zero -fno-builtin-memset -fstack-protector-strong -fPIE -I. -I. -I/usr/local/include -I/usr/local/include -I/usr/local/include/editline -DOPENSSL_API_COMPAT=0x10100000L -DSSHDIR=\"/usr/local/etc/ssh\" -D_PATH_SSH_PROGRAM=\"/usr/local/bin/ssh\" -D_PATH_SSH_ASKPASS_DEFAULT=\"/usr/local/libexec/ssh-askpass\" -D_PATH_SFTP_SERVER=\"/usr/local/libexec/sftp-server\" -D_PATH_SSH_KEY_SIGN=\"/usr/local/libexec/ssh-keysign\" -D_PATH_SSH_PKCS11_HELPER=\"/usr/local/libexec/ssh-pkcs11-helper\" -D_PATH_SSH_SK_HELPER=\"/usr/local/libexec/ssh-sk-helper\" -D_PATH_SSH_PIDDIR=\"/var/run\" -D_PATH_PRIVSEP_CHROOT_DIR=\"/var/empty\" -DHAVE_CONFIG_H -c ssh-ecdsa-sk.c -o ssh-ecdsa-sk.o
1.  <eof> parser at end of file
2.  Code generation
3.  Running pass 'Function Pass Manager' on module 'ssh-ecdsa-sk.c'.
4.  Running pass 'Prologue/Epilogue Insertion & Frame Finalization' on function '@ssh_ecdsa_sk_cleanup'
 #0 0x000000010f52f008 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/usr/local/bin/cc+0x101447008)
 #1 0x000000010f52d0e9 llvm::sys::RunSignalHandlers() (/usr/local/bin/cc+0x1014450e9)
 #2 0x000000010f52e641 llvm::sys::CleanupOnSignal(unsigned long) (/usr/local/bin/cc+0x101446641)
 #3 0x000000010f481881 CrashRecoverySignalHandler(int) (/usr/local/bin/cc+0x101399881)
 #4 0x00007fff99b84b3a (/usr/lib/system/libsystem_platform.dylib+0x7fff8b3a5b3a)
 #5 0x00007fcbafb23c00 
 #6 0x000000010e89147a llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (/usr/local/bin/cc+0x1007a947a)
 #7 0x000000010ecbef65 llvm::FPPassManager::runOnFunction(llvm::Function&) (/usr/local/bin/cc+0x100bd6f65)
 #8 0x000000010ecc67d4 llvm::FPPassManager::runOnModule(llvm::Module&) (/usr/local/bin/cc+0x100bde7d4)
 #9 0x000000010ecbfc3c llvm::legacy::PassManagerImpl::run(llvm::Module&) (/usr/local/bin/cc+0x100bd7c3c)
#10 0x000000010f8b33f3 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::__1::unique_ptr<llvm::raw_pwrite_stream, std::__1::default_delete<llvm::raw_pwrite_stream>>) (/usr/local/bin/cc+0x1017cb3f3)
#11 0x000000010fc574ab clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/usr/local/bin/cc+0x101b6f4ab)
#12 0x0000000111093c86 clang::ParseAST(clang::Sema&, bool, bool) (/usr/local/bin/cc+0x102fabc86)
#13 0x000000011005487a clang::FrontendAction::Execute() (/usr/local/bin/cc+0x101f6c87a)
#14 0x000000010ffafec4 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/usr/local/bin/cc+0x101ec7ec4)
#15 0x00000001100d8c53 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/usr/local/bin/cc+0x101ff0c53)
#16 0x000000010e0eff89 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/usr/local/bin/cc+0x100007f89)
#17 0x000000010e0edf23 ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) (/usr/local/bin/cc+0x100005f23)
#18 0x000000010fdba7de void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::__1::optional<llvm::StringRef>>, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>*, bool*) const::$_0>(long) (/usr/local/bin/cc+0x101cd27de)
#19 0x000000010f48163c llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/usr/local/bin/cc+0x10139963c)
#20 0x000000010fdb9feb clang::driver::CC1Command::Execute(llvm::ArrayRef<std::__1::optional<llvm::StringRef>>, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>*, bool*) const (/usr/local/bin/cc+0x101cd1feb)
#21 0x000000010fd7a614 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/usr/local/bin/cc+0x101c92614)
#22 0x000000010fd7aaef clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::__1::pair<int, clang::driver::Command const*>>&, bool) const (/usr/local/bin/cc+0x101c92aef)
#23 0x000000010fd9b470 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::__1::pair<int, clang::driver::Command const*>>&) (/usr/local/bin/cc+0x101cb3470)
#24 0x000000010e0ed221 clang_main(int, char**, llvm::ToolContext const&) (/usr/local/bin/cc+0x100005221)
#25 0x000000010e0fb244 main (/usr/local/bin/cc+0x100013244)
#26 0x00007fff99975235 (/usr/lib/system/libdyld.dylib+0x7fff8b196235)
#27 0x000000000000002c 
cc: error: clang frontend command failed with exit code 139 (use -v to see invocation)
clang version 17.0.3
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /usr/local/bin
debohman commented 1 year ago

ssh-ecdsa-sk-5fbb7e.zip

debohman commented 1 year ago

Removing the use of -fzero-call-used-regs allows the project to build successfully.

bwendling commented 1 year ago

I compiled this with the offending compilers and couldn't replicate the failure. That was on a Linux box though. I'm not sure if an Apple build of Clang acts subtly diffrently.

debohman commented 1 year ago

OpenSSH apparently ran into this with Clang-15. Normally, they use -fzero-call-used-regs=all, and in the case of Clang-15, they substitute -fzero-call-used-regs=used. Now, with Clang-17, you can't use -fzero-call-used-regs=used either.

I tried to build the previous version of OpenSSH V_9_4_P1, and it fails in the exact same way as V_9_5_P1. V_9_4_P1 was previously built successfully with Clang-16.

daztucker commented 1 year ago

OpenSSH apparently ran into this with Clang-15.

That was the same flag but different symptom: it generated code that had nodeterministic failures (ie the compilation was nondeterministic; some compilations produced working binaries, some produced binaries that failed but IME a given binary would behave deterministically).

https://bugzilla.mindrot.org/show_bug.cgi?id=3475

debohman commented 1 year ago

OpenSSH apparently ran into this with Clang-15.

That was the same flag but different symptom: it generated code that had nodeterministic failures (ie the compilation was nondeterministic; some compilations produced working binaries, some produced binaries that failed but IME a given binary would behave deterministically).

https://bugzilla.mindrot.org/show_bug.cgi?id=3475

You are correct, it is a different failure involving -fzero-call-used-regs.

debohman commented 1 year ago

I just successfully built OpenSSH V_9_5_P1 using Clang 16.0.5. This used -fzero-call-used-regs=all.

bwendling commented 11 months ago

Could you run creduce on the attached bad file? It might help in understanding what's going on and how I can reproduce it on my end.

debohman commented 11 months ago

I assume you are talking about creduce? I tried to build it against clang-17, and it did not build successfully.

thesamesam commented 11 months ago

cvise will do the job as well.

debohman commented 11 months ago

I was able to make the project build with the following diffs:

diff --git a/ssh-ecdsa-sk.c b/ssh-ecdsa-sk.c
index 5dcd3c13d..40fe3af11 100644
--- a/ssh-ecdsa-sk.c
+++ b/ssh-ecdsa-sk.c
@@ -68,7 +68,7 @@ static void
 ssh_ecdsa_sk_cleanup(struct sshkey *k)
 {
    sshkey_sk_cleanup(k);
-   sshkey_ecdsa_funcs.cleanup(k);
+// sshkey_ecdsa_funcs.cleanup(k);
 }

 static int
diff --git a/ssh-ed25519-sk.c b/ssh-ed25519-sk.c
index c6bc5e72b..771b9df39 100644
--- a/ssh-ed25519-sk.c
+++ b/ssh-ed25519-sk.c
@@ -42,7 +42,7 @@ static void
 ssh_ed25519_sk_cleanup(struct sshkey *k)
 {
    sshkey_sk_cleanup(k);
-   sshkey_ed25519_funcs.cleanup(k);
+// sshkey_ed25519_funcs.cleanup(k);
 }

 static int

Does that help to narrow it down at all?

FYI, I am now using Clang-17.0.5.

bwendling commented 11 months ago

It would be much better to have a compilable example to work with. It's not going to fail on my machines as is, so I need to be able to step through and look at what's potentially happening. But I'll see what I can do.

debohman commented 11 months ago

Reversing the lines in the two functions compiles successfully. It may be the tail call through a function pointer.

bwendling commented 11 months ago

Reversing the lines in the two functions compiles successfully. It may be the tail call through a function pointer.

Yeah, here's what I generate. (Notice that %rax isn't modified before the tail call.) Unfortunately, in your backtrace the important information detailing where the assert is happening is missing...:-/

        movq    sshkey_ecdsa_funcs@GOTPCREL(%rip), %rax
        .loc    1 71 2 is_stmt 0                # ssh-ecdsa-sk.c:71:2
        movq    %rbx, %rdi
        .loc    1 71 2 epilogue_begin           # ssh-ecdsa-sk.c:71:2
        popq    %rbx
.Ltmp2:
        #DEBUG_VALUE: ssh_ecdsa_sk_cleanup:k <- $rdi
        .cfi_def_cfa_offset 8
        fldz
        fldz
        fldz
        fldz
        fldz
        fldz
        fldz
        fldz
        fstp    %st(0)
        fstp    %st(0)
        fstp    %st(0)
        fstp    %st(0)
        fstp    %st(0)
        fstp    %st(0)
        fstp    %st(0)
        fstp    %st(0)
        xorl    %ecx, %ecx
        xorl    %edx, %edx
        xorl    %esi, %esi
        xorl    %r8d, %r8d
        xorl    %r9d, %r9d
        xorl    %r10d, %r10d
        xorl    %r11d, %r11d
        xorps   %xmm0, %xmm0
        xorps   %xmm1, %xmm1
        xorps   %xmm2, %xmm2
        xorps   %xmm3, %xmm3
        xorps   %xmm4, %xmm4
        xorps   %xmm5, %xmm5
        xorps   %xmm6, %xmm6
        xorps   %xmm7, %xmm7
        xorps   %xmm8, %xmm8
        xorps   %xmm9, %xmm9
        xorps   %xmm10, %xmm10
        xorps   %xmm11, %xmm11
        xorps   %xmm12, %xmm12
        xorps   %xmm13, %xmm13
        xorps   %xmm14, %xmm14
        xorps   %xmm15, %xmm15
.Ltmp3:
        jmpq    *16(%rax)                       # TAILCALL
bwendling commented 11 months ago

Okay. I'd appreciate it if you can do this. Run the compile command for ssh-ecdsa-sk.c but add -mllvm -print-after-all to it. Pipe the output into a file:

$ clang ... -mllvm -print-after-all > blob.log 2>&1

Then add it to this bug. You'll probably have to compress it first.

debohman commented 11 months ago

No problem.

blob.tar.gz