This is an archive of the discontinued LLVM Phabricator instance.

[libc++] Make check_assertion.h use setjmp/longjmp instead of fork
AbandonedPublic

Authored by john.brawn on Apr 22 2022, 5:59 AM.

Details

Reviewers
ldionne
Mordante
michaelplatings
Group Reviewers
Restricted Project
Summary

Currently check_assertion.h checks an assertion by forking and checking the exit code of the child process, but this means such tests don't work on targets where fork doesn't exist (e.g. bare metal targets).

Instead call setjmp just before we call the function we want to test, then longjmp out of __libcpp_assertion_handler with a return value indicating whether the assert happened as expected.

Diff Detail

Event Timeline

john.brawn created this revision.Apr 22 2022, 5:59 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 22 2022, 5:59 AM
john.brawn requested review of this revision.Apr 22 2022, 5:59 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 22 2022, 5:59 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript

This looks really interesting! However, doesn't that mean that we can't assert that the process terminates if a certain condition is met?

libcxx/test/support/check_assertion.h
148
162

Here and elsewhere.

john.brawn planned changes to this revision.Apr 26 2022, 10:06 AM

This looks really interesting! However, doesn't that mean that we can't assert that the process terminates if a certain condition is met?

I'll also adjust this to use atexit to catch that kind of thing as well (and not doing this is why test_check_assertion.pass.cpp fails).

The failure in debug.erase.iter_iter.pass.cpp is a bit more complicated. At the point the assertion happens the list is in an inconsistent state, so when it's later destroyed we get a segmentation fault (this wasn't a fault previously as exiting the child process through __libcpp_assertion_handler meant we bypassed the destruction of the list). I think this can be fixed by copying the closure f after the setjmp, so the longjmp will bypass its destruction, but getting it right is a bit fiddly.

libcxx/test/support/check_assertion.h
148

Will do.

162

Will do.

john.brawn abandoned this revision.Apr 28 2022, 4:11 AM

After doing some more experimentation I don't think it's possible to get this to work in all cases. If we make a copy of the closure then any containers in it will be copied, but copies of iterators will still point to the container outside of the closure copy, and this causes a bunch of tests to fail.