Bug 94088

Summary: [llvmpipe] SIGFPE pthread_barrier_destroy.c:40
Product: Mesa Reporter: Vinson Lee <vlee>
Component: Mesa coreAssignee: mesa-dev
Status: RESOLVED FIXED QA Contact: mesa-dev
Severity: normal    
Priority: medium CC: steve.langasek
Version: git   
Hardware: x86-64 (AMD64)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:

Description Vinson Lee 2016-02-11 00:31:20 UTC
glxinfo crashes with LP_NUM_THREADS=0 with glibc-2.22.

mesa: 6ee1c386fe8c9b45746e5bbb8a6f9b56da45fd50 (master 11.2.0-devel)

$ glxinfo
[...]
Floating point exception (core dumped)

(gdb) bt
#0  0x00007f1d95b89f79 in pthread_barrier_destroy (
    barrier=barrier@entry=0x565112e8e730) at pthread_barrier_destroy.c:40
#1  0x00007f1d94dbe83f in pipe_barrier_destroy (barrier=0x565112e8e730)
    at ../../../../src/gallium/auxiliary/os/os_thread.h:155
#2  lp_rast_destroy (rast=0x565112e8d010) at lp_rast.c:970
#3  0x00007f1d94dcdbd1 in llvmpipe_destroy_screen (_screen=0x565112e8cef0)
    at lp_screen.c:525
#4  0x00007f1d9497ac6f in dri_destroy_screen_helper (
    screen=screen@entry=0x565112e8cd50) at dri_screen.c:380
#5  0x00007f1d9497ad15 in dri_destroy_screen (sPriv=0x565112e1df80)
    at dri_screen.c:391
#6  0x00007f1d94978d72 in driDestroyScreen (psp=0x565112e1df80)
    at dri_util.c:229
#7  0x00007f1d9912ddc5 in driswDestroyScreen (base=0x565112e073d0)
    at drisw_glx.c:587
#8  0x00007f1d9910e5cc in FreeScreenConfigs (priv=<optimized out>, 
    priv=<optimized out>) at glxext.c:217
#9  0x00007f1d9910e649 in glx_display_free (priv=priv@entry=0x565112e03c70)
    at glxext.c:240
#10 0x00007f1d9910e79e in __glXCloseDisplay (dpy=0x565112df4030, 
    codes=<optimized out>) at glxext.c:288
#11 0x00007f1d98dcfa42 in XCloseDisplay (dpy=0x565112df4030) at ClDisplay.c:65
#12 0x0000565112544c36 in main (argc=<optimized out>, argv=<optimized out>)
    at glxinfo.c:1278
(gdb) frame 0
#0  0x00007f1d95b89f79 in pthread_barrier_destroy (
    barrier=barrier@entry=0x565112e8e730) at pthread_barrier_destroy.c:40
40					   - BARRIER_IN_THRESHOLD % count;
(gdb) print count
$1 = 0
Comment 1 Vinson Lee 2016-02-13 22:48:54 UTC
commit 4ed4c1d9210b11ce6faea81455c21531904ea45b
Author: Vinson Lee <vlee@freedesktop.org>
Date:   Wed Feb 10 16:42:19 2016 -0800

    llvmpipe: Do not use barriers if not using threads.
    
    Cc: mesa-stable@lists.freedesktop.org
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=94088
    Signed-off-by: Vinson Lee <vlee@freedesktop.org>
    Reviewed-by: Roland Scheidegger <sroland@vmware.com>
Comment 2 Steve Langasek 2016-03-22 04:39:07 UTC
Hello,

The patch for this bug is incomplete.  In between the calls to pipe_barrier_init() and pipe_barrier_destroy() are calls to pipe_barrier_wait(), which is implemented on top of pthread_barrier_wait().

Since pipe_barrier_init() has not been called, the calls to pthread_barrier_wait() have undefined behavior, as per <http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_barrier_wait.html>, <http://linux.die.net/man/3/pthread_barrier_wait>.

The applied commit is sufficient to fix the immediate SIGFPE problem with glibc, but the API is still being used incorrectly and could result in future crashes on other implementations.
Comment 3 Roland Scheidegger 2016-03-22 15:44:27 UTC
(In reply to Steve Langasek from comment #2)
> Hello,
> 
> The patch for this bug is incomplete.  In between the calls to
> pipe_barrier_init() and pipe_barrier_destroy() are calls to
> pipe_barrier_wait(), which is implemented on top of pthread_barrier_wait().
> 
> Since pipe_barrier_init() has not been called, the calls to
> pthread_barrier_wait() have undefined behavior, as per
> <http://pubs.opengroup.org/onlinepubs/009695399/functions/
> pthread_barrier_wait.html>,
> <http://linux.die.net/man/3/pthread_barrier_wait>.
> 
> The applied commit is sufficient to fix the immediate SIGFPE problem with
> glibc, but the API is still being used incorrectly and could result in
> future crashes on other implementations.

I can't see how this could possibly happen. Unless I'm missing something, pipe_barrier_wait() is only called in the thread main function, which will never get called if we don't have any threads to begin with.
Comment 4 Steve Langasek 2016-03-22 18:56:31 UTC
Sorry, you're quite right, this code path is not used except when additional threads are spawned. Please ignore.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.