Skip to content
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

Stack overflow in ir::item::Item::is_constified_enum_module #2102

Closed
adetaylor opened this issue Sep 24, 2021 · 5 comments · Fixed by #2109
Closed

Stack overflow in ir::item::Item::is_constified_enum_module #2102

adetaylor opened this issue Sep 24, 2021 · 5 comments · Fixed by #2109

Comments

@adetaylor
Copy link
Contributor

Input C/C++ Header

namespace N {
template <typename> class B{};
template <typename c> class C {
public:
  using U = B<c>;
};
}
class A : N::C<A> {
  U u;
};

Bindgen Invocation

$ target/debug/bindgen  "--default-enum-style" "rust" "--allowlist-function" "A" "--allowlist-function" "autocxx_make_string_default" "--allowlist-type" "A" "--allowlist-var" "A" "--no-layout-tests" "--no-derive-copy" "--no-derive-debug" "--no-derive-default" "--enable-cxx-namespaces" "--generate" "functions,types,vars,methods,constructors,destructors" "--generate-inline-functions" test.hpp "--" "-x" "c++" "-std=c++14" 

Actual Results

Segmentation fault: 11

due to stack overflow

Expected Results

Successful build.

Call stack

  * frame #0: 0x00007fff2026aceb libsystem_malloc.dylib`tiny_malloc_from_free_list + 12
    frame #1: 0x00007fff2026a75d libsystem_malloc.dylib`tiny_malloc_should_clear + 233
    frame #2: 0x00007fff20269667 libsystem_malloc.dylib`szone_malloc_should_clear + 66
    frame #3: 0x00007fff20282f3b libsystem_malloc.dylib`_malloc_zone_malloc + 118
    frame #4: 0x00000001003aa487 bindgen`alloc::alloc::alloc::h881ad6279d012d58(layout=Layout @ 0x00007ffeef401160) at alloc.rs:86:14
    frame #5: 0x00000001003aa506 bindgen`alloc::alloc::Global::alloc_impl::hafac9624b1dc51fc(self=0x00007ffeef401370, layout=Layout @ 0x00007ffeef4011d0, zeroed=false) at alloc.rs:166:73
    frame #6: 0x00000001003ad24b bindgen`_$LT$alloc..alloc..Global$u20$as$u20$core..alloc..Allocator$GT$::allocate::hc2ef14ecfb6278f9(self=0x00007ffeef401370, layout=Layout @ 0x00007ffeef401260) at alloc.rs:226:9
    frame #7: 0x00000001003a1d29 bindgen`hashbrown::raw::alloc::inner::do_alloc::h520716869f21369e(alloc=0x00007ffeef401370, layout=Layout @ 0x00007ffeef4012b0) at alloc.rs:11:9
    frame #8: 0x000000010039a777 bindgen`hashbrown::raw::RawTableInner$LT$A$GT$::new_uninitialized::h15d1ed32a659eed8(alloc=Global @ 0x00007ffeef401370, table_layout=(size = 8, ctrl_align = 16), buckets=4, fallibility=Infallible) at mod.rs:1157:38
    frame #9: 0x000000010039aba4 bindgen`hashbrown::raw::RawTableInner$LT$A$GT$::fallible_with_capacity::h094c3d88e63ae6b6(alloc=Global @ 0x00007ffeef4015e8, table_layout=(size = 8, ctrl_align = 16), capacity=1, fallibility=Infallible) at mod.rs:1186:30
    frame #10: 0x000000010039a115 bindgen`hashbrown::raw::RawTableInner$LT$A$GT$::prepare_resize::h1a576dabc2d364e7(self=0x00007ffeef401df8, table_layout=(size = 8, ctrl_align = 16), capacity=1, fallibility=Infallible) at mod.rs:1396:29
    frame #11: 0x00000001001c3b7d bindgen`hashbrown::raw::RawTable$LT$T$C$A$GT$::resize::h3916b1017029007e(self=0x00007ffeef401df8, capacity=1, hasher={closure#0} @ 0x00007ffeef401898, fallibility=Infallible) at mod.rs:788:17
    frame #12: 0x0000000100648730 bindgen`hashbrown::raw::RawTable$LT$T$C$A$GT$::reserve_rehash::h14f3861a17482b75(self=0x00007ffeef401df8, additional=1, hasher={closure#0} @ 0x00007ffeef401b08, fallibility=Infallible) at mod.rs:693:13
    frame #13: 0x00000001001c76e6 bindgen`hashbrown::raw::RawTable$LT$T$C$A$GT$::reserve::h18efed2053f418c8(self=0x00007ffeef401df8, additional=1, hasher={closure#0} @ 0x00007ffeef401ba8) at mod.rs:646:16
    frame #14: 0x00000001001c1be7 bindgen`hashbrown::raw::RawTable$LT$T$C$A$GT$::insert::ha51f01d056b1f86f(self=0x00007ffeef401df8, hash=1714775736476281168, value=(bindgen::ir::context::ItemId, ()) @ 0x00007ffeef401c48, hasher={closure#0} @ 0x00007ffeef401c50) at mod.rs:827:17
    frame #15: 0x000000010023c2f0 bindgen`hashbrown::map::HashMap$LT$K$C$V$C$S$C$A$GT$::insert::h6df9ec0c761227bc(self=0x00007ffeef401df8, k=(__0 = 16), v=<unavailable>) at map.rs:1266:13
    frame #16: 0x000000010021c185 bindgen`hashbrown::set::HashSet$LT$T$C$S$C$A$GT$::insert::hfa11aaee2516efa2(self=0x00007ffeef401df8, value=(__0 = 16)) at set.rs:985:9
    frame #17: 0x00000001002e4b25 bindgen`std::collections::hash::set::HashSet$LT$T$C$S$GT$::insert::hc632ad229ca57c7a(self=0x00007ffeef401df8, value=(__0 = 16)) at set.rs:835:9
    frame #18: 0x0000000100274b3d bindgen`bindgen::ir::context::ItemResolver::resolve::h9f2cf0533fbc4d25(self=ItemResolver @ 0x00007ffeef401dc8, ctx=0x00007ffeefbef138) at context.rs:2732:17
    frame #19: 0x000000010016a122 bindgen`bindgen::ir::item::Item::is_constified_enum_module::h442f830211b3869f(self=0x00000001098a9a00, ctx=0x00007ffeefbef138) at item.rs:969:20
    frame #20: 0x000000010016a2f1 bindgen`bindgen::ir::item::Item::is_constified_enum_module::h442f830211b3869f(self=0x00000001098a9a00, ctx=0x00007ffeefbef138) at item.rs:987:21

