Skip to content
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

SIGSEGV (invalid address) from LLVM in rustc with asm and #[naked] fn #77848

Closed
Restioson opened this issue Oct 12, 2020 · 7 comments · Fixed by #79411
Closed

SIGSEGV (invalid address) from LLVM in rustc with asm and #[naked] fn #77848

Restioson opened this issue Oct 12, 2020 · 7 comments · Fixed by #79411
Labels
A-inline-assembly Area: Inline assembly (`asm!(…)`) A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-naked Area: `#[naked]`, prologue and epilogue-free, functions, https://git.io/vAzzS C-bug Category: This is a bug. I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics. requires-nightly This issue requires a nightly compiler in some way.

Comments

@Restioson
Copy link

Restioson commented Oct 12, 2020

After making some modifications to a relatively complex project, I received a SIGSEGV from rustc:

* thread #6, name = 'rustc', stop reason = signal SIGSEGV: invalid address (fault address: 0xe10134000)
  * frame #0: 0x00007ffff29dc8ca libLLVM-11-rust-1.49.0-nightly.so`llvm::X86TargetLowering::isZExtFree(llvm::SDValue, llvm::EVT) const + 10
...
    frame #12: 0x00007ffff418c140 librustc_driver-9deb636e5c5c0be1.so`LLVMRustWriteOutputFile + 528

Full backtrace from LLDB.

This originates in the compilation of the crate itself rather than any of its dependencies.

The crate is using quite a few unstable features in its .cargo/config, a custom target json, and the following unstable features: asm, lang_items, allocator_api, alloc_error_handler, panic_info_message, abi_x86_interrupt, naked_functions. However, it appears that the culprit is a particularly complex asm block, as commenting it out makes it compile successfully:

asm!(
    "
    mov ax, 0x33
    mov ds, ax
    mov es, ax
    mov fs, ax
    mov gs, ax
    mov rsp, {0}

    mov rax, rsp
    push 0x33
    push rax
    pushfq

    push 0x2b
    mov rax, {1}
    push rax
    iretq,
    ",
    in(reg) stack_ptr,
    in(reg) instruction_ptr,
    lateout("rax") _
);

This occurs inside of a #[naked] function here. Removing #[naked] causes the segfault to go away.

I have no idea whether this asm block is actually correct, both in terms of macro invocation and assembly, but either way I would not expect a segfault.

Meta

rustc --version --verbose:

rustc 1.49.0-nightly (c71248b70 2020-10-11)
binary: rustc
commit-hash: c71248b70870960af9993de4f31d3cba9bbce7e8
commit-date: 2020-10-11
host: x86_64-unknown-linux-gnu
release: 1.49.0-nightly
LLVM version: 11.0
Backtrace

