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

Compiler generates invalid program that segfault when executed #83111

Closed
marmeladema opened this issue Mar 14, 2021 · 3 comments
Closed

Compiler generates invalid program that segfault when executed #83111

marmeladema opened this issue Mar 14, 2021 · 3 comments
Labels
A-linkage Area: linking into static, shared libraries and binaries A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@marmeladema
Copy link
Contributor

marmeladema commented Mar 14, 2021

I tried this code:

#[no_mangle]
extern "C" fn new() -> Box<usize> {
    Box::new(42)
}

#[no_mangle]
extern "C" fn free(_: Option<Box<usize>>) {}

fn main() {
    let a = new();
    println!("a = {}", a);
}

Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f5501d69b691435bbdcf9c758de6111b

I expected to see this happen:

A valid program is being generated by the compiler and it prints a = 42 and then exists when executed.

Instead, this happened:

The program segfaults when executed.

Meta

You can verify using the playground link that its segfaulting on:

  • stable: currently 1.50.0
  • beta
  • nightly

I also manually tried locally with 1.49.0 and it also segfaults.

Debug

Debugging with gdb:

Program received signal SIGSEGV, Segmentation fault.
0x000055555555942e in alloc::alloc::box_free ()
(gdb) bt
#0  0x000055555555942e in alloc::alloc::box_free ()
#1  0x000055555555991d in core::ptr::drop_in_place ()
#2  0x00005555555598ef in core::ptr::drop_in_place ()
#3  0x000055555555995d in free ()
#4  0x0000555555559417 in alloc::alloc::dealloc ()
#5  0x0000555555559588 in <alloc::alloc::Global as core::alloc::AllocRef>::dealloc ()
#6  0x00005555555594d1 in alloc::alloc::box_free ()
#7  0x000055555555991d in core::ptr::drop_in_place ()
#8  0x00005555555598ef in core::ptr::drop_in_place ()
#9  0x000055555555995d in free ()
#10 0x0000555555559417 in alloc::alloc::dealloc ()
#11 0x0000555555559588 in <alloc::alloc::Global as core::alloc::AllocRef>::dealloc ()
#12 0x00005555555594d1 in alloc::alloc::box_free ()
#13 0x000055555555991d in core::ptr::drop_in_place ()
#14 0x00005555555598ef in core::ptr::drop_in_place ()
#15 0x000055555555995d in free ()
#16 0x0000555555559417 in alloc::alloc::dealloc ()
#17 0x0000555555559588 in <alloc::alloc::Global as core::alloc::AllocRef>::dealloc ()
#18 0x00005555555594d1 in alloc::alloc::box_free ()
#19 0x000055555555991d in core::ptr::drop_in_place ()
#20 0x00005555555598ef in core::ptr::drop_in_place ()
#21 0x000055555555995d in free ()
#22 0x0000555555559417 in alloc::alloc::dealloc ()
#23 0x0000555555559588 in <alloc::alloc::Global as core::alloc::AllocRef>::dealloc ()
#24 0x00005555555594d1 in alloc::alloc::box_free ()
#25 0x000055555555991d in core::ptr::drop_in_place ()
#26 0x00005555555598ef in core::ptr::drop_in_place ()
#27 0x000055555555995d in free ()
#28 0x0000555555559417 in alloc::alloc::dealloc ()
#29 0x0000555555559588 in <alloc::alloc::Global as core::alloc::AllocRef>::dealloc ()

The whole call stack is filled by calls to free. I guess it makes sense in some way since that I mistakenly re-defined free with a function that calls itself, leading to a recursive call "loop".

I fully understand that problem is on my side, I probably should not have re-defined free but arguably when defining ffi-compatible function, one could re-use an already existing libc function name without realizing it and thus leading to all sort of surprising behavior.

Maybe the compiler should:

  • provide a compiler warning
  • do not allow to replace a libc symbol unless explicitly requesting it using a function attribute or something
@marmeladema marmeladema added the C-bug Category: This is a bug. label Mar 14, 2021
@marmeladema
Copy link
Contributor Author

Feel free to close this if it's just an expected behavior.

@ghost
Copy link

ghost commented Mar 14, 2021

I think this is a duplicate of #28179. You can tame it by using #![forbid(unsafe_code)]: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=58866edf5cbfad0f01f6ea1c6bcebe42.

@ChrisDenton ChrisDenton added the needs-triage-legacy Old issue that were never triaged. Remove this label once the issue has been sufficiently triaged. label Jul 16, 2023
@fmease fmease added A-linkage Area: linking into static, shared libraries and binaries C-enhancement Category: An issue proposing an enhancement or a PR with one. A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed C-bug Category: This is a bug. needs-triage-legacy Old issue that were never triaged. Remove this label once the issue has been sufficiently triaged. labels Jan 23, 2024
@fmease
Copy link
Member

fmease commented Jan 23, 2024

Closing as duplicate of #28179.

@fmease fmease closed this as not planned Won't fix, can't repro, duplicate, stale Jan 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries A-lint Area: Lints (warnings about flaws in source code) such as unused_mut. C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants