Stream: project-ffi-unwind

Topic: bad_alloc is a risk even with -fno-exceptions


acfoltzer (Mar 16 2020 at 17:15, on Zulip):

in the lang team meeting, I mentioned that you'll likely get a C++ compiler error if you try compiling exception-throwing code with -fno-exceptions. apparently bad_alloc is a big exception to this: the new constructor that raises that exception is typically compiled into libstdc++, which on most platforms is compiled with exceptions. so even if the user's library is compiled with -fno-exceptions, allocation will still potentially throw :upside_down:

acfoltzer (Mar 16 2020 at 17:18, on Zulip):

I think this further pushes my preference in the direction of whichever proposal makes FFI unwinding support more easily pervasive. between the libc functions unwinding due to pthread_cancel, and bad_alloc coming even from C++ -fno-exceptions, foreign code that is truly nounwind is seeming increasingly rare

acfoltzer (Mar 16 2020 at 17:19, on Zulip):

and right now I think the proposal that best fits this is no. 3 since it would not require changing the types of definitions in existing libraries to add unwinding support

nikomatsakis (Mar 16 2020 at 17:24, on Zulip):

@T-lang :point_up:

centril (Mar 16 2020 at 17:28, on Zulip):

In my experience, failure to allocate storage isn't all that common in modern systems -- there's usually something seriously wrong if that happens.

acfoltzer said:

and right now I think the proposal that best fits this is no. 3 since it would not require changing the types of definitions in existing libraries to add unwinding support

Is this about libraries that were making incorrect assumptions about extern "C"?

acfoltzer (Mar 16 2020 at 17:30, on Zulip):

that's right, I'm thinking about all the cancellation points listed in pthreads(7) in particular

centril (Mar 16 2020 at 17:32, on Zulip):

To me it's not a priority to retcon code that previously had UB/were unsound as having defined behavior

acfoltzer (Mar 16 2020 at 17:34, on Zulip):

I'm curious what the path forward would be then for libraries like libc. I remember hearing some mentions of just explicitly declaring pthread_cancel to be generally incompatible with Rust, but otherwise it seems like proposals 1 & 2 would require changing a number of ABIs to "C unwind"

acfoltzer (Mar 16 2020 at 17:35, on Zulip):

I don't think there's a fundamental reason that couldn't be done, but it seems potentially quite disruptive

centril (Mar 16 2020 at 17:38, on Zulip):

the libc crate can start using "C unwind" for the functions required; if the maintainers of that crate insist that they cannot do that as it would require a semver bump then they can use conditional compilation to use "C unwind" on newer compilers.

centril (Mar 16 2020 at 17:38, on Zulip):

at any rate, on older and current compilers we emit nounwind, so it's not like it was sound before

Amanieu (Mar 16 2020 at 17:42, on Zulip):

Cancellation points are forced exceptions, so the rules are different for them: you can have forced exceptions from extern "C" as long as you make sure you have no destructors in the unwound frames.

Amanieu (Mar 16 2020 at 17:42, on Zulip):

So there would be no need to change the libc definitions (which would be a breaking change anyways)

acfoltzer (Mar 16 2020 at 17:44, on Zulip):

I think in practice a lot of existing code that calls those APIs would run afoul of the no-destructor requirement, but it is good to know that there is a subset that will work fine as-is

acfoltzer (Mar 16 2020 at 17:46, on Zulip):

to be explicit about my thinking here, I don't think any of these points are existential problems with proposals 1 & 2, they just contribute to an overall impression of friction that I get with the split-ABIs vs proposal 3. I should also be explicit this concern comes from my personal language design aesthetics, as opposed to what our project at Fastly requires. any of the proposals currently described would be suitable for us

BatmanAoD (Kyle Strand) (Mar 16 2020 at 18:00, on Zulip):

I haven't been opining much, but for future reference all opinions I give are based exclusively on (as @acfoltzer put it) "my personal language design aesthetics"; I personally don't actually have any projects that rely on FFI unwinding at the moment.

nikomatsakis (Mar 17 2020 at 17:32, on Zulip):

One thing we didn't do at the end of the meeting,

nikomatsakis (Mar 17 2020 at 17:32, on Zulip):

and I was sort of regretting it,

nikomatsakis (Mar 17 2020 at 17:32, on Zulip):

is to kind of do a "round robin" to get a take on where everybody "stood" in terms of what they'd prefer at that moment

nikomatsakis (Mar 17 2020 at 17:32, on Zulip):

...I think it's a useful thing we should do more often...

nikomatsakis (Mar 17 2020 at 17:33, on Zulip):

...though I partly feel like I haven't quite formed my opinion yet. I'm trying to find the "hook" that would put me on one side or another.

nikomatsakis (Mar 17 2020 at 17:34, on Zulip):

I feel like it'd be useful for folks with an opinion to lay out which factors they find most important that pushed them to one side or the other, as @acfoltzer did -- i.e., kind of summarize what you see as the crux of the case and what pushes you to one side

nikomatsakis (Mar 17 2020 at 17:34, on Zulip):

one other clarification that I was thinking about

acfoltzer (Mar 17 2020 at 18:13, on Zulip):

that sounds good as long as we're explicit that it's not a decision-making vote, but just a chance to see where we are relative to a consensus position. I'd be happy to type up more of my thoughts on why I'm personally leaning toward proposal 3

nikomatsakis (Mar 17 2020 at 21:30, on Zulip):

yep, I see this as more of a "where we currently stand and why"

BatmanAoD (Kyle Strand) (Mar 17 2020 at 21:59, on Zulip):

nikomatsakis said:

One thing we didn't do at the end of the meeting,

I thought we agreed to do that offline, i.e. the "straw poll" discussion. It seems @centril is opposed on principle, though, unless I'm misunderstanding.

BatmanAoD (Kyle Strand) (Mar 17 2020 at 22:00, on Zulip):

Or did you think it would be better to just get verbal responses, synchronously?

centril (Mar 18 2020 at 11:30, on Zulip):

@BatmanAoD (Kyle Strand) I'm fine with straw polls on Zulip, although the decision is T-Lang's, but I don't like large straw polls on github

nikomatsakis (Mar 18 2020 at 13:54, on Zulip):

BatmanAoD (Kyle Strand) said:

I thought we agreed to do that offline, i.e. the "straw poll" discussion. It seems centril is opposed on principle, though, unless I'm misunderstanding.

yeah, we did, though I think I'd prefer to see a bit more detailed thoughts, and I just think that in general there is value in make sure we actively hear from the folks in the room. I've found that the "quiet people" often have interesting things to say, and they may or may not speak up in the async case ...

nagisa (Mar 18 2020 at 20:22, on Zulip):

POI: on embedded systems and standard C++ libraries written for that purpose using -fno-exceptions actually does what you’d expect, even in presence of memory allocation failures (which in turn are possible and likely there)

BatmanAoD (Kyle Strand) (Mar 18 2020 at 20:35, on Zulip):

@nagisa Could you be more explicit? I'm not actually sure what I'd expect!

nagisa (Mar 18 2020 at 20:50, on Zulip):

It does not generate any code to unwind. I don’t remember what exact behaviour it was, but IIRC it just behaved like new(nothrow), i.e. returned a nullptr.

BatmanAoD (Kyle Strand) (Mar 18 2020 at 20:51, on Zulip):

Ah, okay. Thanks.

Amanieu (Mar 18 2020 at 22:12, on Zulip):

You get this with -fno-exceptions:

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Amanieu (Mar 18 2020 at 22:13, on Zulip):

(with libstdc++)

Amanieu (Mar 18 2020 at 22:13, on Zulip):

Now obviously if you recompile libstdc++ itself with -fno-exceptions then you'll just get a direct abort instead.

BatmanAoD (Kyle Strand) (Mar 18 2020 at 22:35, on Zulip):

So, in that case, it sounds like libstdc++ compiled with -fexceptions, linked against Rust using our "strategy 2" (with the new ABI) that calls C++ code via extern "C" (the old ABI), would have undefined behavior if that C++ code has a failed allocation.

Amanieu (Mar 18 2020 at 22:41, on Zulip):

Yes, however keep in mind that the practical effect of such UB is actually quite limited in practice: it will usually just terminate the program since it can't find an exception handler.

BatmanAoD (Kyle Strand) (Mar 18 2020 at 22:42, on Zulip):

That sounds rather friendly

Last update: Jun 05 2020 at 23:10UTC