rust-bindgen icon indicating copy to clipboard operation
rust-bindgen copied to clipboard

SIGSEGV / Segfault in 0.61.0

Open SWW13 opened this issue 2 years ago • 8 comments

I just upgraded bindgen to 0.63.0 and was greeted with a segfault. A little bit of manual bisect yielded version 0.61.0 as the first offender.

I'll start digging deeper into the issue soon, I plan to do a git bisect to figure out the commit that introduced the issue and if that doesn't help try to get my build-system running with gdb attached for a backtrace. I'm also open to other debugging suggestions.

Note: this could be duplicate of #2035, but bindgen still works fine for me up until the segfault in 0.61.0 and above.

Input C/C++ Header

It's a large code base with long build times, I'd rather not try to find a minimal reproducer if possible.

Bindgen Invocation

bindgen::Builder::default()
        .derive_debug(true)
        .derive_default(true)
        .impl_debug(true)
        .generate_comments(true)
        .default_enum_style(bindgen::EnumVariation::NewType {
            is_bitfield: false,
            is_global: false, // new in `0.61.0`, same crash with `true`
        })
        .header("wrapper.h")
        .clang_args(crate::bindgen_clang_args()) // extracted from build target
        .allowlist_*("...")
        .blocklist_function("main_loop_wait") // bindgen issue #1313
        .parse_callbacks(Box::new(bindgen::CargoCallbacks))
        .generate()

Actual Results

error: failed to run custom build command for `crate`

Caused by:
  process didn't exit successfully: `/crate-b7933947bb539228/build-script-build` (signal: 11, SIGSEGV: invalid memory reference)

Expected Results

No segfault.

SWW13 avatar Jan 24 '23 15:01 SWW13

These kind of errors are usually bugs while using the clang-sys crate so I suspect that the introduction of the EnumVariation::NewType::is_global field is not the issue as that PR only changed code generation.

I'd be grateful if you could either try and git bisect this as you mentioned or provide case that I can actually run.

pvdrz avatar Jan 24 '23 20:01 pvdrz

There you go:

a5848cf44e02645cddf020609ea67340cf6e3d24 is the first bad commit
commit a5848cf44e02645cddf020609ea67340cf6e3d24
Author: Collin Baker <[email protected]>
Date:   Wed Jul 20 11:57:16 2022 -0400

    Generate opaque type for template param dependent bit field width

    libclang's API does not provide a straightforward way to check for
    this, and calling clang_getFieldDeclBitWidth is actively unsafe in
    this case. See https://github.com/llvm/llvm-project/issues/56644

    We probably can't generate reasonable bindings for such a type, so
    make the binding opaque.

    Ideally libclang would report if the bit width could not be
    evaluated. Unfortunately making such a change would mean bumping the
    minimum libclang version from 6.0 to 15.0.

    Instead, add logic to traverse the AST subtree starting from the
    field's bit width specifier looking for template parameters. If we
    find one, we make the resulting type opaque.

 src/clang.rs                                       | 96 +++++++++++++++++++++-
 src/ir/comp.rs                                     | 26 +++++-
 .../issue-2239-template-dependent-bit-width.rs     | 19 +++++
 .../issue-2239-template-dependent-bit-width.hpp    | 10 +++
 4 files changed, 147 insertions(+), 4 deletions(-)
 create mode 100644 tests/expectations/tests/issue-2239-template-dependent-bit-width.rs
 create mode 100644 tests/headers/issue-2239-template-dependent-bit-width.hpp

SWW13 avatar Jan 24 '23 23:01 SWW13

Ugh... it's no surprise this has to do with C++ templates.

pvdrz avatar Jan 25 '23 15:01 pvdrz

The issue is still present in 0.66.1 and because LLVM 16 is now hitting the distros I can't now no longer build using the 0.60.1 due to #2319.

If we can't figure this issue out in the near future I would appreciate a backport of the #2319 fix.

SWW13 avatar Sep 05 '23 09:09 SWW13

could you give me a reproducible example so we can work on it?

pvdrz avatar Sep 08 '23 20:09 pvdrz

Yes, but it is far from minimized:

  • clone https://github.com/fuzzware-fuzzer/hoedur.git
  • bump version in qemu-build/Cargo.toml
  • fix qemu-build/src/bindings.rs (is_global: false)
  • cargo build -p qemu-sys --features arm

SWW13 avatar Sep 08 '23 20:09 SWW13

So I have done some work on this.

The offender is

typedef struct a a;
struct a {
  a *b;
};
enum { c };

_Static_assert(!(sizeof(struct {
  int : (__builtin_types_compatible_p(typeof(0), typeof((a *)0)) ? 0 : 1);
}) <= c), "Static assertion failed");

This segfaults bindgen 0.69.4 in a docker container with clang 17. It segfaults bindgen on my mac with clang 15. Interestingly it doesn't segfault 0.60.1 bindgen on my mac.

I have attached the preprocessed headers in one file (gzipped) if that is helpful. __bindgen.i.gz

The creduce output was

typedef struct a a;
struct a {
  a *b
};
enum { c };
_Static_assert(!sizeof(struct {
  int : __builtin_types_compatible_p(typeof(0), typeof((a *)0)) ?: 1
}) <= c);

which I modified to get rid of some clang warnings.

Thread 1 "bindgen" received signal SIGSEGV, Segmentation fault.
0x0000555557d40fd6 in core::ptr::const_ptr::{impl#0}::is_aligned_to<isize> (self=0x7ffff7ea5bf0, align=8) at /home/boydjohnson/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/const_ptr.rs:1605
1605	    pub const fn is_aligned_to(self, align: usize) -> bool {
(gdb) bt
#0  0x0000555557d40fd6 in core::ptr::const_ptr::{impl#0}::is_aligned_to<isize> (self=0x7ffff7ea5bf0, align=8)
    at /home/boydjohnson/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/const_ptr.rs:1605
#1  0x0000555557d3e7b0 in core::ptr::const_ptr::{impl#0}::is_aligned<isize> (self=0x7ffff7ea5bf0)
    at /home/boydjohnson/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/const_ptr.rs:1494
#2  0x0000555557fb54c1 in core::intrinsics::is_aligned_and_not_null<isize> (ptr=0x7ffff7ea5bf0)

This is the head of the gdb output.

backtrace.txt

boydjohnson avatar Mar 13 '24 22:03 boydjohnson

Thanks for you work :)

Interestingly it doesn't segfault 0.60.1 bindgen on my mac.

That's expected, 0.60.1 is the last version without the troublesome commit.

SWW13 avatar Mar 15 '24 12:03 SWW13