Skip to content

Segfault from from 100% safe code #139566

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

Closed
dstu opened this issue Apr 9, 2025 · 3 comments
Closed

Segfault from from 100% safe code #139566

dstu opened this issue Apr 9, 2025 · 3 comments
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues.

Comments

@dstu
Copy link
Contributor

dstu commented Apr 9, 2025

I have 100% safe code that segfaults, presumably due to stack exhaustion.

Exhausting stack space in a simple Rust program triggers telltale error messages (thread 'foo' has overflowed its stack, fatal runtime error: stack overflow) and death via SIGABRT. In the behavior I have encountered, these messages are not printed, and the process is killed with SIGSEGV.

It is my understanding that a crate consisting of 100% safe Rust (even if it has bugs) should not segfault like this. I would expect an explicit stack exhaustion error and death by SIGABRT. When examining this in gdb, I see a large number of stack frames (over 40,000) due to the erroneous fmt::Display implementation. In the bottom frame, there is a clear null pointer dereference (call to a method where &self has address 0).

Example code can be found at https://git.sdf.org/vitrine/shatterc/src/branch/reproduce-segfault. You can reproduce this with these steps:

  1. Clone https://git.sdf.org/vitrine/shatterc.git
  2. Switch to the reproduce-segfault branch
  3. Execute cargo run -- example-cycle.c

Two thoughts about where to look next:

@dstu dstu added the C-bug Category: This is a bug. label Apr 9, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Apr 9, 2025
@zachs18
Copy link
Contributor

zachs18 commented Apr 9, 2025

Line 35 of main.rs calls clang::Index::new, which calls clang_sys::clang_createIndex, which is this, which calls this, which (unless the LIBCLANG_DISABLE_CRASH_RECOVERY env var is set), calls llvm::CrashRecoveryContext::Enable(), which calls installExceptionOrSignalHandlers(), which sets a SIGSEGV handler (and some other signals), overriding Rust's SIGSEGV handler.

If I set LIBCLANG_DISABLE_CRASH_RECOVERY=yes, then I do see the thread 'main' has overflowed its stack fatal runtime error: stack overflow message printed from Rust's SIGSEGV handler.

@saethlin saethlin added C-discussion Category: Discussion or questions that doesn't represent real issues. and removed C-bug Category: This is a bug. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Apr 10, 2025
@saethlin
Copy link
Member

So this isn't 100% safe code. I think it's fair to call this expected, though you can argue with clang/LLVM about whether this behavior is good.

@saethlin saethlin closed this as not planned Won't fix, can't repro, duplicate, stale Apr 10, 2025
@dstu
Copy link
Contributor Author

dstu commented Apr 10, 2025

Thanks for taking a look, and good catch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues.
Projects
None yet
Development

No branches or pull requests

4 participants