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
Point to the --whitelist
flags or reporting a bug when we error on binding generation.
#50
Comments
Agreed, though. |
--whitelist
flags or reporting a bug when we error on binding generation.
Please make a comment here if you intend to work on this issue. Thank you! |
Updated the title to be more descriptive. Bonus point for catching panic, I guess. |
I'd like to work on this issue. To be clear, I should (1) change all instances of --whitelist-* to --whitelist-{type,function,var}, and (2) print a message if --whitelist is not used? |
@thuibr: Hi, thanks for wanting to work on this! I just marked this as assigned :) So the idea would be to print a message (or similar) if the all the whitelist flags are empty (you can check those in I don't know what you mean with changing all instances of Thanks once again! :) |
Hi, I'm excited to help! Here is what comes up when I grep for whitelist:
I thought I might need to change those flags to
|
On Sun, Oct 02, 2016 at 02:01:39PM -0700, Thomas Huibregtse wrote:
No, that's not necessary, --whitelist-{type, function, var} is just a By the way, you seem to be grepping in the servo/servo repo. To work on Thanks! |
Okay. Thanks for that last part about cloning rust-bindgen. I'll get to work! |
@emilio: Would this solution work? If none of Or do you still think that a catch_unwind is still the way to go? If so, I'm not really sure where I would put that into code. Could you help me out? Thanks! |
Yeah, that'd work. I think a catch_unwind would be better still, and you probably would want to catch the call to |
@thuibr Are you still working on this? |
I am not, sorry. |
I would like to give this a try if this is not being worked upon. Thanks! |
Sure, thanks! |
@emilio Hi, I am having a little trouble in getting started with this. I didn't find src/bin/bindgen.rs in the repository. |
Hi! Sorry, things have moved around a bit lately :). That file is now |
Hello! Is this still being worked on @choudhary001? If not I would like to work on this :) |
@dengjeffrey Yes, please go ahead. I am not working on this currently. |
Great! @emilio are you mentoring this issue? If not that's okay, it would be helpful if this could be marked assigned though |
Sure, thanks for working on it! |
Let me know if you need anything from me :) |
I spent a good amount of time looking at this issue and reading up on Rust. Being that this is the first time writing in Rust, I need some assistance to how to proceed. It would be really helpful if you can give me some pointers if I am heading in the right direction @emilio 😄 From the description of this issue, I take it that we only point to --whitelist flags when the call to generate() panics. match builder_from_flags(bind_args.into_iter()) {
Ok((builder, output)) => {
let builder_result = panic::catch_unwind(|| {
builder.generate().unwrap();
});
if builder_result.is_err() {
// Should we be more specific and check that a --whitelist flag has not been specified?
println!("Unable to generate binding");
println!("Error is likely caused by not providing a --whitelist-{{type,function,var}} option.");
std::process::exit(1);
}
else {
// Here I try to make a call to bindings.write()
// however the type of bindings is out of scope, so method write() is not found
let mut bindings = builder_result.unwrap();
bindings.write(output)
.expect("Unable to write output");
bindings.write_dummy_uses()
.expect("Unable to write dummy uses to file.");
}
}
Err(error) => {
println!("{}", error);
std::process::exit(1);
}
}; This could be fixed by declaring the return type of the closure in panic::catch_unwind. However I am unsure if this is best practices, or how to declare a return type with a structure that has a lifetime declared in another file, Bindings<'ctx>. |
Are you sure that you need the type of the closure, and not just a Thanks! :) |
Sure! Here it is, https://github.com/dengjeffrey/rust-bindgen/tree/whitelist-binding-panic |
So this is the minimum changeset that makes your changes compile: diff --git a/src/chooser.rs b/src/chooser.rs
index 51392d70..d7a20771 100644
--- a/src/chooser.rs
+++ b/src/chooser.rs
@@ -3,10 +3,11 @@
pub use ir::int::IntKind;
pub use ir::enum_ty::{EnumVariantValue, EnumVariantCustomBehavior};
use std::fmt;
+use std::panic::UnwindSafe;
/// A trait to allow configuring different kinds of types in different
/// situations.
-pub trait TypeChooser: fmt::Debug {
+pub trait TypeChooser: fmt::Debug + UnwindSafe {
/// The integer kind an integer macro should have, given a name and the
/// value of that macro, or `None` if you want the default to be chosen.
fn int_macro(&self, _name: &str, _value: i64) -> Option<IntKind> {
diff --git a/src/lib.rs b/src/lib.rs
index dabab152..1b77e2a1 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -544,6 +544,11 @@ pub struct BindgenOptions {
pub whitelist_recursively: bool,
}
+/// TODO(emilio): This is sort of a lie (see the error message that results from
+/// removing this), but since we don't share references across panic boundaries
+/// it's ok.
+impl ::std::panic::UnwindSafe for BindgenOptions {}
+
impl BindgenOptions {
fn build(&mut self) {
self.whitelisted_vars.build();
diff --git a/src/main.rs b/src/main.rs
index 1ddd1aab..7af360bb 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -45,9 +45,9 @@ pub fn main() {
match builder_from_flags(bind_args.into_iter()) {
Ok((builder, output)) => {
-
+
let builder_result =
- panic::catch_unwind(|| { builder.generate().unwrap(); });
+ panic::catch_unwind(|| builder.generate().unwrap());
if builder_result.is_err() {
println!("Unable to generate binding"); |
Nontheless, I think the flow ideally would be something like: let builder_result =
panic::catch_unwind(|| {
let bindings = builder.generate()
.expect("Unable to generate bindings");
if !bindings.are_valid_rust() {
println!("WARNING: The generated bindings are not valid rust code.");
println!("If this is one of the known-unsupported things (<link>), \
please modify the bindgen flags to work around it as described in <link>.");
println!("Otherwise, please file an issue at https://github.com/servo/rust-bindgen/issues/new");
}
bindings.write(output).expect("unable to write output");
bindings.write_dummy_uses()
.expect("Unable to write dummy uses to file.");
});
if let Err(which) = builder_result {
println!("Bindgen unexpectedly panicked");
println!("The error message was: {:?}", /* try to downcast which to a suitable error */);
println!("We'd appreciate a report at https://github.com/servo/rust-bindgen/issues/new");
std::process::exit(1);
} Note that we'd need to polish error handling after this so a few common errors that cause panic don't, but something like it could be a good start. Somewhat tricky is the |
Thanks! I've taken a look into implementing |
Added catch_unwind to catch panic at generator Fixes #50 - Adds a `catch_unwind` to catch panic at binding generation. - Prints out a more detailed message that points to the potential misuse of flags, when `generate()` fails. - Added false-by-default `verbose` option flag to specify whether detailed message should be printed for the time being - [x] Ran all test cases - [x] Verified that correct error messages appear when bindings fail to generate - [x] Verified use of verbose flag - [x] Considered changes made by `cargo fmt` r? @emilio
Running bindgen on the headers of any nontrivial API tends to generate bindings for most of the C/C++ standard library, which is at best undesirable, often doesn’t compile, and sometimes makes even the binding generation fail. The work-around is to use
--match
to only generate bindings for declarations in relevant header files. (Fortunately, matching can be on a directory name so that there is no need to list each single file individually.)So it seems to me that
--match
is necessary in practice. Running without it should probably print a message explaining all this, rather than leave the user wondering why they have dozens of compiler errors.The text was updated successfully, but these errors were encountered: