Stream: project-ffi-unwind

Topic: Forced unwinding


view this post on Zulip Amanieu (Feb 24 2020 at 15:51):

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.

view this post on Zulip Amanieu (Feb 24 2020 at 15:51):

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

view this post on Zulip Amanieu (Feb 24 2020 at 15:53):

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.

view this post on Zulip Amanieu (Feb 24 2020 at 15:54):

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.

view this post on Zulip BatmanAoD (Kyle Strand) (Feb 24 2020 at 15:57):

Interesting. Thank you for looking into that.

view this post on Zulip BatmanAoD (Kyle Strand) (Feb 24 2020 at 20:23):

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?

view this post on Zulip Amanieu (Feb 24 2020 at 21:42):

There's also frames with no unwinding tables.

view this post on Zulip Amanieu (Feb 24 2020 at 21:42):

That's the main issue here.

view this post on Zulip Amanieu (Feb 24 2020 at 21:44):

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.

view this post on Zulip Amanieu (Feb 24 2020 at 21:44):

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

view this post on Zulip BatmanAoD (Kyle Strand) (Feb 24 2020 at 22:16):

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?

view this post on Zulip Amanieu (Feb 24 2020 at 23:10):

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

view this post on Zulip Amanieu (Feb 24 2020 at 23:10):

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

view this post on Zulip Amanieu (Feb 24 2020 at 23:11):

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

view this post on Zulip Amanieu (Feb 24 2020 at 23:21):

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).

view this post on Zulip BatmanAoD (Kyle Strand) (Feb 25 2020 at 00:17):

catch_unwind only catches Rust panics

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

view this post on Zulip bjorn3 (Feb 25 2020 at 06:07):

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

view this post on Zulip Amanieu (Feb 25 2020 at 08:06):

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.

view this post on Zulip bjorn3 (Feb 25 2020 at 11:08):

Yes, I was refering to #65646


Last updated: Jan 26 2022 at 09:02 UTC