[Toybox] __attribute__((__noreturn__)) vs _Noreturn

enh enh at google.com
Wed May 11 09:04:01 PDT 2022


On Wed, May 11, 2022 at 7:32 AM Rob Landley <rob at landley.net> wrote:
>
> On 5/10/22 13:00, enh wrote:
> > On Tue, May 10, 2022 at 10:44 AM Rob Landley <rob at landley.net> wrote:
> >>
> >> On 5/9/22 18:54, enh via Toybox wrote:
> >> > i think this question already came up recently, but mainly as a joke
> >> > before ... "how do you feel about C11?"
> >>
> >> It's comfortably past the 7 year support horizon. I haven't got anything against
> >> C11, I just haven't needed anything from it yet?
> >>
> >> Actually, I think that typecast constant array syntax is from C11:
> >>
> >>   s = ((char *[]){"NICE", "SCHED", "ETIME", "PCPU", "VSIZE", "UNAME"})[k];
> >
> > my personal favorite is `struct type var = { .one_thing_i_care_about =
> > 123 };` with everything else guaranteed zeroed.
>
> Yup, I've been depending on that too.
>
> >> So yeah, we may already be depending on it and I should update the design.html
> >> page...
> >>
> >> > because i actually have a specific reason to want it now. (buckle in,
> >> > because this is going to annoy you...)
> >> >
> >> > we'd seen large numbers of native crashes show up from toybox, and
> >> > oddly they were from the toybox _tests_. which is weird, because we'd
> >> > have expected the tests to _fail_ in that case, and such a problem not
> >> > to get checked in.
> >> >
> >> > (so, long-term question: should/can we improve the test suite to spot
> >> > exit-via-signal and automatically make that a FAIL?)
> >>
> >> I thought it already did ? runtest.sh line 140:
> >>
> >>   # Catch segfaults
> >>   [ $RETVAL -gt 128 ] && [ $RETVAL -lt 255 ] &&
> >>     echo "exited with signal (or returned $RETVAL)" >> actual
> >>
> >> This replaces the output it's comparing with "exited with signal..." which
> >> should never match the real output, and should be printed in the diff.
> >
> > /me checks...
> >
> > ah, yeah, the trouble was it was the common pattern of a test that
> > says `command || ...` or `command && ...` which doesn't have a third
> > case of "but die completely if it was > 128".
>
> Alas, only so much I can do in the plumbing. :(
>
> The fact that || hides segfaults is something to ponder in test design. Shell
> intercepts the failure and discards failure type. Yeah, that's what we asked it
> to do. Hmmm...
>
> Maybe something like having CONFIG_DEBUG replace all the default signal handlers
> with:
>
>   dprintf(2, "AAAAAAAAHHHHHHH!!!!!!!!"); _exit(128+signal);
>
> Except I would be loathe to ship that, and you enable CONFIG_DEBUG by default,
> and if I made it CONFIG_MORE_DEBUG you'd just enable that.. (Which is GOING to
> cause false positive problems. Remember sigpipe. Nevertheless, it is a thing we
> COULD do to catch this sort of thing. It WILL cause false positive issues though.)

to be clear: we only enable CONFIG_DEBUG because we rely on various
dynamic checkers that can't predict the future and know that the
results of your computation on uninitialized data will be thrown away
later. (was that stack data? if so, it's possible that the default
zero-initialization of all stack data in android has obsoleted
that...)

we don't want "all debugging on all the time", but we do want (a) "to
fix anything that the dynamic tools find" and (b) "to blow up rather
than sweep things under the carpet". since we use dynamic checkers in
production (with the end goal being almost-free hardware enforcement
via stuff like Arm MTE), this isn't really "debug" as far as we're
concerned. CONFIG_CAREFUL might be more like it :-)

if CONFIG_DEBUG really were just for use during the tests, we'd have
no reason to turn that on. we would hit up against "always test the
binary you're going to ship" though.

like i say (and as you can see from the fact we found this), given the
[surprisingly new] "file a bug for all native crashes that happen
during test runs" infrastructure, _android_ should find all of this
stuff going forward anyway. so in the absence of an obvious good fix
for this ... "meh". i did want to point it out unless there _was_ a
good fix i was missing though, and just to explain the background of
this specific issue.

> >> *shrug* I've done uglier things with a similar commit comment. "Here's why this
> >> is ugly: it's working around a compiler bug." Ok then.
> >
> > yeah, pretty much. (obviously another alternative is "i revert the
> > change that tickled this locally in T, and we worry about a proper fix
> > for U", but given that this still isn't fixed upstream yet, others
> > might hit it too.)
> >
> > plus i actually like some of the other C11 stuff, so even though this
> > is a _stupid_ forcing function, i'm not unhappy to have _a_ forcing
> > function :-)
> >
> > (if i didn't already say, my reasoning for moving the AOSP default to
> > C11 for U is that i feel like we're at the tipping point now where
> > "even C programmers", not known for their love of the new, are
> > starting to _assume_ C11, and we're having more and more people have
> > to manually opt in/ask why stuff doesn't "just work". linux moving
> > will probably be quite a heavy thumb on that side of the scale. and in
> > the C committee's defense [in contrast to the C++ committee], they're
> > pretty good about not breaking stuff. literally the only problems i've
> > seen have been from people who had untested and incorrect code in #ifs
> > that checked for C11...)
>
> C11 has leaked in over t he past 2-3 years. Time to update the docs and
> acknowledge it...
>
> > but, yeah, this kind of "codegen bug specific to one architecture" was
> > the kind of GCC nonsense i thought LLVM's cleaner design was supposed
> > to save us from :-(
>
> It's written in C++ and you consider it cleaner?

there's plenty of C++ in the GNU stuff these days; that's orthogonal.

my point was that (aiui) an explicit design goal for LLVM was to not
fall into GCC's trap of having so much duplicated code between
backends. most notably warnings that would be checked very very late,
and so you'd get completely different warnings for the same code on
multiple architectures. that was a _huge_ pain for android when we
still used GCC, because although we support 4 architectures, most
people aren't building all four all the time, and we didn't have good
presubmit infrastructure to have the machines do that at the time
either.

> > (to be fair, i _do_ see a lot less of this with LLVM than i used to with GCC.)
>
> I expect that's more "lack of FSF" than anything else. And scaling 50% more buys
> you one iteration of Gates' Law if you're lucky. Code complexity expands to fit
> available management capability if you let it.
>
> (David Graeber liked to explain how most work is maintenance by saying you make
> a cup once but wash it a thousand times. I spend most of my effort performing
> code topiary trying to make a bonsai command line by constantly PRUNING this
> crap. I wanted somebody to do a proper version of Fabrice Bellad's tinycc for
> similar reasons: so we have a comprehensible reference implementation everyone
> can understand and regression test against. Alas, that concept only ever worked
> for C, not for C++. C is not a moving target, and the whole language can be
> explained in an hour.)
>
> >> Rob
>
> Still Rob



More information about the Toybox mailing list