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

SIGSEGV / Segfault in 0.61.0 #2395

Open
SWW13 opened this issue Jan 24, 2023 · 8 comments
Open

SIGSEGV / Segfault in 0.61.0 #2395

SWW13 opened this issue Jan 24, 2023 · 8 comments

Comments

@SWW13
Copy link

SWW13 commented Jan 24, 2023

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.

@pvdrz
Copy link
Contributor

pvdrz commented Jan 24, 2023

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.

@SWW13
Copy link
Author

SWW13 commented Jan 24, 2023

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

@pvdrz
Copy link
Contributor

pvdrz commented Jan 25, 2023

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

@SWW13
Copy link
Author

SWW13 commented Sep 5, 2023

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.

@pvdrz
Copy link
Contributor

pvdrz commented Sep 8, 2023

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

@SWW13
Copy link
Author

SWW13 commented Sep 8, 2023

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

@boydjohnson
Copy link

boydjohnson commented Mar 13, 2024

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

@SWW13
Copy link
Author

SWW13 commented Mar 15, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants