Stream: project-ffi-unwind

Topic: Forced unwinding


Amanieu (Feb 24 2020 at 15:51, on Zulip):

I've been reading a bit of glibc source code and I think I now have a better idea of how forced unwinding actually works. Basically in glibc, forced unwind works by try to unwind normally as many frames as possible while running destructors. Once it reaches a frame with no unwind info, it skips all remaining frames by using a simply longjmp.

Amanieu (Feb 24 2020 at 15:51, on Zulip):

This is how forced unwind can work with both -fexceptions and -fno-exceptions.

Amanieu (Feb 24 2020 at 15:53, on Zulip):

As such I would like to revise my previous position that unwinding through nounwind is not UB. Keep in mind that with -C panic=abort we often don't even have unwinding tables, so unwinding most likely will not work.

Amanieu (Feb 24 2020 at 15:54, on Zulip):

In terms of how it affects the proposals, it just turns non-forced unwinding from unwind to UB in the table. I don't think this change has any effect on the pros/cons that are listed.

Kyle Strand (Feb 24 2020 at 15:57, on Zulip):

Interesting. Thank you for looking into that.

BatmanAoD (Kyle Strand) (Feb 24 2020 at 20:23, on Zulip):

The new "forced unwinding" description is a bit confusing to me. First, is it not actually true that catch (...) { } will cause the program to abort on forced-unwind? Second, are frames that "do not have unwinding support" just frames marked w/ nounwind?

Amanieu (Feb 24 2020 at 21:42, on Zulip):

There's also frames with no unwinding tables.

Amanieu (Feb 24 2020 at 21:42, on Zulip):

That's the main issue here.

Amanieu (Feb 24 2020 at 21:44, on Zulip):

A normal unwind will just abort if it finds a frame with no unwind info. But pthread uses a hack and performs a longjmp when it reaches such a frame.

Amanieu (Feb 24 2020 at 21:44, on Zulip):

https://github.com/bminor/glibc/blob/master/nptl/unwind.c#L54

BatmanAoD (Kyle Strand) (Feb 24 2020 at 22:16, on Zulip):

So that would apply in panic=abort for both "C" and "C unwind" in all three proposals, and in panic=unwind for "C" with proposals 1 & 2?

Amanieu (Feb 24 2020 at 23:10, on Zulip):

Yes, sort of. Except "C unwind" under panic=abort will need to have unwinding tables since it needs to catch foreign exceptions and abort.

Amanieu (Feb 24 2020 at 23:10, on Zulip):

"C" under panic=abort will not have unwinding tables.

Amanieu (Feb 24 2020 at 23:11, on Zulip):

"C" under panic=unwind in proposal 1&2 does have unwinding tables, but it is declared nounwind so LLVM will optimize destructors away.

Amanieu (Feb 24 2020 at 23:21, on Zulip):

Sorry I missed your first question.

First, is it not actually true that catch (...) { } will cause the program to abort on forced-unwind?

Yes it is technically true but I don't think it is very relevant to this discussion so I removed it. Rust has no mechanism for catching foreign exceptions (catch_unwind only catches Rust panics).

BatmanAoD (Kyle Strand) (Feb 25 2020 at 00:17, on Zulip):

catch_unwind only catches Rust panics

Hm, that's actually probably worth mentioning in the blog post, come to think of it!

bjorn3 (Feb 25 2020 at 06:07, on Zulip):

I believe there was recently a PR to make catch_unwind catch foreign exceptions too.

Amanieu (Feb 25 2020 at 08:06, on Zulip):

I made a PR to make catch_unwind not segfault on foreign exceptions, is that what you're referring to? They're still not caught though.

bjorn3 (Feb 25 2020 at 11:08, on Zulip):

Yes, I was refering to #65646

Last update: Jun 05 2020 at 23:15UTC