[Mesa-dev] [PATCH] mesa: Define helper function to get the number of texture layers.

Brian Paul brianp at vmware.com
Wed Dec 11 08:56:33 PST 2013


On 12/10/2013 03:27 PM, Francisco Jerez wrote:
> Brian Paul <brianp at vmware.com> writes:
>
>> On 12/10/2013 11:06 AM, Francisco Jerez wrote:
>>> Paul Berry <stereotype441 at gmail.com> writes:
>>>
>>>> On 10 December 2013 08:42, Francisco Jerez <currojerez at riseup.net> wrote:
>>>>
>>>>> Brian Paul <brianp at vmware.com> writes:
>>>>>
>>>>>> On 12/07/2013 06:17 PM, Francisco Jerez wrote:
>>>>>>> [...]
>>>>>>> +   default:
>>>>>>> +      unreachable();
>>>>>>
>>>>>> I think I'd like to see an assertion or _mesa_problem() call to catch
>>>>>> unhandled cases if new texture targets are added in the future.
>>>>>>
>>>>>>
>>>>> How about having the unreachable() macro print out an error and abort if
>>>>> it's ever reached?  See the attached patch.
>>>>>
>>>>
>>>> I would prefer for us to simply do this:
>>>>
>>>> assert(!"Unexpected texture target");
>>>> unreachable();
>>>>
>>>> That would have the exact same semantics as your proposed patch (assert in
>>>> debug builds, allow compiler optimizations in release builds), and it would
>>>> have the added advantage that it's obvious what's going on to someone
>>>> reading the code.  With your proposed patch it's not obvious--the reader
>>>> has to be aware that Mesa has a non-standard meaning for unreachable().
>>>
>>> The message adds no additional useful information IMHO, and it's already
>>> obvious for anyone reading the code that something marked with
>>> unreachable() shouldn't ever be reached -- What else do we have to say?
>>> I have the impression that using the assert(!"") idiom before every
>>> occurrence of unreachable() just increases the amount of noise in the
>>> code and the likelihood of making mistakes.
>>>
>>> Regardless of what we do in this specific case, I believe that making
>>> the unreachable() macro abort is a good thing because it will catch
>>> cases where we have forgotten to pair it with an assert call [I have
>>> already, a few times], and mistakes like writing 'assert("!...' [see
>>> 61143b87c16231a2df0d69324d531503027f9aca].
>>>
>>> If you would like to include some additional explanation in an
>>> unreachable block you can just write a comment, or make unreachable() a
>>> variadic macro that prints its (optionally passed) argument to stderr
>>> when the unreachable block is executed.
>>
>>
>> I just did a test.  I put unreachable() in a conspicuous place in Mesa
>> and ran glxinfo.  I got a segfault.  And in gdb the stack trace wasn't
>> even correct.
>>
> That's precisely what I'm attempting to fix with the change I proposed.
>
>> An assert would be much more useful since it tells us the location and
>> we can get a good stack trace in gdb.
>>
> The unreachable() macro could too.
>
>> The gcc docs for __builtin_unreachable say it's about expressing your
>> intent when doing unconventional flow-control, and possibly suppressing
>> compiler warnings.  It doesn't sounds like a debug check to report when
>> there's unexpected control flow.
>>
> Yes, it's mainly useful as a way to suppress warnings and allow the
> optimizer make assumptions it wouldn't otherwise make because the
> program has invariants beyond the inference capabilities of the compiler
> [e.g. that the texObj->Target GLenum is one of the texture target
> enums].  Say that we want to express one of these invariants using
> unreachable(), an invariant which turns out to be wrong, wouldn't it be
> a useful debugging aid to have the program print out an error and abort
> rather than having undefined behavior?

Definitely.  An unreachable() macro that acts like assert sounds good to me.


>
>> I'm more convinced now that we should simply have an assert there rather
>> than unreachable().
>>
>> Finally, in release builds we generally don't want to crash in these
>> situations.  So IMHO, it's preferable to do something like:
>>
> I have the feeling that this is an orthogonal question to unreachable()
> aborting or not.  I'm not convinced that there's a "sensible" default in
> this case, and setting one seems like trying to delay the inevitable to
> me.  An invariant of the program has been broken and it's likely that
> something will go very wrong sooner or later.  The question boils down
> to: do we want undefined behavior now, or later?  I'd rather have it
> now, but it seems like a moot question to me...

In the cases at hand, _mesa_tex_target_is_layered() and 
_mesa_get_texture_layers(), returning false/0 seem like fairly 
reasonable defaults to return and hopefully wouldn't lead to a later crash.

Over the years I've seen several bug reports where someone runs their 
app and sees a bunch of _mesa_problem() error messages but the app keeps 
running and doesn't crash.  I think that's preferable to just crashing 
(esp. when Mesa may be running in the X server).  That's the reason I'm 
hesitant to see __builtin_unreachable() getting used in release builds 
in this particular scenario.  Having X crash just because we hit a 
default switch case seems unnecessarily fragile.

My second concern is this: if someday someone really does want to use 
__builtin_unreachable() in the context of unconventional flow control 
(per gcc docs), will our new-and-improved unreachable() macro still be 
the right tool for them?  I worry about changing the behavior of what 
seems to be an established convention.

Sorry for dragging this out.  Please go ahead and post a patch showing 
what you have in mind.

-Brian



More information about the mesa-dev mailing list