then many repeats ...

    frame #28771: 0x000000010016a2f1 bindgen`bindgen::ir::item::Item::is_constified_enum_module::h442f830211b3869f(self=0x00000001098a9a00, ctx=0x00007ffeefbef138) at item.rs:987:21
    frame #28772: 0x0000000100170186 bindgen`_$LT$bindgen..ir..item..Item$u20$as$u20$bindgen..ir..item..ItemCanonicalPath$GT$::namespace_aware_canonical_path::h061fb5cc46a42547(self=0x00000001098a9a00, ctx=0x00007ffeefbef138) at item.rs:1938:12
    frame #28773: 0x000000010025c23d bindgen`bindgen::codegen::utils::build_path::h4f859c487d15c077(item=0x00000001098a9a00, ctx=0x00007ffeefbef138) at mod.rs:4573:20
    frame #28774: 0x00000001001cdae5 bindgen`_$LT$bindgen..ir..ty..Type$u20$as$u20$bindgen..codegen..TryToRustTy$GT$::try_to_rust_ty::h878371574cecce66(self=0x00000001098a9ab8, ctx=0x00007ffeefbef138, item=0x00000001098a9a00) at mod.rs:3663:21
    frame #28775: 0x0000000100167706 bindgen`_$LT$bindgen..ir..item..Item$u20$as$u20$bindgen..codegen..TryToRustTy$GT$::try_to_rust_ty::h313d2754ad444d24(self=0x00000001098a9a00, ctx=0x00007ffeefbef138, (null)=0x0000000100661af0) at mod.rs:3512:9
    frame #28776: 0x00000001002a2215 bindgen`_$LT$T$u20$as$u20$bindgen..codegen..TryToRustTy$GT$::try_to_rust_ty::hd3596b2ec0a2c103(self=0x00007ffeefbe9210, ctx=0x00007ffeefbef138, (null)=0x000000010065bc08) at mod.rs:3488:9
    frame #28777: 0x00000001001cca4f bindgen`_$LT$bindgen..ir..ty..Type$u20$as$u20$bindgen..codegen..TryToRustTy$GT$::try_to_rust_ty::h878371574cecce66(self=0x00000001098a91f8, ctx=0x00007ffeefbef138, item=0x00000001098a9140) at mod.rs:3641:49
    frame #28778: 0x0000000100167706 bindgen`_$LT$bindgen..ir..item..Item$u20$as$u20$bindgen..codegen..TryToRustTy$GT$::try_to_rust_ty::h313d2754ad444d24(self=0x00000001098a9140, ctx=0x00007ffeefbef138, (null)=0x0000000100661af0) at mod.rs:3512:9
    frame #28779: 0x00000001002a2215 bindgen`_$LT$T$u20$as$u20$bindgen..codegen..TryToRustTy$GT$::try_to_rust_ty::hd3596b2ec0a2c103(self=0x00007ffeefbe9908, ctx=0x00007ffeefbef138, (null)=0x00000001006649a0) at mod.rs:3488:9
    frame #28780: 0x00000001002a2051 bindgen`_$LT$T$u20$as$u20$bindgen..codegen..ToRustTyOrOpaque$GT$::to_rust_ty_or_opaque::h1867c02690aa656b(self=0x00007ffeefbe9908, ctx=0x00007ffeefbef138, extra=0x00000001006649a0) at mod.rs:3457:9
    frame #28781: 0x00000001002e5e57 bindgen`_$LT$bindgen..ir..comp..FieldData$u20$as$u20$bindgen..codegen..FieldCodegen$GT$::codegen::h2f996ba53ed751a4(self=0x0000000108612df8, ctx=0x00007ffeefbef138, fields_should_be_private=false, codegen_depth=1, accessor_kind=None, parent=0x00000001098a8eb0, result=0x00007ffeefbeda80, struct_layout=0x00007ffeefbeaaa0, fields=0x00007ffeefbeaa88, methods=0x00007ffeefbeac58, (null)=<unavailable>) at mod.rs:1250:22
    frame #28782: 0x00000001002e5c15 bindgen`_$LT$bindgen..ir..comp..Field$u20$as$u20$bindgen..codegen..FieldCodegen$GT$::codegen::hba549f9f53ec1e7c(self=0x0000000108612df0, ctx=0x00007ffeefbef138, fields_should_be_private=false, codegen_depth=1, accessor_kind=None, parent=0x00000001098a8eb0, result=0x00007ffeefbeda80, struct_layout=0x00007ffeefbeaaa0, fields=0x00007ffeefbeaa88, methods=0x00007ffeefbeac58, (null)=<unavailable>) at mod.rs:1193:17
    frame #28783: 0x00000001002b3cb9 bindgen`_$LT$bindgen..ir..comp..CompInfo$u20$as$u20$bindgen..codegen..CodeGenerator$GT$::codegen::he50bcf644fb0c7dd(self=0x00000001098a8eb0, ctx=0x00007ffeefbef138, result=0x00007ffeefbeda80, item=0x00000001098a8dc0) at mod.rs:1792:17
    frame #28784: 0x00000001001c9824 bindgen`_$LT$bindgen..ir..ty..Type$u20$as$u20$bindgen..codegen..CodeGenerator$GT$::codegen::h60a82ff9d8c59740(self=0x00000001098a8e78, ctx=0x00007ffeefbef138, result=0x00007ffeefbeda80, item=0x00000001098a8dc0) at mod.rs:798:39
    frame #28785: 0x00000001001675d6 bindgen`_$LT$bindgen..ir..item..Item$u20$as$u20$bindgen..codegen..CodeGenerator$GT$::codegen::hfb80dfb6c50e6f3f(self=0x00000001098a8dc0, ctx=0x00007ffeefbef138, result=0x00007ffeefbeda80, _extra=0x0000000100663568) at mod.rs:493:17
    frame #28786: 0x00000001002c39a2 bindgen`_$LT$bindgen..ir..module..Module$u20$as$u20$bindgen..codegen..CodeGenerator$GT$::codegen::_$u7b$$u7b$closure$u7d$$u7d$::h216d8aa539fe433d(result=0x00007ffeefbeda80, found_any=0x00007ffeefbedd1f) at mod.rs:516:21
    frame #28787: 0x00000001002c3da5 bindgen`_$LT$bindgen..ir..module..Module$u20$as$u20$bindgen..codegen..CodeGenerator$GT$::codegen::_$u7b$$u7b$closure$u7d$$u7d$::h4f32d5d8be185ac1(result=0x00007ffeefbeda80) at mod.rs:564:13
    frame #28788: 0x00000001002c361a bindgen`bindgen::codegen::CodegenResult::inner::h08c4e202b41dcdc1(self=0x00007ffeefbee2e8, cb={closure#1} @ 0x00007ffeefbedd38) at mod.rs:318:9
    frame #28789: 0x000000010015a15c bindgen`_$LT$bindgen..ir..module..Module$u20$as$u20$bindgen..codegen..CodeGenerator$GT$::codegen::h7e4f5c7f03fd0ec8(self=0x00000001098a7eb8, ctx=0x00007ffeefbef138, result=0x00007ffeefbee2e8, item=0x00000001098a7e00) at mod.rs:551:27
    frame #28790: 0x00000001001675a8 bindgen`_$LT$bindgen..ir..item..Item$u20$as$u20$bindgen..codegen..CodeGenerator$GT$::codegen::hfb80dfb6c50e6f3f(self=0x00000001098a7e00, ctx=0x00007ffeefbef138, result=0x00007ffeefbee2e8, _extra=0x0000000100663568) at mod.rs:484:17
    frame #28791: 0x00000001002c61cb bindgen`bindgen::codegen::codegen::_$u7b$$u7b$closure$u7d$$u7d$::h5030937e7242478f((null)={closure#0} @ 0x00007ffeefbee780, context=0x00007ffeefbef138) at mod.rs:4285:9
    frame #28792: 0x00000001002a3790 bindgen`bindgen::ir::context::BindgenContext::gen::h5c8543eb64f81ccd(self=BindgenContext @ 0x00007ffeefbef138, cb={closure#0} @ 0x00007ffeefbef0f8) at context.rs:1187:19
    frame #28793: 0x00000001003183ed bindgen`bindgen::codegen::codegen::hdbf034c19cebbb2b(context=<unavailable>) at mod.rs:4249:5
    frame #28794: 0x000000010022a8d9 bindgen`bindgen::Bindings::generate::h2d526aa73d76695c(options=BindgenOptions @ 0x00007ffeefbf4690) at lib.rs:2362:32
    frame #28795: 0x0000000100226bcf bindgen`bindgen::Builder::generate::ha8c943f87bf5175a(self=Builder @ 0x00007ffeefbf56d8) at lib.rs:1470:9
    frame #28796: 0x0000000100004073 bindgen`bindgen::main::_$u7b$$u7b$closure$u7d$$u7d$::h56393887b91e7e20 at main.rs:54:17
    frame #28797: 0x0000000100024667 bindgen`std::panicking::try::do_call::ha021a9f4661ebdaf(data="\b") at panicking.rs:401:40
    frame #28798: 0x000000010002477b bindgen`__rust_try + 43
    frame #28799: 0x0000000100024529 bindgen`std::panicking::try::hb7e8098b20bbc3fd(f=<unavailable>) at panicking.rs:365:19
    frame #28800: 0x000000010001251d bindgen`std::panic::catch_unwind::hbb3629134709ca6c(f=<unavailable>) at panic.rs:434:14
    frame #28801: 0x0000000100022b64 bindgen`bindgen::main::h56182a57a8c7c287 at main.rs:53:34
    frame #28802: 0x00000001000044fe bindgen`core::ops::function::FnOnce::call_once::h241afb77870a6d4d((null)=(bindgen`bindgen::main::h56182a57a8c7c287 at main.rs:44), (null)=<unavailable>) at function.rs:227:5
    frame #28803: 0x0000000100012841 bindgen`std::sys_common::backtrace::__rust_begin_short_backtrace::h63bc1310c91da133(f=(bindgen`bindgen::main::h56182a57a8c7c287 at main.rs:44)) at backtrace.rs:125:18
    frame #28804: 0x00000001000126a4 bindgen`std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::h3bd1e898f940c515 at rt.rs:63:18
    frame #28805: 0x00000001006226f9 bindgen`std::rt::lang_start_internal::h5f9b030f0a63c040 [inlined] core::ops::function::impls::_$LT$impl$u20$core..ops..function..FnOnce$LT$A$GT$$u20$for$u20$$RF$F$GT$::call_once::h5adc1669b25f044b at function.rs:259:13 [opt]
    frame #28806: 0x00000001006226ec bindgen`std::rt::lang_start_internal::h5f9b030f0a63c040 [inlined] std::panicking::try::do_call::h405f88a3fec16587 at panicking.rs:401 [opt]
    frame #28807: 0x00000001006226ec bindgen`std::rt::lang_start_internal::h5f9b030f0a63c040 [inlined] std::panicking::try::h86d9af92fb3c6022 at panicking.rs:365 [opt]
    frame #28808: 0x00000001006226ec bindgen`std::rt::lang_start_internal::h5f9b030f0a63c040 [inlined] std::panic::catch_unwind::h67150880d2b87901 at panic.rs:434 [opt]
    frame #28809: 0x00000001006226ec bindgen`std::rt::lang_start_internal::h5f9b030f0a63c040 [inlined] std::rt::lang_start_internal::_$u7b$$u7b$closure$u7d$$u7d$::h548e43d03023c928 at rt.rs:45 [opt]
    frame #28810: 0x00000001006226ec bindgen`std::rt::lang_start_internal::h5f9b030f0a63c040 [inlined] std::panicking::try::do_call::h1383affbfec23244 at panicking.rs:401 [opt]
    frame #28811: 0x00000001006226ec bindgen`std::rt::lang_start_internal::h5f9b030f0a63c040 [inlined] std::panicking::try::hf51149bda74e8587 at panicking.rs:365 [opt]
    frame #28812: 0x00000001006226ec bindgen`std::rt::lang_start_internal::h5f9b030f0a63c040 [inlined] std::panic::catch_unwind::h8280208a4f5e7cf4 at panic.rs:434 [opt]
    frame #28813: 0x00000001006226ec bindgen`std::rt::lang_start_internal::h5f9b030f0a63c040 at rt.rs:45 [opt]
    frame #28814: 0x000000010001266e bindgen`std::rt::lang_start::he7c6eec879d9243a(main=(bindgen`bindgen::main::h56182a57a8c7c287 at main.rs:44), argc=45, argv=0x00007ffeefbff520) at rt.rs:62:5
    frame #28815: 0x0000000100022df6 bindgen`main + 22
    frame #28816: 0x00007fff2045cf3d libdyld.dylib`start + 1

