rust-lang / rust-lang/rust-bindgen

C++ ABI in MSVC and function returning non-POD type

Open
#2,865 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
5.3k
Forks
829
Avg merge
1d 1h
Merged PRs (30d)
15

Description

I am happily using bindgen to link Rust to a C++ library, and it works great... except when compiling for the MSVC target (that is i686-pc-windows-msvc or x86_64-pc-windows-msvc), that my program crashes badly with random exceptions.

I have reduced the faulty code to the code in this sample repo, ready to run:

https://github.com/rodrigorc/testabi

Input C/C++ Header

There are two types, for reference, Ok works fine, Err fails. The only difference is the constructor, that IIUIC makes the type non-POD and changes the ABI.

struct Ok
{
    int x;
};

Ok TestOk()
{
    Ok r;
    r.x = 1;
    return r;
}

////////////////////////////

struct Err
{
    Err() {} // <--- Difference here!!!
    int x;
};

Err TestErr()
{
    Err r;
    r.x = 1;
    return r;
}
Bindgen Invocation

It fails both with clang and msvc compilers.

    let bindings = bindgen::Builder::default()
        .header("test.cpp")
        .generate()
        .expect("bindings gen failed");
    bindings
        .write_to_file(out_path.join("bindings.rs"))
        .expect("Couldn't write bindings!");

    let mut build = cc::Build::new();
    //build.compiler("clang");
    build.file("test.cpp");
    build.compile("test");
Actual Results

When running the program in windows, natively compiled, it prints garbage:

[src/main.rs:5:5] s = Ok {
    x: 1,
}
[src/main.rs:8:5] t = Err {
    x: 155599256,
}

Or crashes with something like:

error: process didn't exit successfully: `target\debug\testabi.exe` (exit code 0xc0000005, STATUS_ACCESS_VIOLATION)

Or sometimes other less known exceptions. I reckon the stack is getting corrupted.

Expected Results

When cross compiling from Linux, or running natively on Linux, it prints the expected:

[src/main.rs:5:5] s = Ok {
    x: 1,
}
[src/main.rs:8:5] t = Err {
    x: 1,
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the reduced test.cpp example and the bindgen invocation in the issue, then reproduce it for the i686-pc-windows-msvc and x86_64-pc-windows-msvc targets using the linked testabi repository. Compare the generated bindings and calling behavior for Ok and Err; done means the non-POD return value produces x: 1 without corruption or crashes on MSVC.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, rust
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.