* thread #6, name = 'rustc', stop reason = signal SIGSEGV: invalid address (fault address: 0xe10134000)
  * frame #0: 0x00007ffff29dc8ca libLLVM-11-rust-1.49.0-nightly.so`llvm::X86TargetLowering::isZExtFree(llvm::SDValue, llvm::EVT) const + 10
    frame #1: 0x00007ffff0b56ff7 libLLVM-11-rust-1.49.0-nightly.so`llvm::RegsForValue::getCopyToRegs(llvm::SDValue, llvm::SelectionDAG&, llvm::SDLoc const&, llvm::SDValue&, llvm::SDValue*, llvm::Value const*, llvm::ISD::NodeType) const + 503
    frame #2: 0x00007ffff0b7d50d libLLVM-11-rust-1.49.0-nightly.so`llvm::SelectionDAGBuilder::visitInlineAsm(llvm::CallBase const&) + 15101
    frame #3: 0x00007ffff0b5a547 libLLVM-11-rust-1.49.0-nightly.so`llvm::SelectionDAGBuilder::visit(llvm::Instruction const&) + 103
    frame #4: 0x00007ffff0c1a1de libLLVM-11-rust-1.49.0-nightly.so`llvm::SelectionDAGISel::SelectBasicBlock(llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Instruction, false, false, void>, false, true>, llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Instruction, false, false, void>, false, true>, bool&) + 302
    frame #5: 0x00007ffff0c19473 libLLVM-11-rust-1.49.0-nightly.so`llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) + 7651
    frame #6: 0x00007ffff0c16606 libLLVM-11-rust-1.49.0-nightly.so`llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) + 3030
    frame #7: 0x00007ffff29353e7 libLLVM-11-rust-1.49.0-nightly.so`(anonymous namespace)::X86DAGToDAGISel::runOnMachineFunction(llvm::MachineFunction&) + 151
    frame #8: 0x00007ffff077f44e libLLVM-11-rust-1.49.0-nightly.so`llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 270
    frame #9: 0x00007ffff0559c92 libLLVM-11-rust-1.49.0-nightly.so`llvm::FPPassManager::runOnFunction(llvm::Function&) + 1618
    frame #10: 0x00007ffff05606a3 libLLVM-11-rust-1.49.0-nightly.so`llvm::FPPassManager::runOnModule(llvm::Module&) + 51
    frame #11: 0x00007ffff055a6ea libLLVM-11-rust-1.49.0-nightly.so`llvm::legacy::PassManagerImpl::run(llvm::Module&) + 1706
    frame #12: 0x00007ffff418c140 librustc_driver-9deb636e5c5c0be1.so`LLVMRustWriteOutputFile + 528
    frame #13: 0x00007ffff40abbdc librustc_driver-9deb636e5c5c0be1.so`rustc_codegen_llvm::back::write::write_output_file::h46d5fc2269ff2c68 + 92
    frame #14: 0x00007ffff40b095c librustc_driver-9deb636e5c5c0be1.so`rustc_codegen_llvm::back::write::codegen::hcd9421f191029966 + 4876
    frame #15: 0x00007ffff40dc52b librustc_driver-9deb636e5c5c0be1.so`rustc_codegen_ssa::back::write::finish_intra_module_work::h867579b3376f579c + 219
    frame #16: 0x00007ffff40d69ce librustc_driver-9deb636e5c5c0be1.so`rustc_codegen_ssa::back::write::execute_work_item::h7ad959003256922b + 3118
    frame #17: 0x00007ffff3fabd4f librustc_driver-9deb636e5c5c0be1.so`std::sys_common::backtrace::__rust_begin_short_backtrace::hba6542b44391edb1 + 207
    frame #18: 0x00007ffff40489d5 librustc_driver-9deb636e5c5c0be1.so`core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h7493f76d5c01ce84 + 101
    frame #19: 0x00007ffff33df86a libstd-6e0e72ef3f331f94.so`std::sys::unix::thread::Thread::new::thread_start::hb4b79d379b730058 [inlined] _$LT$alloc..boxed..Box$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$A$GT$$GT$::call_once::h588ce842808b3fd0 at boxed.rs:1042:9
    frame #20: 0x00007ffff33df864 libstd-6e0e72ef3f331f94.so`std::sys::unix::thread::Thread::new::thread_start::hb4b79d379b730058 [inlined] _$LT$alloc..boxed..Box$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$A$GT$$GT$::call_once::h46bc655f05471a92 at boxed.rs:1042
    frame #21: 0x00007ffff33df85b libstd-6e0e72ef3f331f94.so`std::sys::unix::thread::Thread::new::thread_start::hb4b79d379b730058 at thread.rs:87
    frame #22: 0x00007ffff32f8609 libpthread.so.0`start_thread(arg=<unavailable>) at pthread_create.c:477:8
    frame #23: 0x00007ffff320c293 libc.so.6`__clone + 67

@Restioson Restioson added the C-bug Category: This is a bug. label Oct 12, 2020
@tesuji
Copy link
Contributor

tesuji commented Oct 12, 2020

Please check again. There is a comma (,) after iretq makes the code to be not compiled.
https://rust.godbolt.org/z/sPdnYe

@Restioson
Copy link
Author

Restioson commented Oct 12, 2020

Even with that adjusted, it unfortunately still crashes with SIGSEGV :( Thanks for the catch though!

Looks like that asm alone works fine given the godbolt, but it doesn't work in the project. Maybe this is due to other unstable features used in it.

@tesuji
Copy link
Contributor

tesuji commented Oct 12, 2020

The function contains the asm! snippet is here:
https://github.com/Restioson/wolffia/blob/48262b965e83d7263c4200c9e6de4d05958c0d12/kernel/src/userspace/jump.rs

But it is a naked function. Not a normal one.

@Restioson
Copy link
Author

Restioson commented Oct 12, 2020

Indeed, that's intentional (I think... this code is very old and I'm just coming back to it now to update to latest rust version). Could that be causing it somehow? However, in godbolt adding #[naked] still doesn't cause a segfault with the well-formed or invalid syntax https://rust.godbolt.org/z/KrKMrb

@Restioson
Copy link
Author

Restioson commented Oct 12, 2020

I think that must be a key part of the issue. In the actual project, if I remove the #[naked] attribute then it will not segfault anymore and correctly report the syntax error.

@Restioson Restioson changed the title SIGSEGV (invalid address) from LLVM in rustc with new asm macro SIGSEGV (invalid address) from LLVM in rustc with asm and #[naked] fn Oct 12, 2020
@jonas-schievink jonas-schievink added A-inline-assembly Area: Inline assembly (`asm!(…)`) A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-naked Area: `#[naked]`, prologue and epilogue-free, functions, https://git.io/vAzzS I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics. labels Oct 12, 2020
@mati865
Copy link
Contributor

mati865 commented Oct 12, 2020

Even though stack is different I think this is duplicate of #75922

@Restioson
Copy link
Author

That seems highly likely. If it is UB as is said in that thread it could be manifesting in different ways, leading to different stack traces. Apologies, I didn't see that issue. Shall I close?

@nagisa nagisa added the requires-nightly This issue requires a nightly compiler in some way. label Oct 12, 2020
@bors bors closed this as completed in b48cafd Nov 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-inline-assembly Area: Inline assembly (`asm!(…)`) A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-naked Area: `#[naked]`, prologue and epilogue-free, functions, https://git.io/vAzzS C-bug Category: This is a bug. I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics. requires-nightly This issue requires a nightly compiler in some way.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants