Skip to content

Commit ddc07fc

Browse files
author
bors-servo
authored
Auto merge of #463 - dengjeffrey:whitelist-binding-panic, r=emilio
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
2 parents cedadf9 + 692ff74 commit ddc07fc

File tree

5 files changed

+41
-7
lines changed

5 files changed

+41
-7
lines changed

src/chooser.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
pub use ir::enum_ty::{EnumVariantCustomBehavior, EnumVariantValue};
44
pub use ir::int::IntKind;
55
use std::fmt;
6+
use std::panic::UnwindSafe;
67

78
/// A trait to allow configuring different kinds of types in different
89
/// situations.
9-
pub trait TypeChooser: fmt::Debug {
10+
pub trait TypeChooser: fmt::Debug + UnwindSafe {
1011
/// The integer kind an integer macro should have, given a name and the
1112
/// value of that macro, or `None` if you want the default to be chosen.
1213
fn int_macro(&self, _name: &str, _value: i64) -> Option<IntKind> {

src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,11 @@ pub struct BindgenOptions {
554554
pub objc_extern_crate: bool,
555555
}
556556

557+
/// TODO(emilio): This is sort of a lie (see the error message that results from
558+
/// removing this), but since we don't share references across panic boundaries
559+
/// it's ok.
560+
impl ::std::panic::UnwindSafe for BindgenOptions {}
561+
557562
impl BindgenOptions {
558563
fn build(&mut self) {
559564
self.whitelisted_vars.build();

src/main.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ extern crate rustc_serialize;
88

99
use bindgen::clang_version;
1010
use std::env;
11+
use std::panic;
1112

1213
mod options;
1314
use options::builder_from_flags;
@@ -41,9 +42,21 @@ pub fn main() {
4142
}
4243

4344
match builder_from_flags(bind_args.into_iter()) {
44-
Ok((builder, output)) => {
45-
let mut bindings = builder.generate()
46-
.expect("Unable to generate bindings");
45+
Ok((builder, output, verbose)) => {
46+
47+
let builder_result =
48+
panic::catch_unwind(||
49+
builder.generate().expect("Unable to generate bindings")
50+
);
51+
52+
if builder_result.is_err() {
53+
if verbose {
54+
print_verbose_err();
55+
}
56+
std::process::exit(1);
57+
}
58+
59+
let mut bindings = builder_result.unwrap();
4760
bindings.write(output)
4861
.expect("Unable to write output");
4962
bindings.write_dummy_uses()
@@ -55,3 +68,13 @@ pub fn main() {
5568
}
5669
};
5770
}
71+
72+
fn print_verbose_err() {
73+
println!("Bindgen unexpectedly panicked");
74+
println!("This may be caused by one of the known-unsupported \
75+
things (https://github.com/servo/rust-bindgen#c), \
76+
please modify the bindgen flags to work around it as \
77+
described in https://github.com/servo/rust-bindgen#c");
78+
println!("Otherwise, please file an issue at \
79+
https://github.com/servo/rust-bindgen/issues/new");
80+
}

src/options.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::io::{self, Error, ErrorKind};
55

66
/// Construct a new [`Builder`](./struct.Builder.html) from command line flags.
77
pub fn builder_from_flags<I>(args: I)
8-
-> Result<(Builder, Box<io::Write>), io::Error>
8+
-> Result<(Builder, Box<io::Write>, bool), io::Error>
99
where I: Iterator<Item = String>,
1010
{
1111
let matches = App::new("bindgen")
@@ -175,6 +175,9 @@ pub fn builder_from_flags<I>(args: I)
175175
.takes_value(true)
176176
.multiple(true)
177177
.number_of_values(1),
178+
Arg::with_name("verbose")
179+
.long("verbose")
180+
.help("Print verbose error messages"),
178181
]) // .args()
179182
.get_matches_from(args);
180183

@@ -346,5 +349,7 @@ pub fn builder_from_flags<I>(args: I)
346349
Box::new(io::BufWriter::new(io::stdout())) as Box<io::Write>
347350
};
348351

349-
Ok((builder, output))
352+
let verbose = matches.is_present("verbose");
353+
354+
Ok((builder, output, verbose))
350355
}

tests/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ fn create_bindgen_builder(header: &PathBuf) -> Result<Option<Builder>, Error> {
117117
.chain(flags.into_iter());
118118

119119
builder_from_flags(args)
120-
.map(|(builder, _)| Some(builder.no_unstable_rust()))
120+
.map(|(builder, _, _)| Some(builder.no_unstable_rust()))
121121
}
122122

123123
macro_rules! test_header {

0 commit comments

Comments
 (0)