Bug 46173

Informational

GemStone/S 64 Bit

3.3.4, 3.3.3, 3.3.1, 3.3, 3.2.16, 3.2.15, 3.2.14, 3.2.13, 3.2.12, 3.2.11, 3.2.10, 3.2.9, 3.2.8.1, 3.2.8, 3.2.7, 3.2.6, 3.2.5, 3.2.4, 3.2.3, 3.2.2, 3.2.1, 3.2, 3.1.0.6, 3.1.0.5, 3.1.0.4, 3.1.0.3, 3.1.0.2, 3.1.0.1, 3.1, 3.0.1, 3.0, 2.4.7, 2.4.6, 2.4.5.1, 2.4.5, 2.4.4.8, 2.4.4.7, 2.4.4.4, 2.4.x

Linux only

GsFile operations can hang on seteuid / __nptl_setxid GLIBC bug

Customers running Linux GLIBC versions prior to 2.12 may be subject to a GLIBC bug (bug 3270) which can cause GsFile operations calling the OS seteuid( ) operation to deadlock.  Using pstack to view the stack of the hanging gem, if you see these entries then you may have hit this bug:

     __nptl_setxid () from /lib64/libpthread.so.0
     seteuid () from /lib64/libc.so.6

The following web pages have further discussion on this issue:

https://sourceware.org/bugzilla/show_bug.cgi?id=3270

https://sourceforge.net/p/gfarm/tickets/84/

https://github.com/xrootd/xrootd/issues/60

Workaround

Upgrade your Linux machine to use a newer version of GLIBC.  You should upgrade to version 2.12 or later.

The following C code includes a test that can be run to conclusively determine if your machine is subject to this bug.

/* Code to test for GLIBC bug 3270
   If present, will hang on a deadlock condition.

   Compile using cc -pthread test.c
*/

#include      /* Symbolic Constants */
#include   /* Primitive System Data Types */
#include       /* Errors */
#include       /* Input/Output */
#include      /* General Utilities */
#include     /* POSIX Threads */
#include      /* String handling */
#include 

#define NUM_THREADS 5

typedef struct str_thdata
{
        int thread_no;
        char message[10];
} thdata;

void *thread_function ( void *ptr )
{
        thdata *data;
        data = (thdata *) ptr;  /* type cast to a pointer to thdata */

        /* do the work */
        printf("Thread %d says %s \n", data->thread_no, data->message);

        uid_t euid = geteuid();
        setuid(0);
        usleep (1000);
        usleep ((data->thread_no/30)*10000);
        printf("Thread %d signals and ends...\n", data->thread_no);
        setuid(euid);
        return 0;

}

int main()
{
    int loop;
    for (loop = 0; loop < 3000; loop++)
    {
        printf ("loop %d\n",loop);
        pthread_t threads[NUM_THREADS];  /* thread variables */
        thdata data[NUM_THREADS];        /* structs to be passed to threads */
        int i;

        // init
        for (i=0;i


Last updated: 5/18/16