rust-lang / rust-bindgen

Automatically generates Rust FFI bindings to C (and some C++) libraries.
https://rust-lang.github.io/rust-bindgen/
BSD 3-Clause "New" or "Revised" License
4.47k stars 699 forks source link

Stack overflow when computing item name including <filesystem> on windows #2929

Open acovaci opened 2 months ago

acovaci commented 2 months ago

I know you're asking for a minimal header, but I don't have enough C++ experience to be able to understand exactly what's going on. If anyone wants to pair up on this to come up with an example, I'm more than happy to do so. Instead, I'll link to the exact header file I'm using

Input C/C++ Header

https://github.com/AurieFramework/YYToolkit/blob/stable/ExamplePlugin/include/YYToolkit/Shared.hpp

Bindgen Invocation

fn main() {
    const INCLUDE_DIR: &str = "./include";

    println!("cargo:rustc-link-search=native={}", INCLUDE_DIR);

    let bindings = bindgen::Builder::default()
        .header("include/YYToolkit/Shared.hpp")
        .clang_arg(format!("-I{}", INCLUDE_DIR))
        .clang_arg("-std=c++20")
        .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
        .generate()
        .expect("Unable to generate bindings");

    bindings
        .write_to_file(format!(
            "{}/bindings.rs",
            ::std::env::var("OUT_DIR").unwrap()
        ))
        .expect("Couldn't write bindings!");
}

Actual Results

 thread 'main' panicked at C:\Users\Shadow\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bindgen-0.70.1\ir\item.rs:735:59:
  attempt to add with overflow
  stack backtrace:
     0: std::panicking::begin_panic_handler
               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library\std\src\panicking.rs:665
     1: core::panicking::panic_fmt
               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library\core\src\panicking.rs:74
     2: core::panicking::panic_const::panic_const_add_overflow
               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library\core\src\panicking.rs:181
     3: bindgen::ir::item::Item::name
     4: bindgen::ir::item::Item::name
     5: bindgen::ir::item::Item::name
     6: bindgen::ir::item::Item::name
     7: bindgen::ir::item::Item::name
     8: bindgen::ir::item::Item::name
     9: bindgen::ir::item::Item::name
    10: bindgen::ir::item::Item::name
    11: bindgen::ir::item::Item::name
    12: bindgen::ir::item::Item::name
    13: bindgen::ir::item::Item::name
    14: bindgen::ir::item::Item::name
    15: bindgen::ir::item::Item::name
    16: bindgen::ir::item::Item::name
    17: bindgen::ir::item::Item::name
    18: bindgen::ir::item::Item::name
    19: bindgen::ir::item::Item::name
    20: bindgen::ir::item::Item::name
    21: bindgen::ir::item::Item::name
    22: bindgen::ir::item::Item::name
    23: bindgen::ir::item::Item::name
    24: bindgen::ir::item::Item::name
    25: bindgen::ir::item::Item::name
    26: bindgen::ir::item::Item::name
    27: bindgen::ir::item::Item::name
    28: bindgen::ir::item::Item::name
    29: bindgen::ir::item::Item::name
    30: bindgen::ir::item::Item::name
    31: bindgen::ir::item::Item::name
    32: bindgen::ir::item::Item::name
    33: bindgen::ir::item::Item::name
    34: bindgen::ir::item::Item::name
    35: bindgen::ir::item::Item::name
    36: bindgen::ir::item::Item::name
    37: bindgen::ir::item::Item::name
    38: bindgen::ir::item::Item::name
    39: bindgen::ir::item::Item::name
    40: bindgen::ir::item::Item::name
    41: bindgen::ir::item::Item::name
    42: bindgen::ir::item::Item::name
    43: bindgen::ir::item::Item::name
    44: bindgen::ir::item::Item::name
    45: bindgen::ir::item::Item::name
    46: bindgen::ir::item::Item::name
    47: bindgen::ir::item::Item::name
    48: bindgen::ir::item::Item::name
    49: bindgen::ir::item::Item::name
    50: bindgen::ir::item::Item::name
    51: bindgen::ir::item::Item::name
    52: bindgen::ir::item::Item::name
    53: bindgen::ir::item::Item::name
    54: bindgen::ir::item::Item::name
    55: bindgen::ir::item::Item::name
    56: bindgen::ir::item::Item::name
    57: bindgen::ir::item::Item::name
    58: bindgen::ir::item::Item::name
    59: bindgen::ir::item::Item::name
    60: bindgen::ir::item::Item::name
    61: bindgen::ir::item::Item::name
    62: bindgen::ir::item::Item::name
    63: bindgen::ir::item::Item::name
    64: bindgen::ir::item::Item::name
    65: bindgen::ir::item::Item::name
    66: bindgen::ir::item::Item::name
    67: bindgen::ir::item::Item::name
    68: bindgen::ir::item::Item::name
    69: bindgen::ir::item::Item::name
    70: bindgen::ir::item::Item::name
    71: bindgen::ir::item::Item::name
    72: bindgen::ir::item::Item::name
    73: bindgen::ir::item::Item::name
    74: bindgen::ir::item::Item::name
    75: bindgen::ir::item::Item::name
    76: bindgen::ir::item::Item::name
    77: bindgen::ir::item::Item::name
    78: bindgen::ir::item::Item::name
    79: bindgen::ir::item::Item::name
    80: bindgen::ir::item::Item::name
    81: bindgen::ir::item::Item::name
    82: bindgen::ir::item::Item::name
    83: bindgen::ir::item::Item::name
    84: bindgen::ir::item::Item::name
    85: bindgen::ir::item::Item::name
    86: bindgen::ir::item::Item::name
    87: bindgen::ir::item::Item::name
    88: bindgen::ir::item::Item::name
    89: bindgen::ir::item::Item::name
    90: bindgen::ir::item::Item::name
    91: bindgen::ir::item::Item::name
    92: bindgen::ir::item::Item::name

Expected Results

Well, if I understand the bindgen logic, the fact it went down so many levels is not expected behaviour. A more useful error message, maybe pointing out to what might be going on, what might be causing this?

Kriskras99 commented 2 months ago

This can be reduced to this:

#include <filesystem>
Kriskras99 commented 2 months ago

This is something to do with <filesystem> on Windows. It does not happen on Linux. I can't manage to reduce it further because I can't get creduce to work on Windows

Kriskras99 commented 2 months ago

@acovaci you should allowlist the types and functions you need. That should prevent this from happening.

jasper-bosch commented 1 month ago

@Kriskras99 I'm having the same issue. Also tried it in a tiny test project, as soon as you #include <filesystem> in the C++ header (even without using any std::filesystem stuff in the C++ code), the attempt to add with overflow issue occurs.

Kriskras99 commented 1 month ago

@jasper-bosch that's because if you don't specify an allowlist, bindgen will generate bindings for everything that is included. So use an allowlist to import the types you need.

jasper-bosch commented 1 month ago

@Kriskras99 Sorry, forgot to mention it before. I also tried using std::filesystem::path in my test project, just to test and allowlisting that type (.allowlist_type("std::filesystem::path")), but that didn't help.

Kriskras99 commented 1 month ago

@jasper-bosch then it's likely (one of) the definition(s) causing issues. If you don't need to access to the fields of the type you can try to make it an opaque type.

See also the bindgen guide on C++: https://rust-lang.github.io/rust-bindgen/cpp.html

jasper-bosch commented 1 month ago

Thanks @Kriskras99! Marked all of std::.* as opaque and allowlisted only what I need.

emilio commented 1 month ago

Would be good to get a repro for that regardless since it seems we're failing to deal with something complex inside the windows header.