Skip to content

Panic backtrace doesn't traverse ffi code with panic=abort #88275

Open
@glandium

Description

@glandium

I tried this code:

Cargo.toml:

[package]
name = "testcase"
version = "0.1.0"
edition = "2018"

[profile.release]
panic="abort"

[profile.dev]
panic="abort"

[build-dependencies]
cc = "1"

build.rs:

fn main() {
    cc::Build::new().file("foo.c").compile("foo");
}

foo.c:

#include <stdio.h>

extern void do_rust_panic(const char *msg);

void foo() {
	do_rust_panic("foo");
        // prevent tail-call optimization so that the frame for foo is always there
	printf("foo\n");
}

src/main.rs:

use std::ffi::CStr;
use std::os::raw::c_char;

#[no_mangle]
pub unsafe extern "C" fn do_rust_panic(message: *const c_char) {
    panic!("{}", CStr::from_ptr(message).to_string_lossy());
}

extern "C" {
    fn foo();
}

fn main() {
    unsafe {
        foo();
    }
    // prevent tail-call optimization so that the frame for main is always there
    println!("Hello, world!");
}

I expected to see this happen: the panic backtrace would traverse the ffi code, like it does without panic=abort.

Instead, this happened: the panic backtrace stops at do_rust_panic:

$ RUST_BACKTRACE=1 cargo run --release
    Finished release [optimized] target(s) in 0.00s
     Running `target/release/testcase`
Hello, world!
thread 'main' panicked at 'foo', src/main.rs:6:5
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/panicking.rs:515:5
   1: std::panicking::begin_panic_fmt
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/panicking.rs:457:5
   2: do_rust_panic
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Without panic=abort:

$ RUST_BACKTRACE=1 cargo run --release
    Finished release [optimized] target(s) in 0.00s
     Running `target/release/testcase`
thread 'main' panicked at 'foo', src/main.rs:6:5
stack backtrace:
   0: rust_begin_unwind
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/panicking.rs:515:5
   1: std::panicking::begin_panic_fmt
             at /rustc/a178d0322ce20e33eac124758e837cbd80a6f633/library/std/src/panicking.rs:457:5
   2: do_rust_panic
   3: foo
   4: testcase::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Meta

rustc --version --verbose:

rustc 1.54.0 (a178d0322 2021-07-26)
binary: rustc
commit-hash: a178d0322ce20e33eac124758e837cbd80a6f633
commit-date: 2021-07-26
host: x86_64-unknown-linux-gnu
release: 1.54.0
LLVM version: 12.0.1

Also reproducible with nightly:

rustc 1.56.0-nightly (af140757b 2021-08-22)
binary: rustc
commit-hash: af140757b4cb1a60d107c690720311ba8e06e7de
commit-date: 2021-08-22
host: x86_64-unknown-linux-gnu
release: 1.56.0-nightly
LLVM version: 13.0.0

I tried tweaking the FFI build flags, adding combinations of -fno-omit-frame-pointer, -funwind-tables and -g, and none of them changed anything.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-backtraceArea: BacktracesA-docsArea: Documentation for any part of the project, including the compiler, standard library, and toolsA-panicArea: Panicking machineryC-enhancementCategory: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions