Skip to content

SIGSEGV running rust-bindgen on Objective-C headers #665

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

Open
oluseyi opened this issue Apr 26, 2017 · 5 comments
Open

SIGSEGV running rust-bindgen on Objective-C headers #665

oluseyi opened this issue Apr 26, 2017 · 5 comments

Comments

@oluseyi
Copy link

oluseyi commented Apr 26, 2017

Input C/C++ Objective-C Header

#import <Foundation/Foundation.h>
#import <NSWindow.h>
#import <NSTableView.h>

Bindgen Invocation

    let sdk_root = "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk";

    let bindings = bindgen::Builder::default()
        .no_unstable_rust()
        .objc_extern_crate(true)
        .clang_arg("-x")
        .clang_arg("objective-c")
        .clang_arg(format!("-isysroot{}", sdk_root))
        .clang_arg("-mmacosx-version-min=10.10")
        .header("src/wrapper.h")
        .generate()
        .expect("Unable to generate bindings");

Invoked via cargo build with RUST_LOG=libbindgen and RUST_BACKTRACE=1.

Actual Results

oluseyi@Metroplex ~/S/cocoabind-rs> env RUST_LOG=libbindgen RUST_BACKTRACE=1 cargo build
   Compiling cocoabind-rs v0.1.0 (file:///Users/oluseyi/Source/cocoabind-rs)
error: failed to run custom build command for `cocoabind-rs v0.1.0 (file:///Users/oluseyi/Source/cocoabind-rs)`
process didn't exit successfully: `/Users/oluseyi/Source/cocoabind-rs/target/debug/build/cocoabind-rs-b444d464ed631d7a/build-script-build` (signal: 11, SIGSEGV: invalid memory reference)

Note: No stack trace generated!

Expected Results

At this point, simply successful execution without segfault and generation of bindings, even if incorrect.

@oluseyi
Copy link
Author

oluseyi commented Apr 26, 2017

Interestingly, changing the input header to only import framework umbrella headers while using the same invocation changes things:

Alternative Objective-C Header

#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h> // both NSWindow and NSTableView are found in AppKit

Actual Results

oluseyi@Metroplex ~/S/cocoabind-rs> env RUST_LOG=libbindgen RUST_BACKTRACE=1 cargo build
   Compiling cocoabind-rs v0.1.0 (file:///Users/oluseyi/Source/cocoabind-rs)
error: failed to run custom build command for `cocoabind-rs v0.1.0 (file:///Users/oluseyi/Source/cocoabind-rs)`
process didn't exit successfully: `/Users/oluseyi/Source/cocoabind-rs/target/debug/build/cocoabind-rs-b444d464ed631d7a/build-script-build` (exit code: 101)
--- stderr
thread 'main' panicked at 'Invalid function sig: Continue', /Users/rustbuild/src/rust-buildbot/slave/stable-dist-rustc-mac/build/src/libcore/result.rs:868
stack backtrace:
   1:        0x107c81b3c - std::sys::imp::backtrace::tracing::imp::write::h21ca2762819c7ae8
   2:        0x107c8528e - std::panicking::default_hook::{{closure}}::h38f99a37d00bb19b
   3:        0x107c84f30 - std::panicking::default_hook::ha2186ee24b50729c
   4:        0x107c856e7 - std::panicking::rust_panic_with_hook::h979db19ee91d2a53
   5:        0x107c85594 - std::panicking::begin_panic::h6a69f5b54391c64d
   6:        0x107c854b2 - std::panicking::begin_panic_fmt::h9de2343580b3c2c4
   7:        0x107c85417 - rust_begin_unwind
   8:        0x107cadda0 - core::panicking::panic_fmt::haa2997386017a96f
   9:        0x1074dbc47 - core::result::unwrap_failed::hd4b9636c871e995c
  10:        0x10749987f - <core::result::Result<T, E>>::expect::hc3808a7201c3b02a
  11:        0x1075e0148 - bindgen::ir::objc::ObjCInterface::from_ty::{{closure}}::h23e91920790a5253
  12:        0x107599dd3 - bindgen::clang::visit_children::hb9435765c424748b
  13:        0x108e03c53 - _ZN5clang8cxcursor13CursorVisitor5VisitE8CXCursorb
  14:        0x108e057a4 - _ZN5clang8cxcursor13CursorVisitor23handleDeclForVisitationEPKNS_4DeclE
  15:        0x108e05849 - _ZN5clang8cxcursor13CursorVisitor16VisitDeclContextEPNS_11DeclContextE
  16:        0x108e074f5 - _ZN5clang8cxcursor13CursorVisitor22VisitObjCContainerDeclEPNS_17ObjCContainerDeclE
  17:        0x108e07bc2 - _ZN5clang8cxcursor13CursorVisitor22VisitObjCInterfaceDeclEPNS_17ObjCInterfaceDeclE
  18:        0x108e053b0 - _ZN5clang11declvisitor4BaseINS0_8make_ptrENS_8cxcursor13CursorVisitorEbE5VisitEPNS_4DeclE
  19:        0x108e0451d - _ZN5clang8cxcursor13CursorVisitor13VisitChildrenE8CXCursor
  20:        0x108e0e0bd - clang_visitChildren
  21:        0x107742fab - clang_sys::clang_visitChildren::h39a99caeaa290bcf
  22:        0x1075965c8 - bindgen::clang::Cursor::visit::hf458a3ad33e9fbe6
  23:        0x1075df51b - bindgen::ir::objc::ObjCInterface::from_ty::h2e82ec083166c00e
  24:        0x1075d5de9 - bindgen::ir::ty::Type::from_clang_ty::hf346cc68fd2c6cc1
  25:        0x1075c905c - <bindgen::ir::item::Item as bindgen::parse::ClangItemParser>::from_ty_with_id::hafaca2063af99fc4
  26:        0x1075c8184 - <bindgen::ir::item::Item as bindgen::parse::ClangItemParser>::from_ty::hb79ba4d7f2026786
  27:        0x1075c62a5 - <bindgen::ir::item::Item as bindgen::parse::ClangItemParser>::parse::h069918080bc479ca
  28:        0x1075e4b54 - bindgen::parse_one::h087e004499ab6029
  29:        0x1075e524c - bindgen::parse::{{closure}}::{{closure}}::h016504f7a21ebc44
  30:        0x10759a173 - bindgen::clang::visit_children::hcfa94b9af9a46465
  31:        0x108e03c53 - _ZN5clang8cxcursor13CursorVisitor5VisitE8CXCursorb
  32:        0x108e057a4 - _ZN5clang8cxcursor13CursorVisitor23handleDeclForVisitationEPKNS_4DeclE
  33:        0x108e05849 - _ZN5clang8cxcursor13CursorVisitor16VisitDeclContextEPNS_11DeclContextE
  34:        0x108e048cd - _ZN5clang8cxcursor13CursorVisitor13VisitChildrenE8CXCursor
  35:        0x108e0e0bd - clang_visitChildren
  36:        0x107742fab - clang_sys::clang_visitChildren::h39a99caeaa290bcf
  37:        0x107596504 - bindgen::clang::Cursor::visit::hef8bb37e2f4c9693
  38:        0x1075e529c - bindgen::parse::{{closure}}::h3db84f3a59f7ce32
  39:        0x1075b98c8 - bindgen::ir::context::BindgenContext::with_module::h2153d95a34634c8d
  40:        0x1075e5032 - bindgen::parse::hc085ed74066c82bd
  41:        0x1075e350c - bindgen::Bindings::generate::h48b6d40808caf41e
  42:        0x1075e239f - bindgen::Builder::generate::h03484a0dc6cdfda0
  43:        0x1073f3340 - build_script_build::main::h5b4468874f1dfcf4
  44:        0x107c8659a - __rust_maybe_catch_panic
  45:        0x107c85ab6 - std::rt::lang_start::hfc9882558f9403bf
  46:        0x1073f3509 - main

This looks to be running up against the incompleteness of the Objective-C support presently in rust-bindgen.

@fitzgen
Copy link
Member

fitzgen commented Apr 26, 2017

Thanks for the bug report!

@svenknobloch
Copy link

svenknobloch commented Mar 20, 2020

I've also been trying to use bindgen for AppKit and am running into the same issue (the 2nd one). I think I found the cause though.

In the AppKit header file, there is a property with the name operators:

.../MacOSX10.15.sdk/System/Library/Frameworks/AppKit.framework/Headers/NSPredicateEditorRowTemplate.h:59:59
@property (nullable, readonly, copy) NSArray<NSNumber *> *operators;

In the function.rs the FunctionSig constructor checks against C++ operators (link) which matches the operators name and therefore throws an error and fails to parse.

I think a potential solution would be to improve the regex matching to include the symbols for C++ operators (+, =, etc.). I'm not too sure on what implications this would have on other codebases as I'm not too familiar with all the bindgen internals, but I can throw together a sample regex expression and make a PR if you think it's a valid solution.

@svenknobloch
Copy link

Alternatively another solution would just be to guard against only C++ functions using the kind to avoid a complex regex expression. Would guarding against CXCursor_CXXMethod capture all possible operators?

@simlay
Copy link
Contributor

simlay commented Mar 24, 2020

I've also been trying to use bindgen for AppKit and am running into the same issue (the 2nd one). I think I found the cause though.

@svenknobloch I think you'll be interested in #1750.

In the function.rs the FunctionSig constructor checks against C++ operators (link) which matches the operators name and therefore throws an error and fails to parse.

I tested this with the below test case and it looks like you're right.

To update the bug, here's the specific case:

input:

@interface Baz
@property (nullable, readonly) int *operators;
@end

Ran via:
bindgen input.h -- -x objective-c

Expected output (based on recent master):

use objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
pub trait Baz {
    unsafe fn operators(self) -> *mut ::std::os::raw::c_int;
}
impl Baz for id {
    unsafe fn operators(self) -> *mut ::std::os::raw::c_int {
        msg_send!(self, foobar)
    }
}

Annoyingly enough blacklisting doesn't work. I'm guessing because it's at the parse tree phase rather than the generation.

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

4 participants