Thanks to @JustAPerson for reducing this test case over on google/autocxx#616.

@adetaylor
Copy link
Contributor Author

I slightly further reduced this:

template <typename> class B{};
template <typename c> class C {
public:
  using U = B<c>;
};
class A : C<A> {
  U u;
};

There's a test case in this branch, which currently fails: master...adetaylor:bug-2102-test-case

ir

The problem seems to be that we're generating a TypeKind::Alias which refers to itself (ItemId 15 above). I assume this is wrong, and that's why subsequent routines get into infinite recursion.

@adetaylor
Copy link
Contributor Author

It looks like this is a regression since c39c47c - this test passes when run on that version. I'll bisect. (Also, this is quite closely related to #1975, a long-standing PR I've not quite got up to scratch).

@adetaylor
Copy link
Contributor Author

Bisection says this was introduced by 5464546. (@pcwalton perhaps you are interested in this case? It at least has the benefit of being small unlike the horrible case which motivated #2078).

Unfortunately #1975 doesn't appear to help here either. We just get into an infinite loop on this case. Bah.

@adetaylor
Copy link
Contributor Author

This case seems to work fine:

struct B{};
template <typename c> class C {
public:
  using U = B;
};
class A : C<A> {
  U u;
};

In this case, the TypeReference A_U is a type reference to B which is a type reference to the struct B. So it's something to do with that parameterization.

@adetaylor
Copy link
Contributor Author

It looks like the self-referential Alias is probably being constructed by the code in item.rs which has this debug print:

debug!("Avoiding recursion parsing type: {:?}", ty);

adetaylor added a commit to adetaylor/rust-bindgen that referenced this issue Oct 19, 2021
This previously produced a type alias which referred to itself,
which was clearly wrong and resulted in downstream code recursing
infinitely.

The problem case (per bug rust-lang#2102) is:

  template <typename> class B{};
  template <typename c> class C {
  public:
    using U = B<c>;
  };
  class A : C<A> {
    U u;
  };

As far as I can tell, we parse clang's definition of B<A>; that leads
us to parse A; to find it has a field U which turns out to be of type
B<A>. And so we hit the line in item.rs which says:
  debug!("Avoiding recursion parsing type: {:?}", ty);
and bail out, returning the original item ID: hence, a self-
referential typedef is created.

The 'fix' in this PR creates an opaque type in this case instead,
to avoid later infinite loops. It would be preferable to avoid this
situation in the first place, but presumably that would require
us to split the parsing phase into two:
1) types
2) fields within those types.

