Skip to content

Compiler generates invalid program that segfault when executed #83111

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

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-lints 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.

@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-lints 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 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
@fmease fmease added A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. and removed A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. labels Dec 21, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries A-lints 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