Fixes rust-lang#2102.
adetaylor added a commit to adetaylor/rust-bindgen that referenced this issue Oct 19, 2021
This previously produced a type alias which referred to itself,
which was clearly wrong and resulted in downstream code recursing
infinitely.

The problem case (per bug rust-lang#2102) is:

  template <typename> class B{};
  template <typename c> class C {
  public:
    using U = B<c>;
  };
  class A : C<A> {
    U u;
  };

As far as I can tell, we parse clang's definition of B<A>; that leads
us to parse A; to find it has a field U which turns out to be of type
B<A>. And so we hit the line in item.rs which says:
  debug!("Avoiding recursion parsing type: {:?}", ty);
and bail out, returning the original item ID: hence, a self-
referential typedef is created.

The 'fix' in this PR creates an opaque type in this case instead,
to avoid later infinite loops. It would be preferable to avoid this
situation in the first place, but presumably that would require
us to split the parsing phase into two:
1) types
2) fields within those types.

Fixes rust-lang#2102.
lightsofapollo pushed a commit to lightsofapollo/rust-bindgen that referenced this issue Oct 19, 2021
This previously produced a type alias which referred to itself,
which was clearly wrong and resulted in downstream code recursing
infinitely.

The problem case (per bug rust-lang#2102) is:

  template <typename> class B{};
  template <typename c> class C {
  public:
    using U = B<c>;
  };
  class A : C<A> {
    U u;
  };

As far as I can tell, we parse clang's definition of B<A>; that leads
us to parse A; to find it has a field U which turns out to be of type
B<A>. And so we hit the line in item.rs which says:
  debug!("Avoiding recursion parsing type: {:?}", ty);
and bail out, returning the original item ID: hence, a self-
referential typedef is created.

The 'fix' in this PR creates an opaque type in this case instead,
to avoid later infinite loops. It would be preferable to avoid this
situation in the first place, but presumably that would require
us to split the parsing phase into two:
1) types
2) fields within those types.

Fixes rust-lang#2102.
emilio pushed a commit that referenced this issue Oct 27, 2021
This previously produced a type alias which referred to itself,
which was clearly wrong and resulted in downstream code recursing
infinitely.

The problem case (per bug #2102) is:

  template <typename> class B{};
  template <typename c> class C {
  public:
    using U = B<c>;
  };
  class A : C<A> {
    U u;
  };

As far as I can tell, we parse clang's definition of B<A>; that leads
us to parse A; to find it has a field U which turns out to be of type
B<A>. And so we hit the line in item.rs which says:
  debug!("Avoiding recursion parsing type: {:?}", ty);
and bail out, returning the original item ID: hence, a self-
referential typedef is created.

The 'fix' in this PR creates an opaque type in this case instead,
to avoid later infinite loops. It would be preferable to avoid this
situation in the first place, but presumably that would require
us to split the parsing phase into two:
1) types
2) fields within those types.

Fixes #2102.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant